From c408c2b070f7a8db410eebeaaa42331dfc916119 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 8 Jul 2023 03:07:49 -0600 Subject: [PATCH 001/133] (#642): changed references to BLWK_mustKillArray macro --- Functions/Supports/fn_reconUAV.sqf | 3 +-- Functions/Waves/fn_addToMustKillArray.sqf | 5 ++--- Functions/Waves/fn_clearMustKillArray.sqf | 6 +----- Functions/Waves/fn_isWaveCleared.sqf | 3 +-- Functions/Waves/fn_startWave.sqf | 3 +-- Headers/String Constants.hpp | 4 ---- 6 files changed, 6 insertions(+), 18 deletions(-) diff --git a/Functions/Supports/fn_reconUAV.sqf b/Functions/Supports/fn_reconUAV.sqf index cd0cdd5c..93d74da5 100644 --- a/Functions/Supports/fn_reconUAV.sqf +++ b/Functions/Supports/fn_reconUAV.sqf @@ -1,4 +1,3 @@ -#include "..\..\Headers\String Constants.hpp" /* ---------------------------------------------------------------------------- Function: BLWK_fnc_reconUAV @@ -50,7 +49,7 @@ private _createdMarkers = []; private _endtime = time + LIFETIME; while {sleep UPDATE_TIME; time < _endTime} do { //_unitsArray = units side OPFOR; - _unitsArray = missionNamespace getVariable [WAVE_ENEMIES_ARRAY,[]]; + _unitsArray = missionNamespace getVariable ["BLWK_mustKillList",[]]; if !(_unitsArray isEqualTo []) then { diff --git a/Functions/Waves/fn_addToMustKillArray.sqf b/Functions/Waves/fn_addToMustKillArray.sqf index dd5acd9b..77dfb1f0 100644 --- a/Functions/Waves/fn_addToMustKillArray.sqf +++ b/Functions/Waves/fn_addToMustKillArray.sqf @@ -1,4 +1,3 @@ -#include "..\..\Headers\String Constants.hpp" /* ---------------------------------------------------------------------------- Function: BLWK_fnc_addToMustKillArray @@ -31,11 +30,11 @@ params [ if (isNull _unitToAdd) exitWith {false}; -private _currentArray = missionNamespace getVariable [WAVE_ENEMIES_ARRAY,[]]; +private _currentArray = missionNamespace getVariable ["BLWK_mustKillList",[]]; _currentArray pushBackUnique _unitToAdd; -missionNamespace setVariable [WAVE_ENEMIES_ARRAY,_currentArray,2]; +missionNamespace setVariable ["BLWK_mustKillList",_currentArray,2]; true \ No newline at end of file diff --git a/Functions/Waves/fn_clearMustKillArray.sqf b/Functions/Waves/fn_clearMustKillArray.sqf index 3e97bf83..1eb45389 100644 --- a/Functions/Waves/fn_clearMustKillArray.sqf +++ b/Functions/Waves/fn_clearMustKillArray.sqf @@ -20,10 +20,6 @@ Examples: Author(s): Ansible2 // Cipher ---------------------------------------------------------------------------- */ -#ifndef WAVE_ENEMIES_ARRAY - #include "..\..\Headers\String Constants.hpp" -#endif - // need to check if anyone is still alive before clearing waitUntil { if (call BLWK_fnc_isWaveCleared) exitWith {true}; @@ -31,4 +27,4 @@ waitUntil { false }; -missionNamespace setVariable [WAVE_ENEMIES_ARRAY,[]]; \ No newline at end of file +missionNamespace setVariable ["BLWK_mustKillList",[]]; \ No newline at end of file diff --git a/Functions/Waves/fn_isWaveCleared.sqf b/Functions/Waves/fn_isWaveCleared.sqf index 19a90fef..b25c8ec2 100644 --- a/Functions/Waves/fn_isWaveCleared.sqf +++ b/Functions/Waves/fn_isWaveCleared.sqf @@ -1,4 +1,3 @@ -#include "..\..\Headers\String Constants.hpp" /* ---------------------------------------------------------------------------- Function: BLWK_fnc_isWaveCleared @@ -25,7 +24,7 @@ Author(s): ---------------------------------------------------------------------------- */ if (!isServer) exitWith {false}; -private _index = (missionNamespace getVariable [WAVE_ENEMIES_ARRAY,[]]) findIf {alive _x}; +private _index = (missionNamespace getVariable ["BLWK_mustKillList",[]]) findIf {alive _x}; private _allDronesCreated = missionNamespace getVariable ["BLWK_allDronesCreated",true]; if (_index != -1 OR {!_allDronesCreated}) then { false diff --git a/Functions/Waves/fn_startWave.sqf b/Functions/Waves/fn_startWave.sqf index 89c46391..be647c9e 100644 --- a/Functions/Waves/fn_startWave.sqf +++ b/Functions/Waves/fn_startWave.sqf @@ -1,4 +1,3 @@ -#include "..\..\Headers\String Constants.hpp" /* ---------------------------------------------------------------------------- Function: BLWK_fnc_startWave @@ -112,7 +111,7 @@ call BLWK_fnc_cleanUpTheDead; waitUntil { if ( missionNamespace getVariable ["BLWK_initialWaveSpawnComplete",false] OR - {!(missionNamespace getVariable [WAVE_ENEMIES_ARRAY,[]] isEqualTo [])} + {!(missionNamespace getVariable ["BLWK_mustKillList",[]] isEqualTo [])} ) exitWith {true}; sleep 1; false diff --git a/Headers/String Constants.hpp b/Headers/String Constants.hpp index 26020efb..307e5cee 100644 --- a/Headers/String Constants.hpp +++ b/Headers/String Constants.hpp @@ -1,13 +1,9 @@ // queue Strings #define STANDARD_ENEMY_INFANTRY_QUEUE "BLWK_standardEnemyInfantryqueue" -// Arrays -#define WAVE_ENEMIES_ARRAY "BLWK_mustKillArray" - // Notifications #define SPECIAL_WARNING_TEMPLATE "SpecialWarning" #define TASK_ASSIGNED_TEMPLATE "TaskAssigned" #define TASK_COMPLETE_TEMPLATE "TaskSucceeded" #define COMPLETED_WAVE_NOTIFICATION(WAVE_NUM_STRING) ("Wave " + WAVE_NUM_STRING + " Complete") -//#define DEFECTORS_WAVE_NOTIFICATION "Defectors Are Attacking!" From 007da6bf6b3334c2d66e2c85c00c1727bc070812 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 8 Jul 2023 03:09:59 -0600 Subject: [PATCH 002/133] (#000): adjusted some header comments --- Functions/Other/fn_handleUnconsciousAiEvent.sqf | 2 +- Functions/Supports/fn_reconUAV.sqf | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Functions/Other/fn_handleUnconsciousAiEvent.sqf b/Functions/Other/fn_handleUnconsciousAiEvent.sqf index e0136fd1..015c01dc 100644 --- a/Functions/Other/fn_handleUnconsciousAiEvent.sqf +++ b/Functions/Other/fn_handleUnconsciousAiEvent.sqf @@ -13,7 +13,7 @@ Returns: Examples: (begin example) - call BLWK_fnc_handleUnconsciousAiEvent; + [] spawn BLWK_fnc_handleUnconsciousAiEvent; (end) Author(s): diff --git a/Functions/Supports/fn_reconUAV.sqf b/Functions/Supports/fn_reconUAV.sqf index 93d74da5..f0fbb5d3 100644 --- a/Functions/Supports/fn_reconUAV.sqf +++ b/Functions/Supports/fn_reconUAV.sqf @@ -13,13 +13,11 @@ Returns: Examples: (begin example) - [] spawn BLWK_fnc_reconUAV; - (end) Authors: - Ansible2 // Cipher + Ansible2 ---------------------------------------------------------------------------- */ #define LIFETIME 120 #define MARKER_SIZE 0.5 From f910b0da66de125727129b0b06f2d4676fe98a85 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 8 Jul 2023 03:10:58 -0600 Subject: [PATCH 003/133] (#000): added sleep time while awaiting player selection of custom play area --- Functions/Init Functions/fn_selectPlayArea.sqf | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Functions/Init Functions/fn_selectPlayArea.sqf b/Functions/Init Functions/fn_selectPlayArea.sqf index f8eef0f9..1f2b6385 100644 --- a/Functions/Init Functions/fn_selectPlayArea.sqf +++ b/Functions/Init Functions/fn_selectPlayArea.sqf @@ -23,7 +23,7 @@ Examples: Author(s): Ansible2 // Cipher ---------------------------------------------------------------------------- */ -if (!isServer OR {!canSuspend}) exitWith {}; +if ((!isServer) OR (!canSuspend)) exitWith {}; if (BLWK_customPlayLocation) then { // wait for a play area to be selected by a user @@ -49,7 +49,10 @@ if (BLWK_customPlayLocation) then { }; // waitUntil the play area is received by the server - waitUntil {!isNil "BLWK_playAreaCenter"}; + waitUntil { + sleep 1; + !isNil "BLWK_playAreaCenter" + }; publicVariable "BLWK_playAreaCenter"; } else { // get all location positions on the map and shuffle them From 46571236c2b6cc110779547f89b8fb6f213985f1 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 8 Jul 2023 03:14:01 -0600 Subject: [PATCH 004/133] (#642): renamed BLWK_fnc_addToMustKillArrray -> BLWK_fnc_addToMustKillList --- .../Drone Wave Library/fn_createDroneWave.sqf | 2 +- .../fn_handleHelicopterWave.sqf | 2 +- .../fn_stdEnemyManCreateCode.sqf | 2 +- ...ustKillArray.sqf => fn_addToMustKillList.sqf} | 16 +++++++--------- Headers/descriptionEXT/functions.hpp | 2 +- 5 files changed, 11 insertions(+), 13 deletions(-) rename Functions/Waves/{fn_addToMustKillArray.sqf => fn_addToMustKillList.sqf} (79%) diff --git a/Functions/Wave Type Libraries/Drone Wave Library/fn_createDroneWave.sqf b/Functions/Wave Type Libraries/Drone Wave Library/fn_createDroneWave.sqf index 9ef32fff..d573d123 100644 --- a/Functions/Wave Type Libraries/Drone Wave Library/fn_createDroneWave.sqf +++ b/Functions/Wave Type Libraries/Drone Wave Library/fn_createDroneWave.sqf @@ -116,7 +116,7 @@ for "_i" from 1 to DRONE_NUMBER do { deleteVehicle _unit; }]; - [_drone_temp] remoteExec ["BLWK_fnc_addToMustKillArray",2]; + [_drone_temp] remoteExec ["BLWK_fnc_addToMustKillList",2]; [BLWK_zeus,[[_drone_temp], true]] remoteExecCall ["addCuratorEditableObjects",2]; // space out spawns so that you don't get spammed diff --git a/Functions/Wave Type Libraries/Helicopter Wave Library/fn_handleHelicopterWave.sqf b/Functions/Wave Type Libraries/Helicopter Wave Library/fn_handleHelicopterWave.sqf index 9a9b9309..e8a6334e 100644 --- a/Functions/Wave Type Libraries/Helicopter Wave Library/fn_handleHelicopterWave.sqf +++ b/Functions/Wave Type Libraries/Helicopter Wave Library/fn_handleHelicopterWave.sqf @@ -61,7 +61,7 @@ private _fn_spawnHeli = { // loop through crew (_vehicleArray select 1) apply { - [_x] remoteExecCall ["BLWK_fnc_addToMustKillArray",2]; + [_x] remoteExecCall ["BLWK_fnc_addToMustKillList",2]; [_x] call BLWK_fnc_addStdEnemyManEHs; _x allowDamage true; _x setSkill 0.05; diff --git a/Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyManCreateCode.sqf b/Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyManCreateCode.sqf index 3ec91d92..5399ea9b 100644 --- a/Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyManCreateCode.sqf +++ b/Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyManCreateCode.sqf @@ -39,7 +39,7 @@ if (isNil "_group") then { // add to server's list of units that must be dead before the round can end -[_unit] remoteExecCall ["BLWK_fnc_addToMustKillArray",2]; +[_unit] remoteExecCall ["BLWK_fnc_addToMustKillList",2]; [BLWK_zeus, [[_unit],false]] remoteExecCall ["addCuratorEditableObjects",2]; diff --git a/Functions/Waves/fn_addToMustKillArray.sqf b/Functions/Waves/fn_addToMustKillList.sqf similarity index 79% rename from Functions/Waves/fn_addToMustKillArray.sqf rename to Functions/Waves/fn_addToMustKillList.sqf index 77dfb1f0..eaa9a588 100644 --- a/Functions/Waves/fn_addToMustKillArray.sqf +++ b/Functions/Waves/fn_addToMustKillList.sqf @@ -1,11 +1,10 @@ /* ---------------------------------------------------------------------------- -Function: BLWK_fnc_addToMustKillArray +Function: BLWK_fnc_addToMustKillList Description: Adds a unit to the server's global array that keeps track of what units need to be killed before the round can be done. - Parameters: 0: _unitToAdd : - The unit to add @@ -14,13 +13,11 @@ Returns: Examples: (begin example) - - [myUnit] call BLWK_fnc_addToMustKillArray; - + [myUnit] call BLWK_fnc_addToMustKillList; (end) Author(s): - Ansible2 // Cipher + Ansible2 ---------------------------------------------------------------------------- */ if (!isServer) exitWith {false}; @@ -28,12 +25,13 @@ params [ ["_unitToAdd",objNull,[objNull]] ]; -if (isNull _unitToAdd) exitWith {false}; +if (isNull _unitToAdd) exitWith { + ["A null unit was passed..."] call KISKA_fnc_log; + nil +}; private _currentArray = missionNamespace getVariable ["BLWK_mustKillList",[]]; - _currentArray pushBackUnique _unitToAdd; - missionNamespace setVariable ["BLWK_mustKillList",_currentArray,2]; diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 495e57ae..abe63d33 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -507,7 +507,7 @@ class BLWK class Waves { file = "Functions\Waves"; - class addToMustKillArray + class addToMustKillList {}; class cacheEnemyMenSpawnPositions {}; From dd974b752261506a3518f96fe646e1b2bfdf7736 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 8 Jul 2023 03:14:17 -0600 Subject: [PATCH 005/133] (#0): header comment change --- Functions/Waves/fn_isWaveCleared.sqf | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Functions/Waves/fn_isWaveCleared.sqf b/Functions/Waves/fn_isWaveCleared.sqf index b25c8ec2..8dfc6bbe 100644 --- a/Functions/Waves/fn_isWaveCleared.sqf +++ b/Functions/Waves/fn_isWaveCleared.sqf @@ -14,13 +14,11 @@ Returns: Examples: (begin example) - _areEnemiesDead = call BLWK_fnc_isWaveCleared; - (end) Author(s): - Ansible2 // Cipher + Ansible2 ---------------------------------------------------------------------------- */ if (!isServer) exitWith {false}; From 53fd4bbd870ed77f5c013396b989fb00a95ca7a2 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 8 Jul 2023 03:32:16 -0600 Subject: [PATCH 006/133] (#642): implemented BLWK_fnc_getMustKillList and renamed BLWK_fnc_clearMustKillArray -> BLWK_fnc_clearMustKillList --- Functions/Supports/fn_reconUAV.sqf | 68 ++++++++----------- Functions/Waves/fn_addToMustKillList.sqf | 11 ++- ...KillArray.sqf => fn_clearMustKillList.sqf} | 17 ++--- Functions/Waves/fn_getMustKillList.sqf | 25 +++++++ Functions/Waves/fn_isWaveCleared.sqf | 16 +++-- Functions/Waves/fn_startWave.sqf | 1 + Headers/descriptionEXT/functions.hpp | 4 +- 7 files changed, 76 insertions(+), 66 deletions(-) rename Functions/Waves/{fn_clearMustKillArray.sqf => fn_clearMustKillList.sqf} (52%) create mode 100644 Functions/Waves/fn_getMustKillList.sqf diff --git a/Functions/Supports/fn_reconUAV.sqf b/Functions/Supports/fn_reconUAV.sqf index f0fbb5d3..ba9140e8 100644 --- a/Functions/Supports/fn_reconUAV.sqf +++ b/Functions/Supports/fn_reconUAV.sqf @@ -35,61 +35,49 @@ if !(canSuspend) exitWith { // make it so we can have 2 UAVs active at once missionNamespace setVariable ["BLWK_reconUavActive",true,true]; -private [ - "_unit_temp", - "_markerName_temp", - "_marker_temp", - "_markerExists_temp", - "_unitsArray" -]; - private _createdMarkers = []; private _endtime = time + LIFETIME; while {sleep UPDATE_TIME; time < _endTime} do { - //_unitsArray = units side OPFOR; - _unitsArray = missionNamespace getVariable ["BLWK_mustKillList",[]]; - - if !(_unitsArray isEqualTo []) then { - - { - _markerName_temp = [RECON_MARKER,_forEachIndex] joinString "_"; - _markerExists_temp = (getMarkerType _markerName_temp) != ""; - if (alive _x) then { - if (_markerExists_temp) then { - _markerName_temp setMarkerPos _x; - //diag_log (["Updating position of",_markerName_temp] joinString " "); - } else { - _marker_temp = createMarkerLocal [_markerName_temp,_x]; - _marker_temp setMarkerTypeLocal "mil_triangle"; - _marker_temp setMarkerSizeLocal [MARKER_SIZE,MARKER_SIZE]; - _marker_temp setMarkerColor "colorOPFOR"; - - _createdMarkers pushBack _marker_temp; - //diag_log (["created marker:",_marker_temp] joinString " "); - }; - - sleep UPDATE_TIME; + + { + private _markerName = [RECON_MARKER,_forEachIndex] joinString "_"; + private _markerExists = (getMarkerType _markerName) != ""; + if (alive _x) then { + if (_markerExists) then { + _markerName setMarkerPos _x; + //diag_log (["Updating position of",_markerName] joinString " "); } else { - if (_markerExists_temp) then { - deleteMarker _markerName_temp; - //diag_log (["marker", _markerName_temp, "was deleted"] joinString " "); - }; + private _marker = createMarkerLocal [_markerName,_x]; + _marker setMarkerTypeLocal "mil_triangle"; + _marker setMarkerSizeLocal [MARKER_SIZE,MARKER_SIZE]; + _marker setMarkerColor "colorOPFOR"; + + _createdMarkers pushBack _marker; + //diag_log (["created marker:",_marker] joinString " "); }; - } forEach _unitsArray; - }; + + sleep UPDATE_TIME; + } else { + if (_markerExists) then { + deleteMarker _markerName; + //diag_log (["marker", _markerName, "was deleted"] joinString " "); + }; + }; + } forEach (call BLWK_fnc_getMustKillList); //diag_log "Reached end of while, going back"; }; -// delete markers + _createdMarkers apply { // if marker is not already deleted - if ((getMarkerType _x) != "") then { - //diag_log (["The marker isn't already deleted, deleting marker:",_x] joinString " "); + private _markerNotDeleted = (getMarkerType _x) != ""; + if (_markerNotDeleted) then { deleteMarker _x; }; }; + missionNamespace setVariable ["BLWK_reconUavActive",false,true]; ["Recon UAV is no longer active"] remoteExecCall ["KISKA_fnc_notification",BLWK_allClientsTargetId]; diff --git a/Functions/Waves/fn_addToMustKillList.sqf b/Functions/Waves/fn_addToMustKillList.sqf index eaa9a588..12782e56 100644 --- a/Functions/Waves/fn_addToMustKillList.sqf +++ b/Functions/Waves/fn_addToMustKillList.sqf @@ -9,7 +9,7 @@ Parameters: 0: _unitToAdd : - The unit to add Returns: - BOOL + NOTHING Examples: (begin example) @@ -19,7 +19,7 @@ Examples: Author(s): Ansible2 ---------------------------------------------------------------------------- */ -if (!isServer) exitWith {false}; +if (!isServer) exitWith {}; params [ ["_unitToAdd",objNull,[objNull]] @@ -30,9 +30,6 @@ if (isNull _unitToAdd) exitWith { nil }; -private _currentArray = missionNamespace getVariable ["BLWK_mustKillList",[]]; +private _currentArray = call BLWK_fnc_getMustKillList; _currentArray pushBackUnique _unitToAdd; -missionNamespace setVariable ["BLWK_mustKillList",_currentArray,2]; - - -true \ No newline at end of file +localNamespace setVariable ["BLWK_mustKillList",_currentArray]; diff --git a/Functions/Waves/fn_clearMustKillArray.sqf b/Functions/Waves/fn_clearMustKillList.sqf similarity index 52% rename from Functions/Waves/fn_clearMustKillArray.sqf rename to Functions/Waves/fn_clearMustKillList.sqf index 1eb45389..65b35089 100644 --- a/Functions/Waves/fn_clearMustKillArray.sqf +++ b/Functions/Waves/fn_clearMustKillList.sqf @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- -Function: BLWK_fnc_clearMustKillArray +Function: BLWK_fnc_clearMustKillList Description: Simply clears the global variable array for the next round. @@ -12,19 +12,12 @@ Returns: Examples: (begin example) - - call BLWK_fnc_clearMustKillArray; - + call BLWK_fnc_clearMustKillList; (end) Author(s): - Ansible2 // Cipher + Ansible2 ---------------------------------------------------------------------------- */ -// need to check if anyone is still alive before clearing -waitUntil { - if (call BLWK_fnc_isWaveCleared) exitWith {true}; - sleep 0.5; - false -}; +scriptName "BLWK_fnc_clearMustKillList"; -missionNamespace setVariable ["BLWK_mustKillList",[]]; \ No newline at end of file +localNamespace setVariable ["BLWK_mustKillList",[]]; diff --git a/Functions/Waves/fn_getMustKillList.sqf b/Functions/Waves/fn_getMustKillList.sqf new file mode 100644 index 00000000..c31b4aea --- /dev/null +++ b/Functions/Waves/fn_getMustKillList.sqf @@ -0,0 +1,25 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_getMustKillList + +Description: + Returns the reference to the must kill list for the current wave. + +Parameters: + NONE + +Returns: + - an array of all the units that must be killed + +Examples: + (begin example) + private _listOfUnits = call BLWK_fnc_getMustKillList; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_getMustKillList"; + +if (!isServer) exitWith {[]}; + +localNamespace getVariable ["BLWK_mustKillList",[]] \ No newline at end of file diff --git a/Functions/Waves/fn_isWaveCleared.sqf b/Functions/Waves/fn_isWaveCleared.sqf index 8dfc6bbe..f12dc214 100644 --- a/Functions/Waves/fn_isWaveCleared.sqf +++ b/Functions/Waves/fn_isWaveCleared.sqf @@ -2,7 +2,7 @@ Function: BLWK_fnc_isWaveCleared Description: - Checks all the units in the global must kill array to see if any are still alive. + Checks all the units in the global must kill list to see if any are still alive. Executed from "BLWK_fnc_startWave" @@ -10,21 +10,25 @@ Parameters: NONE Returns: - BOOL + - whether or not all the rquired enemies to kill are dead Examples: (begin example) - _areEnemiesDead = call BLWK_fnc_isWaveCleared; + private _areEnemiesDead = call BLWK_fnc_isWaveCleared; (end) Author(s): Ansible2 ---------------------------------------------------------------------------- */ -if (!isServer) exitWith {false}; +if (!isServer) exitWith { false }; -private _index = (missionNamespace getVariable ["BLWK_mustKillList",[]]) findIf {alive _x}; +private _index = (call BLWK_fnc_getMustKillList) findIf { alive _x }; +private _aUnitIsStillAlive = _index isNotEqualTo -1; +// not all special wave drones spawn right away, so checking that they have +// (and that they are therefore in the kill list) +// before checking if all enemies are dead private _allDronesCreated = missionNamespace getVariable ["BLWK_allDronesCreated",true]; -if (_index != -1 OR {!_allDronesCreated}) then { +if (_aUnitIsStillAlive OR (!_allDronesCreated)) then { false } else { true diff --git a/Functions/Waves/fn_startWave.sqf b/Functions/Waves/fn_startWave.sqf index be647c9e..d1044077 100644 --- a/Functions/Waves/fn_startWave.sqf +++ b/Functions/Waves/fn_startWave.sqf @@ -31,6 +31,7 @@ params [ ["_clearDroppedItems",false] ]; +call BLWK_fnc_clearMustKillList; /* ---------------------------------------------------------------------------- Clean must kill array diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index abe63d33..4e04ad3a 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -513,12 +513,14 @@ class BLWK {}; class cleanUpTheDead {}; - class clearMustKillArray + class clearMustKillList {}; class decideWaveType {}; class endWave {}; + class getMustKillList + {}; class isWaveCleared {}; class setSkill From 3ebcf5801d48b62293861d136602670b5d34dd1b Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 8 Jul 2023 03:36:29 -0600 Subject: [PATCH 007/133] (#642): removed old list clearing from start wave function --- Functions/Waves/fn_startWave.sqf | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/Functions/Waves/fn_startWave.sqf b/Functions/Waves/fn_startWave.sqf index d1044077..66aba4c4 100644 --- a/Functions/Waves/fn_startWave.sqf +++ b/Functions/Waves/fn_startWave.sqf @@ -33,24 +33,6 @@ params [ call BLWK_fnc_clearMustKillList; -/* ---------------------------------------------------------------------------- - Clean must kill array ----------------------------------------------------------------------------- */ -/* - it's rare, but if enemies die too quickly, - this can cause overlap in the next wave of enemies. - These are people that were just being added into the array when it is cleared -*/ -private _arrayCleared = [] spawn BLWK_fnc_clearMustKillArray; -waitUntil { - if (scriptDone _arrayCleared) exitWith {true}; - sleep 0.1; - false -}; - -/* ---------------------------------------------------------------------------- - Clear Dropped Items ----------------------------------------------------------------------------- */ if (_clearDroppedItems) then { private _weaponHolders = BLWK_playAreaCenter nearObjects ["weaponHolder",250]; From 2cc9993c3e419c47770171355734930c2955baeb Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 8 Jul 2023 11:36:30 -0600 Subject: [PATCH 008/133] (#642): made adjustments to loot spawn and made initial call unscheduled --- Functions/Waves/fn_spawnLoot.sqf | 51 +++++++++++++++++++------------- initServer.sqf | 2 +- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/Functions/Waves/fn_spawnLoot.sqf b/Functions/Waves/fn_spawnLoot.sqf index fbfbeda8..9f38e5a0 100644 --- a/Functions/Waves/fn_spawnLoot.sqf +++ b/Functions/Waves/fn_spawnLoot.sqf @@ -46,11 +46,7 @@ if (!isServer) exitWith {false}; /* ---------------------------------------------------------------------------- Delete Previous Loot Markers ---------------------------------------------------------------------------- */ -if !((missionNamespace getVariable ["BLWK_lootMarkers",[]]) isEqualTo []) then { - BLWK_lootMarkers apply { - deleteMarker _x; - }; -}; +BLWK_lootMarkers apply { deleteMarker _x }; /* ---------------------------------------------------------------------------- @@ -59,20 +55,26 @@ if !((missionNamespace getVariable ["BLWK_lootMarkers",[]]) isEqualTo []) then { // Add a bool variable to this in the future to check if the play area size changed if (isNil "BLWK_playAreaBuildings" /*OR {playAreaSizeWasChanged}*/) then { // get ALL buildings in area - private _buildingsInPlayArea = nearestTerrainObjects [BLWK_playAreaCenter,["House"], BLWK_playAreaRadius, false, true]; + private _buildingsInPlayArea = nearestTerrainObjects [ + BLWK_playAreaCenter, + ["House"], + BLWK_playAreaRadius, + false, + true + ]; // make sure the building has configed positions to spawn stuff at BLWK_playAreaBuildings = _buildingsInPlayArea select { - ((_x buildingPos -1) isNotEqualTo []) + private _allBuildingPositions = _x buildingPos -1; + (_allBuildingPositions isNotEqualTo []) }; - BLWK_playAreaBuildings = [BLWK_playAreaBuildings,true] call CBAP_fnc_shuffle; //playAreaSizeWasChanged = false; -} else { - // randomize buildings because the forEach loop below will be the same every time then - BLWK_playAreaBuildings = [BLWK_playAreaBuildings,true] call CBAP_fnc_shuffle; }; +// randomize buildings because the forEach loop below will be the same every time then +// shuffles array in place +[BLWK_playAreaBuildings,true] call CBAP_fnc_shuffle; /* ---------------------------------------------------------------------------- @@ -81,22 +83,29 @@ if (isNil "BLWK_playAreaBuildings" /*OR {playAreaSizeWasChanged}*/) then { private _sortedPositions = []; private _exit = false; { - if (_exit) then {break}; + if (_exit) then { break }; private _currentBuilding = _x; private _buildingIndex = _forEachIndex; // to distribute to every building, every other building, every 3rd, etc. - if ((_buildingIndex mod BLWK_loot_cityDistribution) isEqualTo 0) then { - private _buildingsPositions = _currentBuilding buildingPos -1; + if ((_buildingIndex mod BLWK_loot_cityDistribution) isNotEqualTo 0) then { continue }; - { - if (count _sortedPositions >= MAX_SPAWNS_PLUS_UNIQUES) then {_exit = true; break}; + private _buildingsPositions = _currentBuilding buildingPos -1; + { + if (count _sortedPositions >= MAX_SPAWNS_PLUS_UNIQUES) then { + _exit = true; + break; + }; - if (_forEachIndex isEqualTo 0 OR {(_forEachIndex mod BLWK_loot_roomDistribution) isEqualTo 0}) then { - _sortedPositions pushBack (AGLToASL (_x vectorAdd [0,0,LOOT_HOLDER_Z_BUFFER])); - }; - } forEach _buildingsPositions; - }; + private _positionMatchesBuildingLootDistribution = (_forEachIndex mod BLWK_loot_roomDistribution) isEqualTo 0; + private _isFirstPositionInBuilding = _forEachIndex isEqualTo 0; + if (_isFirstPositionInBuilding OR _positionMatchesBuildingLootDistribution) then { + // mitigate loot from sometimes being in the ground + private _buildingPositionWithHeightIncrease = _x vectorAdd [0,0,LOOT_HOLDER_Z_BUFFER]; + _sortedPositions pushBack (AGLToASL _buildingPositionWithHeightIncrease); + }; + } forEach _buildingsPositions; + } forEach BLWK_playAreaBuildings; // if there are less available positions in the area then the max allowed, just readjust diff --git a/initServer.sqf b/initServer.sqf index ecbe5d10..7e1dc0ae 100644 --- a/initServer.sqf +++ b/initServer.sqf @@ -21,7 +21,7 @@ if (BLWK_buildingsNearTheCrateAreIndestructable_radius > 0) then { [] spawn BLWK_fnc_theCrateBuildingsLoop; }; -call BLWK_fnc_spawnLoot; +[{ call BLWK_fnc_spawnLoot; }] call CBAP_fnc_directCall; [] spawn BLWK_fnc_createBattleAmbienceSound; From 59a104052e30797812d8c9c7e7ace05e244b1baa Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 8 Jul 2023 11:39:32 -0600 Subject: [PATCH 009/133] (#642): added guard against undefined array for BLWK_lootMarkers --- Functions/Waves/fn_spawnLoot.sqf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Functions/Waves/fn_spawnLoot.sqf b/Functions/Waves/fn_spawnLoot.sqf index 9f38e5a0..c3ba1af9 100644 --- a/Functions/Waves/fn_spawnLoot.sqf +++ b/Functions/Waves/fn_spawnLoot.sqf @@ -46,7 +46,7 @@ if (!isServer) exitWith {false}; /* ---------------------------------------------------------------------------- Delete Previous Loot Markers ---------------------------------------------------------------------------- */ -BLWK_lootMarkers apply { deleteMarker _x }; +(missionNamespace getVariable ["BLWK_lootMarkers",[]]) apply { deleteMarker _x }; /* ---------------------------------------------------------------------------- @@ -105,7 +105,7 @@ private _exit = false; _sortedPositions pushBack (AGLToASL _buildingPositionWithHeightIncrease); }; } forEach _buildingsPositions; - + } forEach BLWK_playAreaBuildings; // if there are less available positions in the area then the max allowed, just readjust From c8c6a1c571cdaf71369d8b9616446da863b37376 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 8 Jul 2023 12:31:15 -0600 Subject: [PATCH 010/133] (#642): simplified BLWK_fnc_cleanUpTheDead --- Functions/Waves/fn_cleanUpTheDead.sqf | 58 ++++++--------------------- 1 file changed, 12 insertions(+), 46 deletions(-) diff --git a/Functions/Waves/fn_cleanUpTheDead.sqf b/Functions/Waves/fn_cleanUpTheDead.sqf index 2811186d..33fab679 100644 --- a/Functions/Waves/fn_cleanUpTheDead.sqf +++ b/Functions/Waves/fn_cleanUpTheDead.sqf @@ -2,9 +2,7 @@ Function: BLWK_fnc_cleanUpTheDead Description: - Cleans up dead bodies after the next wave begins. - Also handles heaping the bodies into piles based upon the mission params - for how long the dead should last. + Cleans up dead bodies according to the mission param BLWK_roundsBeforeBodyDeletion. Executed from "BLWK_fnc_startWave" @@ -12,63 +10,31 @@ Parameters: NONE Returns: - BOOL + NOTHING Examples: (begin example) - call BLWK_fnc_cleanUpTheDead; - (end) Author(s): Hilltop(Willtop) & omNomios, - Modified by: Ansible2 // Cipher + Modified by: Ansible2 ---------------------------------------------------------------------------- */ -if (!isServer) exitWIth {false}; - -private _allDeadMen = allDeadMen; +if (!isServer) exitWIth {}; if (BLWK_roundsBeforeBodyDeletion isEqualTo 0) exitWith { - _allDeadMen apply { - if !(isNull _x) then { - deleteVehicle _x; - }; - }; -}; - - -if (BLWK_deadBodies_1 isEqualTo []) then { - BLWK_deadBodies_1 = _allDeadMen; -} else { - if (BLWK_roundsBeforeBodyDeletion isEqualTo 1) then { - private _killed1WaveAgo = _allDeadMen select {!(isNull _x) AND {!(_x in BLWK_deadBodies_1)}}; - BLWK_deadBodies_1 apply { - if !(isNull _x) then { - deleteVehicle _x; - }; - }; - - BLWK_deadBodies_1 = _killed1WaveAgo; - }; + allDeadMen apply { deleteVehicle _x }; }; - -if (BLWK_roundsBeforeBodyDeletion isEqualTo 2) then { - - if (BLWK_deadBodies_2 isEqualTo []) then { - // get all the guys who weren't already added to BLWK_deadBodies_1 the last wave - private _killed1WaveAgo = _allDeadMen select {!(isNull _x) AND {!(_x in BLWK_deadBodies_1)}}; - BLWK_deadBodies_2 = BLWK_deadBodies_1; - BLWK_deadBodies_1 = _killed1WaveAgo; +allDeadMen apply { + private _numberOfWavesUnitHasBeenDead = _x getVariable ["BLWK_numberOfWavesDead",0]; + if (_numberOfWavesUnitHasBeenDead >= BLWK_roundsBeforeBodyDeletion) then { + deleteVehicle _x } else { - BLWK_deadBodies_2 apply { - if !(isNull _x) then { - deleteVehicle _x; - }; - }; - BLWK_deadBodies_2 = []; + _x setVariable ["BLWK_numberOfWavesDead",_numberOfWavesUnitHasBeenDead + 1]; }; }; -true \ No newline at end of file + +nil From a88584297993f70d577ab6cb5c4f223e1db3507d Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 8 Jul 2023 12:45:19 -0600 Subject: [PATCH 011/133] (#642): renamed BLWK_fnc_decideWaveType -> BLWK_fnc_spawnWaveEnemies --- .../fn_civiliansWave.sqf | 2 +- .../Drone Wave Library/fn_handleDroneWave.sqf | 2 +- .../fn_handleHelicopterWave.sqf | 2 +- .../fn_handleMortarWave.sqf | 2 +- .../fn_handleOverrunWave.sqf | 2 +- .../fn_handleParatrooperWave.sqf | 2 +- .../fn_handleDefectorWave.sqf | 2 +- .../fn_handleStandardWave.sqf | 2 +- .../fn_handleSuicideWave.sqf | 2 +- ...deWaveType.sqf => fn_spawnWaveEnemies.sqf} | 36 +++++++++---------- Functions/Waves/fn_startWave.sqf | 18 ++++------ Headers/descriptionEXT/Wave Types.hpp | 2 +- Headers/descriptionEXT/functions.hpp | 4 +-- 13 files changed, 36 insertions(+), 42 deletions(-) rename Functions/Waves/{fn_decideWaveType.sqf => fn_spawnWaveEnemies.sqf} (81%) diff --git a/Functions/Wave Type Libraries/Civilian Wave Library/fn_civiliansWave.sqf b/Functions/Wave Type Libraries/Civilian Wave Library/fn_civiliansWave.sqf index c7a4bd1b..a8db71de 100644 --- a/Functions/Wave Type Libraries/Civilian Wave Library/fn_civiliansWave.sqf +++ b/Functions/Wave Type Libraries/Civilian Wave Library/fn_civiliansWave.sqf @@ -4,7 +4,7 @@ Function: BLWK_fnc_civiliansWave Description: Creates the civilians during a special wave. - It is executed from the "BLWK_fnc_decideWaveType". + It is executed from the "BLWK_fnc_spawnWaveEnemies". Parameters: NONE diff --git a/Functions/Wave Type Libraries/Drone Wave Library/fn_handleDroneWave.sqf b/Functions/Wave Type Libraries/Drone Wave Library/fn_handleDroneWave.sqf index 2d51bc1e..dcaf86e6 100644 --- a/Functions/Wave Type Libraries/Drone Wave Library/fn_handleDroneWave.sqf +++ b/Functions/Wave Type Libraries/Drone Wave Library/fn_handleDroneWave.sqf @@ -5,7 +5,7 @@ Description: This is simply an alias for the below functions. It is used to exec both on whomever the AI handler is without using multiple remoteExecs - Executed from "BLWK_fnc_decideWaveType" + Executed from "BLWK_fnc_spawnWaveEnemies" Parameters: NONE diff --git a/Functions/Wave Type Libraries/Helicopter Wave Library/fn_handleHelicopterWave.sqf b/Functions/Wave Type Libraries/Helicopter Wave Library/fn_handleHelicopterWave.sqf index e8a6334e..75e10874 100644 --- a/Functions/Wave Type Libraries/Helicopter Wave Library/fn_handleHelicopterWave.sqf +++ b/Functions/Wave Type Libraries/Helicopter Wave Library/fn_handleHelicopterWave.sqf @@ -5,7 +5,7 @@ Description: This is simply an alias for the below functions. It is used to exec both on whomever the AI handler is without using multiple remoteExecs - Executed from "BLWK_fnc_decideWaveType" + Executed from "BLWK_fnc_spawnWaveEnemies" Parameters: NONE diff --git a/Functions/Wave Type Libraries/Mortar Wave Library/fn_handleMortarWave.sqf b/Functions/Wave Type Libraries/Mortar Wave Library/fn_handleMortarWave.sqf index 621cbcf5..62fa93b1 100644 --- a/Functions/Wave Type Libraries/Mortar Wave Library/fn_handleMortarWave.sqf +++ b/Functions/Wave Type Libraries/Mortar Wave Library/fn_handleMortarWave.sqf @@ -5,7 +5,7 @@ Description: This is simply an alias for the below functions. It is used to exec both on whomever the AI handler is without using multiple remoteExecs - Executed from "BLWK_fnc_decideWaveType" + Executed from "BLWK_fnc_spawnWaveEnemies" Parameters: NONE diff --git a/Functions/Wave Type Libraries/Overrun Wave Library/fn_handleOverrunWave.sqf b/Functions/Wave Type Libraries/Overrun Wave Library/fn_handleOverrunWave.sqf index 7d8eab12..ad15c2cb 100644 --- a/Functions/Wave Type Libraries/Overrun Wave Library/fn_handleOverrunWave.sqf +++ b/Functions/Wave Type Libraries/Overrun Wave Library/fn_handleOverrunWave.sqf @@ -5,7 +5,7 @@ Description: This is simply an alias for the below functions. It is used to exec both on whomever the AI handler is without using multiple remoteExecs - Executed from "BLWK_fnc_decideWaveType" + Executed from "BLWK_fnc_spawnWaveEnemies" Parameters: NONE diff --git a/Functions/Wave Type Libraries/Paratrooper Wave Library/fn_handleParatrooperWave.sqf b/Functions/Wave Type Libraries/Paratrooper Wave Library/fn_handleParatrooperWave.sqf index 1c5e574f..4c31a996 100644 --- a/Functions/Wave Type Libraries/Paratrooper Wave Library/fn_handleParatrooperWave.sqf +++ b/Functions/Wave Type Libraries/Paratrooper Wave Library/fn_handleParatrooperWave.sqf @@ -5,7 +5,7 @@ Description: This is simply an alias for the below functions. It is used to exec both on whomever the AI handler is without using multiple remoteExecs - Executed from "BLWK_fnc_decideWaveType" + Executed from "BLWK_fnc_spawnWaveEnemies" Parameters: NONE diff --git a/Functions/Wave Type Libraries/Standard Wave Library/fn_handleDefectorWave.sqf b/Functions/Wave Type Libraries/Standard Wave Library/fn_handleDefectorWave.sqf index b477074f..f7c379ed 100644 --- a/Functions/Wave Type Libraries/Standard Wave Library/fn_handleDefectorWave.sqf +++ b/Functions/Wave Type Libraries/Standard Wave Library/fn_handleDefectorWave.sqf @@ -5,7 +5,7 @@ Description: This is simply an alias for the below functions. It is used to exec both on whomever the AI handler is without using multiple remoteExecs - Executed from "BLWK_fnc_decideWaveType" + Executed from "BLWK_fnc_spawnWaveEnemies" Parameters: NONE diff --git a/Functions/Wave Type Libraries/Standard Wave Library/fn_handleStandardWave.sqf b/Functions/Wave Type Libraries/Standard Wave Library/fn_handleStandardWave.sqf index ae8cc698..8835131b 100644 --- a/Functions/Wave Type Libraries/Standard Wave Library/fn_handleStandardWave.sqf +++ b/Functions/Wave Type Libraries/Standard Wave Library/fn_handleStandardWave.sqf @@ -5,7 +5,7 @@ Description: This is simply an alias for the below functions. It is used to exec both on whomever the AI handler is without using multiple remoteExecs - Executed from "BLWK_fnc_decideWaveType" + Executed from "BLWK_fnc_spawnWaveEnemies" Parameters: NONE diff --git a/Functions/Wave Type Libraries/Suicide Wave Library/fn_handleSuicideWave.sqf b/Functions/Wave Type Libraries/Suicide Wave Library/fn_handleSuicideWave.sqf index 77e54566..a35f7896 100644 --- a/Functions/Wave Type Libraries/Suicide Wave Library/fn_handleSuicideWave.sqf +++ b/Functions/Wave Type Libraries/Suicide Wave Library/fn_handleSuicideWave.sqf @@ -5,7 +5,7 @@ Description: This is simply an alias for the below functions. It is used to exec both on whomever the AI handler is without using multiple remoteExecs - Executed from "BLWK_fnc_decideWaveType" + Executed from "BLWK_fnc_spawnWaveEnemies" Parameters: NONE diff --git a/Functions/Waves/fn_decideWaveType.sqf b/Functions/Waves/fn_spawnWaveEnemies.sqf similarity index 81% rename from Functions/Waves/fn_decideWaveType.sqf rename to Functions/Waves/fn_spawnWaveEnemies.sqf index 9dd8118e..eebe74d9 100644 --- a/Functions/Waves/fn_decideWaveType.sqf +++ b/Functions/Waves/fn_spawnWaveEnemies.sqf @@ -1,8 +1,9 @@ /* ---------------------------------------------------------------------------- -Function: BLWK_fnc_decideWaveType +Function: BLWK_fnc_spawnWaveEnemies Description: - Decides what type of wave will be next if there are special waves allowed. + Determines what type of wave should happen next and then initiates the + spawning of enemies for that wave. Executed from "BLWK_fnc_startWave" @@ -10,20 +11,20 @@ Parameters: NONE Returns: - BOOL + NOTHING Examples: (begin example) - call BLWK_fnc_decideWaveType; + call BLWK_fnc_spawnWaveEnemies; (end) Author(s): Hilltop(Willtop) & omNomios, - Modified by: Ansible2 // Cipher + Modified by: Ansible2 ---------------------------------------------------------------------------- */ -scriptName "BLWK_fnc_decideWaveType"; +scriptName "BLWK_fnc_spawnWaveEnemies"; -if (!isServer) exitWith {false}; +if (!isServer) exitWith {}; /* ---------------------------------------------------------------------------- Check if special waves are allowed @@ -33,7 +34,6 @@ if (BLWK_currentWaveNumber >= BLWK_specialWavesStartAt) then { ["Special waves can be selected this wave",false] call KISKA_fnc_log; private _standardWaveLikelihood = 1 - BLWK_specialWaveLikelihood; _selectSpecialWave = selectRandomWeighted [true,BLWK_specialWaveLikelihood,false,_standardWaveLikelihood]; - }; private _usedSpecialWaves = localNamespace getVariable ["BLWK_usedSpecialWaveConfigs",[]]; @@ -44,21 +44,21 @@ private _usedSpecialWaves = localNamespace getVariable ["BLWK_usedSpecialWaveCon ---------------------------------------------------------------------------- */ private _getAllowedSpecialWaves = { BLWK_specialWaveConfigs select { - !(_x in _usedSpecialWaves) AND {missionNamespace getVariable [getText(_x >> "toggleVariable"),true]} + private _waveIsAllowedInParams = missionNamespace getVariable [getText(_x >> "toggleVariable"),true]; + !(_x in _usedSpecialWaves) AND _waveIsAllowedInParams }; }; private _fn_getNormalWave = { - if (BLWK_currentWaveNumber >= BLWK_normalWavesStartAt) then { + if (BLWK_currentWaveNumber >= BLWK_normalWavesStartAt) exitWith { private _weights = BLWK_normalWaveConfigs apply { missionNamespace getVariable [getText(_x >> "weightVariable"),0]; }; - BLWK_normalWaveConfigs selectRandomWeighted _weights; - } else { - missionConfigFile >> "BLWK_waveTypes" >> "normalWaves" >> "standardWave"; - + BLWK_normalWaveConfigs selectRandomWeighted _weights }; + + missionConfigFile >> "BLWK_waveTypes" >> "normalWaves" >> "standardWave" }; @@ -71,7 +71,8 @@ if (_selectSpecialWave) then { ["Selected a special wave instead of standard",false] call KISKA_fnc_log; private _allowedSpecialWaves = call _getAllowedSpecialWaves; - if (_allowedSpecialWaves isEqualTo []) then { + private _allSpecialWavesHaveBeenUsed = _allowedSpecialWaves isEqualTo []; + if (_allSpecialWavesHaveBeenUsed) then { _usedSpecialWaves = []; localNamespace setVariable ["BLWK_usedSpecialWaveConfigs",_usedSpecialWaves]; _allowedSpecialWaves = call _getAllowedSpecialWaves; @@ -113,14 +114,13 @@ if ([_waveConfigPath >> "compileNotificationText"] call BIS_fnc_getCfgDataBool) }; _notification pushBack _notificationText; + private _players = call CBAP_fnc_players; _notification remoteExec ["BIS_fnc_showNotification", _players]; - - // play a sound for special waves if (_playAlarm) then { ["Alarm"] remoteExec ["playSound", _players]; }; -true +nil diff --git a/Functions/Waves/fn_startWave.sqf b/Functions/Waves/fn_startWave.sqf index 66aba4c4..556c1298 100644 --- a/Functions/Waves/fn_startWave.sqf +++ b/Functions/Waves/fn_startWave.sqf @@ -14,18 +14,16 @@ Returns: Examples: (begin example) - - [true] spawn BLWK_fnc_startWave; - + [true] call BLWK_fnc_startWave; (end) Author(s): Hilltop(Willtop) & omNomios, - Modified by: Ansible2 // Cipher + Modified by: Ansible2 ---------------------------------------------------------------------------- */ scriptName "BLWK_fnc_startWave"; -if (!isServer OR {!canSuspend}) exitWith {}; +if (!isServer) exitWith {}; params [ ["_clearDroppedItems",false] @@ -62,14 +60,10 @@ missionNamespace setVariable ["BLWK_initialWaveSpawnComplete",false]; Decide Wave Type/Handle Extraction ---------------------------------------------------------------------------- */ if (missionNamespace getVariable ["BLWK_extractionQueued",false]) then { - [ - { - call BLWK_fnc_extraction; - } - ] call CBAP_fnc_directCall; + call BLWK_fnc_extraction; } else { - call BLWK_fnc_decideWaveType; + call BLWK_fnc_spawnWaveEnemies; // loot is spawned before the wave starts at round 1 if (BLWK_currentWaveNumber > BLWK_startingFromWaveNumber) then { @@ -94,7 +88,7 @@ call BLWK_fnc_cleanUpTheDead; waitUntil { if ( missionNamespace getVariable ["BLWK_initialWaveSpawnComplete",false] OR - {!(missionNamespace getVariable ["BLWK_mustKillList",[]] isEqualTo [])} + {(call BLWK_fnc_getMusKillList) isNotEqualTo []} ) exitWith {true}; sleep 1; false diff --git a/Headers/descriptionEXT/Wave Types.hpp b/Headers/descriptionEXT/Wave Types.hpp index 5b18367f..3eb0f01a 100644 --- a/Headers/descriptionEXT/Wave Types.hpp +++ b/Headers/descriptionEXT/Wave Types.hpp @@ -6,7 +6,7 @@ class BLWK_waveTypes { class standardWave { - onSelected = "remoteExec ['BLWK_fnc_handleStandardWave',BLWK_theAIHandlerOwnerID]"; // uncompiled code that is run on the server when the wave is selected (started). For context of execution see BLWK_fnc_startWave's use of BLWK_fnc_decideWaveType + onSelected = "remoteExec ['BLWK_fnc_handleStandardWave',BLWK_theAIHandlerOwnerID]"; // uncompiled code that is run on the server when the wave is selected (started). For context of execution see BLWK_fnc_startWave's use of BLWK_fnc_spawnWaveEnemies //onWaveEnd = ""; // uncompiled code that is run on the server when the wave is ended creationNotificationTemplate = TASK_ASSIGNED_TEMPLATE; // a CfgNotification template for when the wave starts notificationText = "['','Incoming Wave: ' + (str BLWK_currentWaveNumber)]"; // text to appear in wave start notification diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 4e04ad3a..9a57c9c9 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -515,8 +515,6 @@ class BLWK {}; class clearMustKillList {}; - class decideWaveType - {}; class endWave {}; class getMustKillList @@ -529,6 +527,8 @@ class BLWK {}; class startWave {}; + class spawnWaveEnemies + {}; class startWaveCountdown {}; }; From bd918ab58420b05ccc7533284e56bb8ef0ca15ab Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 8 Jul 2023 16:44:16 -0600 Subject: [PATCH 012/133] (#642): added KISKA_fnc_selectRandom --- KISKA Systems/KISKA Functions.hpp | 2 + .../fn_selectRandom.sqf | 56 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 KISKA Systems/KISKA Utility Functions/fn_selectRandom.sqf diff --git a/KISKA Systems/KISKA Functions.hpp b/KISKA Systems/KISKA Functions.hpp index 3f947028..2783155f 100644 --- a/KISKA Systems/KISKA Functions.hpp +++ b/KISKA Systems/KISKA Functions.hpp @@ -159,6 +159,8 @@ class KISKA {}; class removeArsenal {}; + class selectRandom + {}; class setCrew {}; class spawnVehicle diff --git a/KISKA Systems/KISKA Utility Functions/fn_selectRandom.sqf b/KISKA Systems/KISKA Utility Functions/fn_selectRandom.sqf new file mode 100644 index 00000000..e8c6d3a2 --- /dev/null +++ b/KISKA Systems/KISKA Utility Functions/fn_selectRandom.sqf @@ -0,0 +1,56 @@ +/* ---------------------------------------------------------------------------- +Function: KISKA_fnc_selectRandom + +Description: + Selects randomly an entry from an array be it weighted or unweighted. + +Parameters: + 0: _array - An array either formatted as [value, weight (number)], or + just values ([value1,value2]) + 1: _valueType - A variable that should have the same type as the value + entries in the array e.g. "" for string, [] for array + (only needed for possibly weighted arrays) + +Returns: + - Random entry from the array + +Examples: + (begin example) + private _randomValue = [[ + "thing1", + "thing2" + ]] call KISKA_fnc_selectRandom; + (end) + + (begin example) + private _weight1 = 0.5; + private _weight2 = 0.5; + + private _randomWeightedValue = [ + ["thing1", _weight1, + "thing2", _weight2], + "" + ] call KISKA_fnc_selectRandom; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "KISKA_fnc_selectRandom"; + +params [ + ["_array",[],[[]]], + "_valueType" +]; + +if (isNil "_valueType") exitWith { + selectRandom _array; +}; + +private _weightedArray = _array isEqualTypeParams [_valueType,1]; +if (_weightedArray) exitWith { + selectRandomWeighted _array; +}; + + +selectRandom _array; From 8fbce5e5da0cb004cf95f0e849a9f388fc581ea2 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 8 Jul 2023 17:05:59 -0600 Subject: [PATCH 013/133] (#642): added notifyAdminsOrHostOfError --- .../Other/fn_notifyAdminsOrHostsOfError.sqf | 39 +++++++++++++++++++ Headers/descriptionEXT/functions.hpp | 2 + 2 files changed, 41 insertions(+) create mode 100644 Functions/Other/fn_notifyAdminsOrHostsOfError.sqf diff --git a/Functions/Other/fn_notifyAdminsOrHostsOfError.sqf b/Functions/Other/fn_notifyAdminsOrHostsOfError.sqf new file mode 100644 index 00000000..a67d6b54 --- /dev/null +++ b/Functions/Other/fn_notifyAdminsOrHostsOfError.sqf @@ -0,0 +1,39 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_notifyAdminsOrHostOfError + +Description: + Prints a simple KISKA Notify error notification on screen. + +Parameters: + 0: _message : - The second line of the notification. + Formatted the same as the parameters for CBA_fnc_notify: + _lineN - N-th content line (may be passed directly if only 1 line is required). + _text - Text to display or path to .paa or .jpg image (may be passed directly if only text is required). + _size - Text or image size multiplier. (optional, default: 1) + _color - RGB or RGBA color (range 0-1). (optional, default: [1, 1, 1, 1]) + 1: _lifetime : - How long the notification lasts in seconds (at least 2) + +Returns: + NOTHING + +Examples: + (begin example) + [ + "An error happened somewhere" + ] remoteExec ["BLWK_fnc_notifyAdminsOrHostOfError",0]; + (end) + +Author: + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "KISKA_fnc_errorNotification"; + +if !(call KISKA_fnc_isAdminOrHost) exitWith {}; + +params [ + ["_message","",["",[]]], + ["_lifetime",4,[123]] +]; + + +_this call KISKA_fnc_errorNotification; diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 9a57c9c9..b5b71a05 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -252,6 +252,8 @@ class BLWK {}; class lootReveal {}; + class notifyAdminsOrHostOfError + {}; class optreMedicalToVanilla {}; class randomizeWeapons From 9cd336a2eb40d872d8e8dfe85fd4fadefec68df7 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 8 Jul 2023 17:07:29 -0600 Subject: [PATCH 014/133] (#642): updated description for BLWK_fnc_notifyAdminsOrHostOfError --- Functions/Other/fn_notifyAdminsOrHostsOfError.sqf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Functions/Other/fn_notifyAdminsOrHostsOfError.sqf b/Functions/Other/fn_notifyAdminsOrHostsOfError.sqf index a67d6b54..b9038202 100644 --- a/Functions/Other/fn_notifyAdminsOrHostsOfError.sqf +++ b/Functions/Other/fn_notifyAdminsOrHostsOfError.sqf @@ -2,7 +2,7 @@ Function: BLWK_fnc_notifyAdminsOrHostOfError Description: - Prints a simple KISKA Notify error notification on screen. + Prints an error onto the screen of only sever and admin machines. Parameters: 0: _message : - The second line of the notification. @@ -26,7 +26,7 @@ Examples: Author: Ansible2 ---------------------------------------------------------------------------- */ -scriptName "KISKA_fnc_errorNotification"; +scriptName "BLWK_fnc_notifyAdminsOrHostOfError"; if !(call KISKA_fnc_isAdminOrHost) exitWith {}; From cd622feeb2898d43567d39d1891a41c3f56b0f60 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 8 Jul 2023 17:08:01 -0600 Subject: [PATCH 015/133] (#642): convert indents --- Functions/Other/fn_notifyAdminsOrHostsOfError.sqf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Functions/Other/fn_notifyAdminsOrHostsOfError.sqf b/Functions/Other/fn_notifyAdminsOrHostsOfError.sqf index b9038202..f3de5128 100644 --- a/Functions/Other/fn_notifyAdminsOrHostsOfError.sqf +++ b/Functions/Other/fn_notifyAdminsOrHostsOfError.sqf @@ -19,8 +19,8 @@ Returns: Examples: (begin example) [ - "An error happened somewhere" - ] remoteExec ["BLWK_fnc_notifyAdminsOrHostOfError",0]; + "An error happened somewhere" + ] remoteExec ["BLWK_fnc_notifyAdminsOrHostOfError",0]; (end) Author: From 020d5fbd97f1bd58f74100b6cd6c54bd55da44e7 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 8 Jul 2023 18:52:30 -0600 Subject: [PATCH 016/133] (#642): started refactor of queue --- Functions/Queue/fn_addToQueue.sqf | 40 ----------------- Functions/Queue/fn_spawnQueue_add.sqf | 44 +++++++++++++++++++ .../Queue/fn_spawnQueue_popAndCreate.sqf | 28 ++++++++++++ Headers/descriptionEXT/functions.hpp | 6 ++- 4 files changed, 76 insertions(+), 42 deletions(-) delete mode 100644 Functions/Queue/fn_addToQueue.sqf create mode 100644 Functions/Queue/fn_spawnQueue_add.sqf create mode 100644 Functions/Queue/fn_spawnQueue_popAndCreate.sqf diff --git a/Functions/Queue/fn_addToQueue.sqf b/Functions/Queue/fn_addToQueue.sqf deleted file mode 100644 index 54092cd6..00000000 --- a/Functions/Queue/fn_addToQueue.sqf +++ /dev/null @@ -1,40 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_addToQueue - -Description: - Adds the type and position of a unit to a queue - -Parameters: - 0: _queueName : - The global var name for the queue you want to add to - 1: _type : - The className of the unit you want to add to the queue - 2: _position : - The position to spawn the unit at - -Returns: - BOOL - -Examples: - (begin example) - - ["BLWK_standardInfantryQueue",_aClassName,[0,0,0]] call BLWK_fnc_addToQueue; - - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -params [ - ["_queueName","",[""]], - ["_type","",[""]], - ["_position",[],[objNull,[]]] -]; - -if (_queueName isEqualTo "" OR {_type isEqualTo ""} OR {_position isEqualTo []}) exitWith {false}; - -if (isNil _queueName) then { - missionNamespace setVariable [_queueName,[]]; -}; - -(missionNamespace getVariable _queueName) pushBack [_type,_position]; - - -true \ No newline at end of file diff --git a/Functions/Queue/fn_spawnQueue_add.sqf b/Functions/Queue/fn_spawnQueue_add.sqf new file mode 100644 index 00000000..fccd4b9d --- /dev/null +++ b/Functions/Queue/fn_spawnQueue_add.sqf @@ -0,0 +1,44 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_queue_add + +Description: + Adds the given args to the enemy spawn queue + +Parameters: + 0: _class : - The classname of the unit you want to add to the queue + 1: _position : - The position to spawn the unit at + 2: _onManCreatedFunctionName : - The global var name for the function + to run once the unit is created on the AI handler owner machine. + +Returns: + NOTHING + +Examples: + (begin example) + [ + "I_Soldier_A_F", + [0,0,0], + "BLWK_fnc_standardWave_onManCreated" + ] call BLWK_fnc_queue_add; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_queue_add"; + +params [ + ["_class","",[""]], + ["_position",[],[objNull,[]]] + ["_onManCreatedFunctionName","BLWK_fnc_standardWave_onManCreated",[""]], +]; + +if (isNil {localNamespace getVariable "BLWK_spawnQueue"}) then { + localNamespace setVariable ["BLWK_spawnQueue",[]]; +}; + +private _queue = localNamespace getVariable "BLWK_spawnQueue"; +_queue pushBack _this; + + +nil diff --git a/Functions/Queue/fn_spawnQueue_popAndCreate.sqf b/Functions/Queue/fn_spawnQueue_popAndCreate.sqf new file mode 100644 index 00000000..c3fa25c8 --- /dev/null +++ b/Functions/Queue/fn_spawnQueue_popAndCreate.sqf @@ -0,0 +1,28 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_spawnQueue_popAndCreate + +Description: + Takes the first entry in the enemy man spawn queue, removes the item and then + spawns the unit from the arguments. + +Parameters: + NONE + +Returns: + NOTHING + +Examples: + (begin example) + call BLWK_fnc_spawnQueue_popAndCreate; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_spawnQueue_popAndCreate"; + +// check if queue is empty +private _queue = localNamespace getVariable ["BLWK_spawnQueue",[]]; +if (_queue isEqualTo []) exitWith {}; + +(_queue deleteAt 0) params ["_type","_position","_onManCreatedFunctionName"]; diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index b5b71a05..f8fa3b86 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -297,10 +297,12 @@ class BLWK class Queue { file = "Functions\Queue"; - class addtoQueue - {}; class createFromQueue {}; + class spawnQueue_add + {}; + class spawnQueue_popAndCreate + {}; }; class SatelliteShop From 9df1d71d23e69782701eab788b6d5af5e54884c5 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 8 Jul 2023 18:53:59 -0600 Subject: [PATCH 017/133] (#642): started on refactor of wave creation --- .../Common Wave Library/fn_wave_create.sqf | 171 ++++++++++++++++++ ...aveEnemies.sqf => fn_getConfigForWave.sqf} | 43 +---- Functions/Waves/fn_startWave.sqf | 3 +- Headers/descriptionEXT/functions.hpp | 11 +- 4 files changed, 189 insertions(+), 39 deletions(-) create mode 100644 Functions/Wave Type Libraries/Common Wave Library/fn_wave_create.sqf rename Functions/Waves/{fn_spawnWaveEnemies.sqf => fn_getConfigForWave.sqf} (69%) diff --git a/Functions/Wave Type Libraries/Common Wave Library/fn_wave_create.sqf b/Functions/Wave Type Libraries/Common Wave Library/fn_wave_create.sqf new file mode 100644 index 00000000..011f0c5e --- /dev/null +++ b/Functions/Wave Type Libraries/Common Wave Library/fn_wave_create.sqf @@ -0,0 +1,171 @@ + +scriptName "BLWK_fnc_wave_create"; + +// if (clientOwner isNotEqualTo BLWK_theAIHandlerOwnerID) exitWith { +// private _message = [ +// "Executed BLWK_fnc_wave_create on clientOwner: ", +// clientOwner, +// " while BLWK_theAIHandlerOwnerID was: ", +// BLWK_theAIHandlerOwnerID, +// " on this machine! Defaulting to sever to handle the wave" +// ] joinString ""; +// [_message,5] remoteExecCall ["KISKA_fnc_errorNotification",0]; +// [_message,true] remoteExecCall ["KISKA_fnc_log",2]; + +// _this remoteExecCall ["BLWK_fnc_wave_create",2]; +// }; + +// #define DEFAULT_ON_WAVE_SELECTED_NAME "BLWK_fnc_standardWave_onWaveSelected" +#define DEFAULT_WAVE_CONFIG_PATH missionConfigFile >> "BLWK_waveTypes" >> "normalWaves" >> "standardWave" +#define SPECIAL_WAVE_CONFIG missionConfigFile >> "BLWK_waveTypes" >> "specialWaves" +#define BASE_ENEMY_NUMBER 2 + +params [ + ["_waveConfig",configNull,[configNull]], + ["_totalNumEnemiesToSpawnDuringWave",-1,[123]] +]; + +// private _onWaveSelectedFunction = missionNamespace getVariable [_onWaveSelectedFunctionName,{}]; +// if (_waveConfig isEqualTo configNull) exitWith { +// private _message = [ +// "Could not find onWaveSelected function with the name: ", +// _onWaveSelectedFunction, +// " on the server! Using standard Wave..." +// ] joinString ""; + +// [_message,10] remoteExecCall ["KISKA_fnc_errorNotification",0]; +// [_message,true] remoteExecCall ["KISKA_fnc_log",2]; + +// [DEFAULT_ON_WAVE_SELECTED_NAME] call BLWK_fnc_wave_create; +// }; + +private _notifyOfError = { + params ["_message"]; + + [_message] remoteExec ["BLWK_fnc_notifyAdminsOrHostOfError",0]; + [_message,true] call KISKA_fnc_log; +}; + +private _fn_getFunctionFromWaveConfig = { + params [ + "_configProperty", + ["_justName",false] + ]; + + private _requestedFunctionName = getText(_waveConfig >> _configProperty); + private _default_functionName = getText(DEFAULT_WAVE_CONFIG_PATH >> _configProperty); + if (_requestedFunctionName isEqualTo "") then { + _requestedFunctionName = _default_functionName + }; + + private _requestedFunction = missionNamespace getVariable [ + _requestedFunctionName, + {} + ]; + if (_requestedFunction isEqualTo {}) then { + private _message = [ + "Could not find function for property: ", + _configProperty, + " with the name: ", + _requestedFunctionName, + " on the server in config: ", + _waveConfig + ] joinString ""; + [_message] call _notifyOfError; + + _requestedFunction = missionNamespace getVariable _default_functionName; + }; + + + if (_justName) exitWith { _requestedFunctionName }; + _requestedFunction +}; + + +/* ---------------------------------------------------------------------------- + Create Queue +---------------------------------------------------------------------------- */ +private _generatManClassesFunction = ["generateMenClassnames"] call _fn_getFunctionFromWaveConfig; +private _generateSpawnPositionFunction = ["generateManSpawnPosition"] call _fn_getFunctionFromWaveConfig; + +if (_totalNumEnemiesToSpawnDuringWave < BASE_ENEMY_NUMBER) then { + _totalNumEnemiesToSpawnDuringWave = BASE_ENEMY_NUMBER * ((BLWK_enemiesPerWaveMultiplier * BLWK_currentWaveNumber) + 1); + _totalNumEnemiesToSpawnDuringWave = _totalNumEnemiesToSpawnDuringWave + (BLWK_enemiesPerPlayerMultiplier * (count (call CBAP_fnc_players))); + _totalNumEnemiesToSpawnDuringWave = round _totalNumEnemiesToSpawnDuringWave; +}; + +private _availableClassnames = call _generatManClassesFunction; +private "_spawnPosition_temp"; +if (!BLWK_multipleEnemyPositions) then { + _spawnPosition_temp = selectRandom BLWK_infantrySpawnPositions; +}; + +private _onManCreatedFunctionName = ["generateManSpawnPosition",true] call _fn_getFunctionFromWaveConfig; +for "_i" from 1 to _totalNumEnemiesToSpawnDuringWave do { + if (BLWK_multipleEnemyPositions) then { + _spawnPosition_temp = call _generateSpawnPositionFunction; + }; + + private _class = [_availableClassnames] call KISKA_fnc_selectRandom; + [ + _class, + _spawnPosition_temp, + _onManCreatedFunctionName + ] call BLWK_fnc_addToQueue; +}; + + +/* ---------------------------------------------------------------------------- + Send wave start notification +---------------------------------------------------------------------------- */ +private _notification = []; +_notification pushBack (getText(_waveConfigPath >> "creationNotificationTemplate")); + +private _notificationText = getText(_waveConfigPath >> "notificationText"); +if ([_waveConfigPath >> "compileNotificationText"] call BIS_fnc_getCfgDataBool) then { + _notificationText = call compileFinal _notificationText; + +} else { + _notificationText = [_notificationText]; + +}; +_notification pushBack _notificationText; + + +private _players = call CBAP_fnc_players; +_notification remoteExec ["BIS_fnc_showNotification", _players]; +// play a sound for special waves +private _isSpecialWave = [_waveConfigPath,SPECIAL_WAVE_CONFIG] call CBAP_fnc_inheritsFrom; +if (_isSpecialWave) then { + ["Alarm"] remoteExec ["playSound", _players]; +}; + +// TODO: +// need to create base enemy units +// server needs to know when all units are dead to end the wave +// server needs to know that wave has started (e.g. initial enemies have spawned) + + +// Wave types determine how to create enemies to a point +// Things the ai owner cares about: +// 1. where is the guy spawning +// 2. what type is he +// 3. what code should I run on his creation? + +// [] remoteExecCall ["BLWK_fnc_onWaveEnemiesSpawned",2]; + + +localNamespace setVariable ["BLWK_currentWaveConfig",_waveConfigPath]; + +nil + + + + + + + + + + + diff --git a/Functions/Waves/fn_spawnWaveEnemies.sqf b/Functions/Waves/fn_getConfigForWave.sqf similarity index 69% rename from Functions/Waves/fn_spawnWaveEnemies.sqf rename to Functions/Waves/fn_getConfigForWave.sqf index eebe74d9..131f3d54 100644 --- a/Functions/Waves/fn_spawnWaveEnemies.sqf +++ b/Functions/Waves/fn_getConfigForWave.sqf @@ -1,9 +1,9 @@ /* ---------------------------------------------------------------------------- -Function: BLWK_fnc_spawnWaveEnemies +Function: BLWK_fnc_getConfigForWave Description: - Determines what type of wave should happen next and then initiates the - spawning of enemies for that wave. + Determines what type of wave should happen next and returns the selected + wave's config. Executed from "BLWK_fnc_startWave" @@ -11,18 +11,18 @@ Parameters: NONE Returns: - NOTHING + - The config of the selected wave Examples: (begin example) - call BLWK_fnc_spawnWaveEnemies; + private _waveConfig = call BLWK_fnc_getConfigForWave; (end) Author(s): Hilltop(Willtop) & omNomios, Modified by: Ansible2 ---------------------------------------------------------------------------- */ -scriptName "BLWK_fnc_spawnWaveEnemies"; +scriptName "BLWK_fnc_getConfigForWave"; if (!isServer) exitWith {}; @@ -65,7 +65,6 @@ private _fn_getNormalWave = { /* ---------------------------------------------------------------------------- Select wave type ---------------------------------------------------------------------------- */ -private _playAlarm = false; private _waveConfigPath = configNull; if (_selectSpecialWave) then { ["Selected a special wave instead of standard",false] call KISKA_fnc_log; @@ -83,7 +82,6 @@ if (_selectSpecialWave) then { _waveConfigPath = call _fn_getNormalWave; } else { - _playAlarm = true; _usedSpecialWaves pushBack _waveConfigPath; localNamespace setVariable ["BLWK_usedSpecialWaveConfigs",_usedSpecialWaves]; @@ -94,33 +92,6 @@ if (_selectSpecialWave) then { _waveConfigPath = call _fn_getNormalWave; }; -localNamespace setVariable ["BLWK_currentWaveConfig",_waveConfigPath]; -call compileFinal (getText(_waveConfigPath >> "onSelected")); -/* ---------------------------------------------------------------------------- - Send wave start notification ----------------------------------------------------------------------------- */ -private _notification = []; -_notification pushBack (getText(_waveConfigPath >> "creationNotificationTemplate")); - -private _notificationText = getText(_waveConfigPath >> "notificationText"); -if ([_waveConfigPath >> "compileNotificationText"] call BIS_fnc_getCfgDataBool) then { - _notificationText = call compileFinal _notificationText; - -} else { - _notificationText = [_notificationText]; - -}; -_notification pushBack _notificationText; - - -private _players = call CBAP_fnc_players; -_notification remoteExec ["BIS_fnc_showNotification", _players]; -// play a sound for special waves -if (_playAlarm) then { - ["Alarm"] remoteExec ["playSound", _players]; -}; - - -nil +_waveConfigPath diff --git a/Functions/Waves/fn_startWave.sqf b/Functions/Waves/fn_startWave.sqf index 556c1298..dd75e7d0 100644 --- a/Functions/Waves/fn_startWave.sqf +++ b/Functions/Waves/fn_startWave.sqf @@ -63,7 +63,8 @@ if (missionNamespace getVariable ["BLWK_extractionQueued",false]) then { call BLWK_fnc_extraction; } else { - call BLWK_fnc_spawnWaveEnemies; + private _waveConfig = call BLWK_fnc_getConfigForWave; + [_waveConfig] call BLWK_fnc_wave_create; // loot is spawned before the wave starts at round 1 if (BLWK_currentWaveNumber > BLWK_startingFromWaveNumber) then { diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index f8fa3b86..6e520ffd 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -463,6 +463,13 @@ class BLWK class handleParatrooperWave {}; }; + class CommonWaveLib + { + file = "Functions\Wave Type Libraries\Common Wave Library"; + class wave_create + {}; + }; + class StandardWaveLib class StandardWaveLibrary { @@ -521,6 +528,8 @@ class BLWK {}; class endWave {}; + class getConfigForWave + {}; class getMustKillList {}; class isWaveCleared @@ -531,8 +540,6 @@ class BLWK {}; class startWave {}; - class spawnWaveEnemies - {}; class startWaveCountdown {}; }; From 10bb81563311aa091c7207e2a4ffd6760dfe2be9 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 8 Jul 2023 18:54:54 -0600 Subject: [PATCH 018/133] (#642): started on refactor of standard wave --- ..._standardWave_generateManSpawnPosition.sqf | 23 +++++++ .../fn_standardWave_generateMenClassnames.sqf | 49 +++++++++++++++ .../fn_standardWave_onManCreated.sqf | 0 .../fn_standardWave_onWaveSelected.sqf | 0 Headers/descriptionEXT/Wave Types.hpp | 62 ++++++++++++++----- Headers/descriptionEXT/functions.hpp | 12 ++++ 6 files changed, 132 insertions(+), 14 deletions(-) create mode 100644 Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_generateManSpawnPosition.sqf create mode 100644 Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_generateMenClassnames.sqf create mode 100644 Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onManCreated.sqf create mode 100644 Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveSelected.sqf diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_generateManSpawnPosition.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_generateManSpawnPosition.sqf new file mode 100644 index 00000000..23bd0f92 --- /dev/null +++ b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_generateManSpawnPosition.sqf @@ -0,0 +1,23 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_standardWave_generateManSpawnPosition + +Description: + Gets a spawn position for a unit to a man unit to spawn at. + +Parameters: + NONE + +Returns: + - A position for a man unit to spawn. + +Examples: + (begin example) + private _position = call BLWK_fnc_standardWave_generateManSpawnPosition; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_standardWave_generateManSpawnPosition"; + +selectRandom BLWK_infantrySpawnPositions diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_generateMenClassnames.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_generateMenClassnames.sqf new file mode 100644 index 00000000..ad423494 --- /dev/null +++ b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_generateMenClassnames.sqf @@ -0,0 +1,49 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_standardWave_generateMenClassnames + +Description: + Gets the standard (weighted) list of available men classes. + +Parameters: + NONE + +Returns: + <(STRING | NUMBER)[]> - A weighted or unweighted array of classnames that + enemy units will spawn from. + +Examples: + (begin example) + private _availableClasses = call BLWK_fnc_standardWave_generateMenClassnames; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_standardWave_generateMenClassnames"; + + +private _availableClasses = []; +// classes +_availableClasses pushback BLWK_level1Faction_menClasses; +// weight of class +_availableClasses pushBack BLWK_level1Faction_weight; + +if (BLWK_currentWaveNumber >= BLWK_level2Faction_startWave) then { + _availableClasses pushback BLWK_level2Faction_menClasses; + _availableClasses pushBack BLWK_level2Faction_weight; +}; +if (BLWK_currentWaveNumber > BLWK_level3Faction_startWave) then { + _availableClasses pushback BLWK_level3Faction_menClasses; + _availableClasses pushBack BLWK_level3Faction_weight; +}; +if (BLWK_currentWaveNumber > BLWK_level4Faction_startWave) then { + _availableClasses pushback BLWK_level4Faction_menClasses; + _availableClasses pushBack BLWK_level4Faction_weight; +}; +if (BLWK_currentWaveNumber > BLWK_level5Faction_startWave) then { + _availableClasses pushback BLWK_level5Faction_menClasses; + _availableClasses pushBack BLWK_level5Faction_weight; +}; + + +_availableClasses diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onManCreated.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onManCreated.sqf new file mode 100644 index 00000000..e69de29b diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveSelected.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveSelected.sqf new file mode 100644 index 00000000..e69de29b diff --git a/Headers/descriptionEXT/Wave Types.hpp b/Headers/descriptionEXT/Wave Types.hpp index 3eb0f01a..faf28981 100644 --- a/Headers/descriptionEXT/Wave Types.hpp +++ b/Headers/descriptionEXT/Wave Types.hpp @@ -6,21 +6,52 @@ class BLWK_waveTypes { class standardWave { - onSelected = "remoteExec ['BLWK_fnc_handleStandardWave',BLWK_theAIHandlerOwnerID]"; // uncompiled code that is run on the server when the wave is selected (started). For context of execution see BLWK_fnc_startWave's use of BLWK_fnc_spawnWaveEnemies - //onWaveEnd = ""; // uncompiled code that is run on the server when the wave is ended - creationNotificationTemplate = TASK_ASSIGNED_TEMPLATE; // a CfgNotification template for when the wave starts - notificationText = "['','Incoming Wave: ' + (str BLWK_currentWaveNumber)]"; // text to appear in wave start notification - compileNotificationText = 1; // notificationText will be compiled and called. It must return an array compatible with the "arguments" parameter of BIS_fnc_showNotification + // uncompiled code that is run on the server when the wave is selected (started). + // For context of execution see BLWK_fnc_startWave's use of BLWK_fnc_getConfigForWave + // onSelected = "remoteExecCall ['BLWK_fnc_handleStandardWave',BLWK_theAIHandlerOwnerID]"; + + // a function that returns a list of queue entries of enemies to spawn + // an example of the expected return shape: + /* + [ + [ + "I_Soldier_A_F", // enemy class name + [0,0,0] // spawn position ATL + ] + ] + */ + generateMenClassnames = "BLWK_fnc_standardWave_generateMenClassnames"; + generateManSpawnPosition = "BLWK_fnc_standardWave_generateManSpawnPosition"; + + // The name of a function that exists on the AI handler owner that will be called + onWaveSelected = "BLWK_fnc_standardWave_onWaveSelected"; + onManCreated = "BLWK_fnc_standardWave_onManCreated"; + + // uncompiled code that is run on the server when the wave is ended + //onWaveEnd = ""; + + // a CfgNotification template for when the wave starts + creationNotificationTemplate = TASK_ASSIGNED_TEMPLATE; + + // "notificationText" is text to appear in wave start notification + notificationText = "['','Incoming Wave: ' + (str BLWK_currentWaveNumber)]"; + + // whether notificationText will be compiled and called or not. + // It must return an array compatible with the "arguments" parameter of BIS_fnc_showNotification + compileNotificationText = 1; + + // A missionNamespace variable that is available on the server and must evaluate to a number + // This will determine the likelihood (relative to other normal waves) that it is created on any given wave weightVariable = "BLWK_standardWaveWeight"; }; class paratrooperWave : standardWave { - onSelected = "remoteExec ['BLWK_fnc_handleParatrooperWave',BLWK_theAIHandlerOwnerID]"; + onSelected = "remoteExecCall ['BLWK_fnc_handleParatrooperWave',BLWK_theAIHandlerOwnerID]"; weightVariable = "BLWK_paratrooperWaveWeight"; }; class defectorWave : standardWave { - onSelected = "remoteExec ['BLWK_fnc_handleDefectorWave',BLWK_theAIHandlerOwnerID]"; + onSelected = "remoteExecCall ['BLWK_fnc_handleDefectorWave',BLWK_theAIHandlerOwnerID]"; weightVariable = "BLWK_defectorWaveWeight"; }; }; @@ -29,40 +60,43 @@ class BLWK_waveTypes { class suicideWave { - onSelected = "remoteExec ['BLWK_fnc_handleSuicideWave',BLWK_theAIHandlerOwnerID]"; + onSelected = "remoteExecCall ['BLWK_fnc_handleSuicideWave',BLWK_theAIHandlerOwnerID]"; creationNotificationTemplate = SPECIAL_WARNING_TEMPLATE; notificationText = "Enemy Suicide Bombers Are Incoming!"; - toggleVariable = "BLWK_allowSuicideWave"; // a name of a missionNamespace variable (on the server) that can be set to true or false to toggle the ability to have the wave (usually paired with the KISKA parameter menu) + // The "toggleVariable" is a name of a missionNamespace variable (on the server) + // that can be set to true or false to toggle the ability to have the wave + // (likely paired with a KISKA parameter menu mission param) + toggleVariable = "BLWK_allowSuicideWave"; }; class civilianWave : suicideWave { - onSelected = "remoteExec ['BLWK_fnc_handleStandardWave',BLWK_theAIHandlerOwnerID]; call BLWK_fnc_civiliansWave"; + onSelected = "remoteExecCall ['BLWK_fnc_handleStandardWave',BLWK_theAIHandlerOwnerID]; call BLWK_fnc_civiliansWave"; notificationText = "Civilians Are Fleeing, Watch Your Fire!"; onWaveEnd = "call BLWK_fnc_onCivWaveEnd"; toggleVariable = "BLWK_allowCivWave"; }; class droneWave : suicideWave { - onSelected = "remoteExec ['BLWK_fnc_handleDroneWave',BLWK_theAIHandlerOwnerID]"; + onSelected = "remoteExecCall ['BLWK_fnc_handleDroneWave',BLWK_theAIHandlerOwnerID]"; notificationText = "Enemy Drones Inbound!"; onWaveEnd = "call BLWK_fnc_onDroneWaveEnd"; toggleVariable = "BLWK_allowDroneWave"; }; class overrunWave : suicideWave { - onSelected = "remoteExec ['BLWK_fnc_handleOverrunWave',BLWK_theAIHandlerOwnerID]"; + onSelected = "remoteExecCall ['BLWK_fnc_handleOverrunWave',BLWK_theAIHandlerOwnerID]"; notificationText = "The Area Was Overrun!"; toggleVariable = "BLWK_allowOverrunWave"; }; class heliWave : suicideWave { - onSelected = "remoteExec ['BLWK_fnc_handleHelicopterWave',BLWK_theAIHandlerOwnerID]"; + onSelected = "remoteExecCall ['BLWK_fnc_handleHelicopterWave',BLWK_theAIHandlerOwnerID]"; notificationText = "Enemy Helicopters Inbound!"; toggleVariable = "BLWK_allowHeliWave"; }; class mortarWave : suicideWave { - onSelected = "remoteExec ['BLWK_fnc_handleMortarWave',BLWK_theAIHandlerOwnerID]"; + onSelected = "remoteExecCall ['BLWK_fnc_handleMortarWave',BLWK_theAIHandlerOwnerID]"; notificationText = "Incoming Mortar Fire!"; toggleVariable = "BLWK_allowMortarWave"; }; diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 6e520ffd..aa01c863 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -470,6 +470,18 @@ class BLWK {}; }; class StandardWaveLib + { + file = "Functions\Wave Type Libraries\Standard Wave Lib"; + class standardWave_generateManSpawnPosition + {}; + class standardWave_generateMenClassnames + {}; + class standardWave_onManCreated + {}; + class standardWave_onWaveSelected + {}; + }; + class StandardWaveLibrary { From 9a7b17e146a7785f99062a69d678e58083644edc Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 8 Jul 2023 21:23:05 -0600 Subject: [PATCH 019/133] (#642): WIP implementing refactor for wave spawns --- Functions/Queue/fn_spawnQueue_add.sqf | 2 +- Functions/Queue/fn_spawnQueue_create.sqf | 37 +++++ .../Queue/fn_spawnQueue_popAndCreate.sqf | 6 +- .../Common Wave Library/fn_wave_create.sqf | 142 ++++++------------ Functions/Waves/fn_startWave.sqf | 40 +---- .../Waves/fn_waves_getFunctionFromConfig.sqf | 74 +++++++++ Functions/Waves/fn_waves_onInitialized.sqf | 63 ++++++++ Headers/descriptionEXT/functions.hpp | 5 + 8 files changed, 232 insertions(+), 137 deletions(-) create mode 100644 Functions/Queue/fn_spawnQueue_create.sqf create mode 100644 Functions/Waves/fn_waves_getFunctionFromConfig.sqf create mode 100644 Functions/Waves/fn_waves_onInitialized.sqf diff --git a/Functions/Queue/fn_spawnQueue_add.sqf b/Functions/Queue/fn_spawnQueue_add.sqf index fccd4b9d..608ba289 100644 --- a/Functions/Queue/fn_spawnQueue_add.sqf +++ b/Functions/Queue/fn_spawnQueue_add.sqf @@ -2,7 +2,7 @@ Function: BLWK_fnc_queue_add Description: - Adds the given args to the enemy spawn queue + Adds the given args to the enemy spawn queue. Parameters: 0: _class : - The classname of the unit you want to add to the queue diff --git a/Functions/Queue/fn_spawnQueue_create.sqf b/Functions/Queue/fn_spawnQueue_create.sqf new file mode 100644 index 00000000..c4bc05eb --- /dev/null +++ b/Functions/Queue/fn_spawnQueue_create.sqf @@ -0,0 +1,37 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_spawnQueue_create + +Description: + Creates a unit for the wave based upon the args provided. + +Parameters: + 0: _class : - The classname of the unit you want to add to the queue + 1: _position : - The position to spawn the unit at + 2: _onManCreatedFunctionName : - The global var name for the function + to run once the unit is created on the AI handler owner machine. + +Returns: + NOTHING + +Examples: + (begin example) + [ + missionConfigFile >> "BLWK_waveTypes" >> "normalWaves" >> "standardWave" + ] call BLWK_fnc_spawnQueue_create; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_spawnQueue_create"; + +params [ + ["_class","",[""]], + ["_position",[],[objNull,[]]] + ["_onManCreatedFunctionName","BLWK_fnc_standardWave_onManCreated",[""]], +]; + + +// TODO: create man and add him to the mustkill array on the server + +nil diff --git a/Functions/Queue/fn_spawnQueue_popAndCreate.sqf b/Functions/Queue/fn_spawnQueue_popAndCreate.sqf index c3fa25c8..476e6662 100644 --- a/Functions/Queue/fn_spawnQueue_popAndCreate.sqf +++ b/Functions/Queue/fn_spawnQueue_popAndCreate.sqf @@ -21,8 +21,12 @@ Author(s): ---------------------------------------------------------------------------- */ scriptName "BLWK_fnc_spawnQueue_popAndCreate"; +if (!isServer) exitWith {}; + // check if queue is empty private _queue = localNamespace getVariable ["BLWK_spawnQueue",[]]; if (_queue isEqualTo []) exitWith {}; -(_queue deleteAt 0) params ["_type","_position","_onManCreatedFunctionName"]; +private _spawnArgs = _queue deleteAt 0; +_spawnArgs remoteExecCall ["BLWK_fnc_spawnQueue_create",BLWK_theAIHandlerOwnerID]; +// params ["_type","_position","_onManCreatedFunctionName"] \ No newline at end of file diff --git a/Functions/Wave Type Libraries/Common Wave Library/fn_wave_create.sqf b/Functions/Wave Type Libraries/Common Wave Library/fn_wave_create.sqf index 011f0c5e..ad13580f 100644 --- a/Functions/Wave Type Libraries/Common Wave Library/fn_wave_create.sqf +++ b/Functions/Wave Type Libraries/Common Wave Library/fn_wave_create.sqf @@ -1,4 +1,28 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_wave_create + +Description: + Takes the first entry in the enemy man spawn queue, removes the item and then + spawns the unit from the arguments. + +Parameters: + 0: _waveConfig - The config path of the wave to create + 1: _totalNumEnemiesToSpawnDuringWave - The total number of enemies to spawn during the wave. + If less than `1`, the number will be automatically calculated. + +Returns: + NOTHING + +Examples: + (begin example) + [ + missionConfigFile >> "BLWK_waveTypes" >> "normalWaves" >> "standardWave" + ] call BLWK_fnc_wave_create; + (end) +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ scriptName "BLWK_fnc_wave_create"; // if (clientOwner isNotEqualTo BLWK_theAIHandlerOwnerID) exitWith { @@ -16,8 +40,6 @@ scriptName "BLWK_fnc_wave_create"; // }; // #define DEFAULT_ON_WAVE_SELECTED_NAME "BLWK_fnc_standardWave_onWaveSelected" -#define DEFAULT_WAVE_CONFIG_PATH missionConfigFile >> "BLWK_waveTypes" >> "normalWaves" >> "standardWave" -#define SPECIAL_WAVE_CONFIG missionConfigFile >> "BLWK_waveTypes" >> "specialWaves" #define BASE_ENEMY_NUMBER 2 params [ @@ -25,68 +47,12 @@ params [ ["_totalNumEnemiesToSpawnDuringWave",-1,[123]] ]; -// private _onWaveSelectedFunction = missionNamespace getVariable [_onWaveSelectedFunctionName,{}]; -// if (_waveConfig isEqualTo configNull) exitWith { -// private _message = [ -// "Could not find onWaveSelected function with the name: ", -// _onWaveSelectedFunction, -// " on the server! Using standard Wave..." -// ] joinString ""; - -// [_message,10] remoteExecCall ["KISKA_fnc_errorNotification",0]; -// [_message,true] remoteExecCall ["KISKA_fnc_log",2]; - -// [DEFAULT_ON_WAVE_SELECTED_NAME] call BLWK_fnc_wave_create; -// }; - -private _notifyOfError = { - params ["_message"]; - - [_message] remoteExec ["BLWK_fnc_notifyAdminsOrHostOfError",0]; - [_message,true] call KISKA_fnc_log; -}; - -private _fn_getFunctionFromWaveConfig = { - params [ - "_configProperty", - ["_justName",false] - ]; - - private _requestedFunctionName = getText(_waveConfig >> _configProperty); - private _default_functionName = getText(DEFAULT_WAVE_CONFIG_PATH >> _configProperty); - if (_requestedFunctionName isEqualTo "") then { - _requestedFunctionName = _default_functionName - }; - - private _requestedFunction = missionNamespace getVariable [ - _requestedFunctionName, - {} - ]; - if (_requestedFunction isEqualTo {}) then { - private _message = [ - "Could not find function for property: ", - _configProperty, - " with the name: ", - _requestedFunctionName, - " on the server in config: ", - _waveConfig - ] joinString ""; - [_message] call _notifyOfError; - - _requestedFunction = missionNamespace getVariable _default_functionName; - }; - - - if (_justName) exitWith { _requestedFunctionName }; - _requestedFunction -}; - /* ---------------------------------------------------------------------------- Create Queue ---------------------------------------------------------------------------- */ -private _generatManClassesFunction = ["generateMenClassnames"] call _fn_getFunctionFromWaveConfig; -private _generateSpawnPositionFunction = ["generateManSpawnPosition"] call _fn_getFunctionFromWaveConfig; +private _generatManClassesFunction = ["generateMenClassnames"] call BLWK_fnc_waves_getFunctionFromConfig; +private _generateSpawnPositionFunction = ["generateManSpawnPosition"] call BLWK_fnc_waves_getFunctionFromConfig; if (_totalNumEnemiesToSpawnDuringWave < BASE_ENEMY_NUMBER) then { _totalNumEnemiesToSpawnDuringWave = BASE_ENEMY_NUMBER * ((BLWK_enemiesPerWaveMultiplier * BLWK_currentWaveNumber) + 1); @@ -100,7 +66,7 @@ if (!BLWK_multipleEnemyPositions) then { _spawnPosition_temp = selectRandom BLWK_infantrySpawnPositions; }; -private _onManCreatedFunctionName = ["generateManSpawnPosition",true] call _fn_getFunctionFromWaveConfig; +private _onManCreatedFunctionName = ["generateManSpawnPosition",true] call BLWK_fnc_waves_getFunctionFromConfig; for "_i" from 1 to _totalNumEnemiesToSpawnDuringWave do { if (BLWK_multipleEnemyPositions) then { _spawnPosition_temp = call _generateSpawnPositionFunction; @@ -111,51 +77,35 @@ for "_i" from 1 to _totalNumEnemiesToSpawnDuringWave do { _class, _spawnPosition_temp, _onManCreatedFunctionName - ] call BLWK_fnc_addToQueue; + ] call BLWK_fnc_spawnQueue_add; }; -/* ---------------------------------------------------------------------------- - Send wave start notification ----------------------------------------------------------------------------- */ -private _notification = []; -_notification pushBack (getText(_waveConfigPath >> "creationNotificationTemplate")); - -private _notificationText = getText(_waveConfigPath >> "notificationText"); -if ([_waveConfigPath >> "compileNotificationText"] call BIS_fnc_getCfgDataBool) then { - _notificationText = call compileFinal _notificationText; -} else { - _notificationText = [_notificationText]; +// TODO: spawn enemies +// spawn the enemies for wave start +private _numStartingEnemies = BLWK_maxEnemyInfantryAtOnce; +private _spawnQueueCount = count (missionNamespace getVariable [STANDARD_ENEMY_INFANTRY_QUEUE,[]]); +if (_spawnQueueCount < BLWK_maxEnemyInfantryAtOnce) then { + _numStartingEnemies = _spawnQueueCount; }; -_notification pushBack _notificationText; - - -private _players = call CBAP_fnc_players; -_notification remoteExec ["BIS_fnc_showNotification", _players]; -// play a sound for special waves -private _isSpecialWave = [_waveConfigPath,SPECIAL_WAVE_CONFIG] call CBAP_fnc_inheritsFrom; -if (_isSpecialWave) then { - ["Alarm"] remoteExec ["playSound", _players]; +private _unit = objNull; +private _units = []; +for "_i" from 1 to _numStartingEnemies do { + _unit = [STANDARD_ENEMY_INFANTRY_QUEUE,"_this call BLWK_fnc_stdEnemyManCreateCode"] call BLWK_fnc_createFromQueue; + _units pushBack _unit; }; -// TODO: -// need to create base enemy units -// server needs to know when all units are dead to end the wave -// server needs to know that wave has started (e.g. initial enemies have spawned) - - -// Wave types determine how to create enemies to a point -// Things the ai owner cares about: -// 1. where is the guy spawning -// 2. what type is he -// 3. what code should I run on his creation? - -// [] remoteExecCall ["BLWK_fnc_onWaveEnemiesSpawned",2]; +/* ---------------------------------------------------------------------------- + Activate Initialization +---------------------------------------------------------------------------- */ +localNamespace setVariable ["BLWK_currentWaveConfig",_waveConfig]; +[_waveConfig] spawn { + // TODO: wait for enemies spawned from ai handler owner +}; -localNamespace setVariable ["BLWK_currentWaveConfig",_waveConfigPath]; nil diff --git a/Functions/Waves/fn_startWave.sqf b/Functions/Waves/fn_startWave.sqf index dd75e7d0..6d038509 100644 --- a/Functions/Waves/fn_startWave.sqf +++ b/Functions/Waves/fn_startWave.sqf @@ -51,9 +51,7 @@ if (_clearDroppedItems) then { ---------------------------------------------------------------------------- */ private _previousWaveNum = missionNamespace getVariable ["BLWK_currentWaveNumber",0]; missionNamespace setVariable ["BLWK_currentWaveNumber", _previousWaveNum + 1,true]; - missionNamespace setVariable ["BLWK_inBetweenWaves",false,true]; -missionNamespace setVariable ["BLWK_initialWaveSpawnComplete",false]; /* ---------------------------------------------------------------------------- @@ -75,43 +73,7 @@ if (missionNamespace getVariable ["BLWK_extractionQueued",false]) then { }; -/* ---------------------------------------------------------------------------- - Clean Dead ----------------------------------------------------------------------------- */ call BLWK_fnc_cleanUpTheDead; -/* ---------------------------------------------------------------------------- - Make sure enemies have spawned ----------------------------------------------------------------------------- */ -// check to make sure there are actually units inside the wave array before looping -// or that all initial units are spawned -waitUntil { - if ( - missionNamespace getVariable ["BLWK_initialWaveSpawnComplete",false] OR - {(call BLWK_fnc_getMusKillList) isNotEqualTo []} - ) exitWith {true}; - sleep 1; - false -}; - - -// log wave -[["Start Wave: ",BLWK_currentWaveNumber],false] call KISKA_fnc_log; - -// invoke wave start event -[missionNamespace,"BLWK_onWaveStart"] remoteExecCall ["BIS_fnc_callScriptedEventHandler",0]; - - -/* ---------------------------------------------------------------------------- - Check for wave end ----------------------------------------------------------------------------- */ -waitUntil { - if (call BLWK_fnc_isWaveCleared) exitWith { - [] spawn BLWK_fnc_endWave; - true - }; - - sleep 3; - false -}; +nil diff --git a/Functions/Waves/fn_waves_getFunctionFromConfig.sqf b/Functions/Waves/fn_waves_getFunctionFromConfig.sqf new file mode 100644 index 00000000..2375eae2 --- /dev/null +++ b/Functions/Waves/fn_waves_getFunctionFromConfig.sqf @@ -0,0 +1,74 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_waves_getFunctionFromConfig + +Description: + Intellegently finds the code for a given config property in a wave config. + + Will fill in with the standard wave defaults and notify users of certain errors. + +Parameters: + 0: _waveConfig - The config path of the wave to get the property from + 1: _configProperty - The name of the code property to find in the config + 2: _justName - If true, only the string name of the function will be returned + +Returns: + - either returns the name of a function or the code associated with that name + +Examples: + (begin example) + private _code = [ + missionConfigFile >> "BLWK_waveTypes" >> "normalWaves" >> "standardWave", + "generateMenClassnames" + ] call BLWK_fnc_waves_getFunctionFromConfig; + (end) + + (begin example) + private _functionName = [ + missionConfigFile >> "BLWK_waveTypes" >> "normalWaves" >> "standardWave", + "generateMenClassnames", + true + ] call BLWK_fnc_waves_getFunctionFromConfig; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_waves_getFunctionFromConfig"; + +#define DEFAULT_WAVE_CONFIG_PATH missionConfigFile >> "BLWK_waveTypes" >> "normalWaves" >> "standardWave" + +params [ + ["_waveConfig",configNull,[configNull]], + ["_configProperty","",""], + ["_justName",false,[true]] +]; + +private _requestedFunctionName = getText(_waveConfig >> _configProperty); +private _default_functionName = getText(DEFAULT_WAVE_CONFIG_PATH >> _configProperty); +if (_requestedFunctionName isEqualTo "") then { + _requestedFunctionName = _default_functionName +}; + +private _requestedFunction = missionNamespace getVariable [ + _requestedFunctionName, + {} +]; +if (_requestedFunction isEqualTo {}) then { + private _message = [ + "Could not find function for property: ", + _configProperty, + " with the name: ", + _requestedFunctionName, + " on the server in config: ", + _waveConfig + ] joinString ""; + + [_message] remoteExec ["BLWK_fnc_notifyAdminsOrHostOfError",0]; + [_message,true] call KISKA_fnc_log; + + _requestedFunction = missionNamespace getVariable _default_functionName; +}; + + +if (_justName) exitWith { _requestedFunctionName }; +_requestedFunction diff --git a/Functions/Waves/fn_waves_onInitialized.sqf b/Functions/Waves/fn_waves_onInitialized.sqf new file mode 100644 index 00000000..f93db56f --- /dev/null +++ b/Functions/Waves/fn_waves_onInitialized.sqf @@ -0,0 +1,63 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_waves_onInitialized + +Description: + Activates some basic events after a wave has been fully initialized. + + Meaning that the initial group of units has been spawned. + +Parameters: + 0: _waveConfig - The config path of the wave that was created + +Returns: + NOTHING + +Examples: + (begin example) + [ + missionConfigFile >> "BLWK_waveTypes" >> "normalWaves" >> "standardWave" + ] call BLWK_fnc_waves_onInitialized; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_waves_onInitialized"; + +#define SPECIAL_WAVE_CONFIG missionConfigFile >> "BLWK_waveTypes" >> "specialWaves" + +if (!isServer) exitWith {}; + +params [ + ["_waveConfigPath",configNull,[configNull]] +]; + +private _notification = []; +_notification pushBack (getText(_waveConfigPath >> "creationNotificationTemplate")); + +private _notificationText = getText(_waveConfigPath >> "notificationText"); +if ([_waveConfigPath >> "compileNotificationText"] call BIS_fnc_getCfgDataBool) then { + _notificationText = call compileFinal _notificationText; +} else { + _notificationText = [_notificationText]; +}; +_notification pushBack _notificationText; + + +private _players = call CBAP_fnc_players; +_notification remoteExec ["BIS_fnc_showNotification", _players]; + +// play a sound for special waves +private _isSpecialWave = [_waveConfigPath,SPECIAL_WAVE_CONFIG] call CBAP_fnc_inheritsFrom; +if (_isSpecialWave) then { + ["Alarm"] remoteExec ["playSound", _players]; +}; + + + +[["Start Wave: ",BLWK_currentWaveNumber],false] call KISKA_fnc_log; + +[missionNamespace,"BLWK_onWaveStart"] remoteExecCall ["BIS_fnc_callScriptedEventHandler",0]; + + +nil diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index aa01c863..d1894021 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -530,6 +530,11 @@ class BLWK class Waves { file = "Functions\Waves"; + class waves_getFunctionFromConfig + {}; + class waves_onInitialized + {}; + class addToMustKillList {}; class cacheEnemyMenSpawnPositions From 196c69725b21c3e0aaf23d53be363be97131058e Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 00:06:04 -0600 Subject: [PATCH 020/133] (#642): renamed event functions for hit and killed enemies --- .../fn_event_hitEnemy.sqf} | 15 +++--- .../fn_event_killedEnemy.sqf} | 18 ++++--- .../fn_stdEnemyHitEvent.sqf | 53 ------------------- .../fn_stdEnemyHitEventLocal.sqf | 36 ------------- .../fn_stdEnemyKilledEvent.sqf | 48 ----------------- Headers/descriptionEXT/functions.hpp | 12 +++-- 6 files changed, 25 insertions(+), 157 deletions(-) rename Functions/{Wave Type Libraries/Standard Wave Library/fn_handleHitEventPlayer.sqf => Events/fn_event_hitEnemy.sqf} (81%) rename Functions/{Wave Type Libraries/Standard Wave Library/fn_handleKillEventPlayer.sqf => Events/fn_event_killedEnemy.sqf} (77%) delete mode 100644 Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyHitEvent.sqf delete mode 100644 Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyHitEventLocal.sqf delete mode 100644 Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyKilledEvent.sqf diff --git a/Functions/Wave Type Libraries/Standard Wave Library/fn_handleHitEventPlayer.sqf b/Functions/Events/fn_event_hitEnemy.sqf similarity index 81% rename from Functions/Wave Type Libraries/Standard Wave Library/fn_handleHitEventPlayer.sqf rename to Functions/Events/fn_event_hitEnemy.sqf index 3766c93b..23574336 100644 --- a/Functions/Wave Type Libraries/Standard Wave Library/fn_handleHitEventPlayer.sqf +++ b/Functions/Events/fn_event_hitEnemy.sqf @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- -Function: BLWK_fnc_stdEnemyHitEventPlayer +Function: BLWK_fnc_event_hitEnemy Description: Executes from an enemy's hit eventhandler. The message is sent from whomever @@ -7,8 +7,6 @@ Description: This is what will add the points to a player and create a hit marker. - Executed from the event added by "BLWK_fnc_stdEnemyHitEventLocal" - Parameters: 0: _hitUnit : - The unit hit 1: _damage : - The numerical damage done to a unit (for points/hit markers) @@ -19,16 +17,15 @@ Returns: Examples: (begin example) // from hit event - [_hitUnit,_damage] remoteExecCall ["BLWK_fnc_handleHitEventPlayer",_instigator]; + [_hitUnit,_damage] remoteExecCall ["BLWK_fnc_event_hitEnemy",_instigator]; (end) Author(s): Hilltop(Willtop) & omNomios, - Modified by: Ansible2 // Cipher + Modified by: Ansible2 ---------------------------------------------------------------------------- */ -#define SCRIPT_NAME "BLWK_fnc_handleHitEventPlayer" -scriptName SCRIPT_NAME; +scriptName "BLWK_fnc_event_hitEnemy"; if !(hasInterface) exitWith {}; @@ -52,4 +49,6 @@ if (missionNamespace getVariable ["BLWK_isAircraftGunner",false]) then { private _points = round (BLWK_pointsForHit + _damagePoints); [_points] call BLWK_fnc_addPoints; [_hitUnit,_points] call BLWK_fnc_createHitMarker; -}; \ No newline at end of file +}; + +nil diff --git a/Functions/Wave Type Libraries/Standard Wave Library/fn_handleKillEventPlayer.sqf b/Functions/Events/fn_event_killedEnemy.sqf similarity index 77% rename from Functions/Wave Type Libraries/Standard Wave Library/fn_handleKillEventPlayer.sqf rename to Functions/Events/fn_event_killedEnemy.sqf index 9c055ebb..45a22e00 100644 --- a/Functions/Wave Type Libraries/Standard Wave Library/fn_handleKillEventPlayer.sqf +++ b/Functions/Events/fn_event_killedEnemy.sqf @@ -7,8 +7,6 @@ Description: This is what will add the points to a player and create a hit marker. - Executed from the event added by "BLWK_fnc_stdEnemyKilledEvent" - Parameters: 0: _killedUnit : - The unit killed 1: _isVehicle : - True if anything other then a man unit (tank,car,etc.) @@ -19,15 +17,14 @@ Returns: Examples: (begin example) // from hit event - [_killedUnit] remoteExecCall ["BLWK_fnc_handleKillEventPlayer",_instigator]; - + [_killedUnit] remoteExecCall ["BLWK_fnc_event_killedEnemy",_instigator]; (end) Author(s): Hilltop(Willtop) & omNomios, - Modified by: Ansible2 // Cipher + Modified by: Ansible2 ---------------------------------------------------------------------------- */ -scriptName "BLWK_fnc_handleKillEventPlayer"; +scriptName "BLWK_fnc_event_killedEnemy"; if !(hasInterface) exitWith {}; @@ -44,10 +41,15 @@ if (isNull _killedUnit) exitWith { private _points = [_killedUnit] call BLWK_fnc_getPointsForKill; // aircraft gunners get limited points -if (missionNamespace getVariable ["BLWK_isAircraftGunner",false] AND {!_isVehicle}) then { - +if ( + (missionNamespace getVariable ["BLWK_isAircraftGunner",false]) AND + (!_isVehicle) +) then { _points = round (_points / 4); }; [_points] call BLWK_fnc_addPoints; [_killedUnit,_points,true] call BLWK_fnc_createHitMarker; + + +nil diff --git a/Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyHitEvent.sqf b/Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyHitEvent.sqf deleted file mode 100644 index d7795df0..00000000 --- a/Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyHitEvent.sqf +++ /dev/null @@ -1,53 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_stdEnemyHitEvent - -Description: - Executes the code in the standard enemy's hit event for adding points to player. - - Parameters are that of the normal HIT eventhandler. - - Executed from the event added by "BLWK_fnc_addStdEnemyManEHs" - -Parameters: - 0: _unit : - Object the event handler is assigned to - 1: _source : - Object that caused the damage – contains unit in case of collisions (not used) - 2: _damage : - Level of damage caused by the hit - 3: _instigator : - Person who pulled the trigger - -Returns: - NOTHING - -Examples: - (begin example) - - _this call BLWK_fnc_stdEnemyHitEvent; - - (end) - -Author(s): - Hilltop(Willtop) & omNomios, - Modified by: Ansible2 // Cipher ----------------------------------------------------------------------------- */ -if !(hasInterface) exitWith {}; - -private _instigator = _this select 3; - -if (_instigator isEqualTo player) then { - private _unit = _this select 0; - - // aircraft gunners get limited points - if (missionNamespace getVariable ["BLWK_isAircraftGunner",false]) then { - [1] call BLWK_fnc_addPoints; - [_unit,1] call BLWK_fnc_createHitMarker; - } else { - // multiply by damage - private _damagePoints = BLWK_pointsMultiForDamage * (_this select 2); - if (_damagePoints > BLWK_maxPointsForDamage) then { - _damagePoints = BLWK_maxPointsForDamage; - }; - - private _points = round (BLWK_pointsForHit + _damagePoints); - [_points] call BLWK_fnc_addPoints; - [_unit,_points] call BLWK_fnc_createHitMarker; - }; -}; \ No newline at end of file diff --git a/Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyHitEventLocal.sqf b/Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyHitEventLocal.sqf deleted file mode 100644 index 426034b7..00000000 --- a/Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyHitEventLocal.sqf +++ /dev/null @@ -1,36 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_stdEnemyHitEventLocal - -Description: - Executes the code in the standard enemy's hit event for adding points to player. - - Parameters are that of the normal HIT eventhandler. - - Executed from the event added by "BLWK_fnc_addStdEnemyManEHs" - -Parameters: - 0: _unit : - Object the event handler is assigned to - 1: _source : - Object that caused the damage – contains unit in case of collisions (not used) - 2: _damage : - Level of damage caused by the hit - 3: _instigator : - Person who pulled the trigger - -Returns: - NOTHING - -Examples: - (begin example) - - _this call BLWK_fnc_stdEnemyHitEventLocal; - - (end) - -Author(s): - Hilltop(Willtop) & omNomios, - Modified by: Ansible2 // Cipher ----------------------------------------------------------------------------- */ -params ["_hitUnit", "_source", "_damage", "_instigator"]; - -if (!(isNull _instigator) AND {isPlayer _instigator}) then { - // show a player hit points and add them to there score - [_hitUnit,_damage] remoteExecCall ["BLWK_fnc_handleHitEventPlayer",_instigator]; -}; \ No newline at end of file diff --git a/Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyKilledEvent.sqf b/Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyKilledEvent.sqf deleted file mode 100644 index 5159bac2..00000000 --- a/Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyKilledEvent.sqf +++ /dev/null @@ -1,48 +0,0 @@ -#include "..\..\..\Headers\String Constants.hpp" -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_stdEnemyKilledEvent - -Description: - Executes the code in the standard enemy man killed event - for adding points to players and markers. - - Executed from the event added by "BLWK_fnc_addStdEnemyManEHs" - -Parameters: - 0: _killedUnit : - Object the event handler is assigned to - 1: _killer : - Object that killed _killedUnit – contains unit itself in case of collisions (not used) - 2: _instigator : - Person who pulled the trigger - 3: _useEffects : - same as useEffects in setDamage alt syntax (not used) - - -Returns: - NOTHING - -Examples: - (begin example) - - _this call BLWK_fnc_stdEnemyKilledEvent; - - (end) - -Author(s): - Hilltop(Willtop) & omNomios, - Modified by: Ansible2 // Cipher ----------------------------------------------------------------------------- */ -params ["_killedUnit", "_killer", "_instigator", "_useEffects"]; - -if (!(isNull _instigator) AND {isPlayer _instigator}) then { - // show a player hit points and add them to there score - [_killedUnit] remoteExecCall ["BLWK_fnc_handleKillEventPlayer",_instigator]; -}; - -// spawn the next in queue -if (clientOwner isEqualTo BLWK_theAIHandlerOwnerID) then { - // if the spawn queue is not empty - if !((missionNamespace getVariable [STANDARD_ENEMY_INFANTRY_QUEUE,[]]) isEqualTo []) then { - [STANDARD_ENEMY_INFANTRY_QUEUE,"_this call BLWK_fnc_stdEnemyManCreateCode"] call BLWK_fnc_createFromQueue; - }; -}; - - -[[_killedUnit]] remoteExecCall ["removeFromRemainsCollector",2]; diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index d1894021..4ce88878 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -482,6 +482,14 @@ class BLWK {}; }; + class Events + { + file = "Functions\Wave Type Libraries\Events"; + class event_killedEnemy + {}; + class event_hitEnemy + {}; + }; class StandardWaveLibrary { @@ -492,10 +500,6 @@ class BLWK {}; class handleDefectorWave {}; - class handleKillEventPlayer - {}; - class handleHitEventPlayer - {}; class handleStandardWave {}; class stdEnemyHitEvent From 1ca346787aab9170a204221d11eafcd4137ff5c4 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 00:18:00 -0600 Subject: [PATCH 021/133] (#642): removed a number of functions --- .../fn_addStdEnemyManEHs.sqf | 44 -------------- .../fn_stdEnemyManCreateCode.sqf | 60 ------------------- Headers/descriptionEXT/functions.hpp | 10 ---- 3 files changed, 114 deletions(-) delete mode 100644 Functions/Wave Type Libraries/Standard Wave Library/fn_addStdEnemyManEHs.sqf delete mode 100644 Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyManCreateCode.sqf diff --git a/Functions/Wave Type Libraries/Standard Wave Library/fn_addStdEnemyManEHs.sqf b/Functions/Wave Type Libraries/Standard Wave Library/fn_addStdEnemyManEHs.sqf deleted file mode 100644 index 51eb202a..00000000 --- a/Functions/Wave Type Libraries/Standard Wave Library/fn_addStdEnemyManEHs.sqf +++ /dev/null @@ -1,44 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_addStdEnemyManEHs - -Description: - Executes the addEventhandler to all machines for a standard units events. - - Executed from "BLWK_fnc_stdEnemyManCreateCode" - -Parameters: - 0: _unit : - The unit to add the events to - -Returns: - NOTHING - -Examples: - (begin example) - - [aUnit] call BLWK_fnc_addStdEnemyManEHs; - - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -#define SCRIPT_NAME "BLWK_fnc_addStdEnemyManEHs" -scriptName SCRIPT_NAME; - -params ["_unit"]; - -if !(local _unit) exitWith { - [["Tried to add events to ",_unit," but they are not local. Exiting..."],true] call KISKA_fnc_log; - false -}; - -_unit addEventHandler ["Hit",{ - _this call BLWK_fnc_stdEnemyHitEventLocal; -}]; - -_unit addEventHandler ["Killed",{ - _this call BLWK_fnc_stdEnemyKilledEvent; -}]; - - -true \ No newline at end of file diff --git a/Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyManCreateCode.sqf b/Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyManCreateCode.sqf deleted file mode 100644 index 5399ea9b..00000000 --- a/Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyManCreateCode.sqf +++ /dev/null @@ -1,60 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_stdEnemyManCreateCode - -Description: - The code to run on units created for the standard library. - -Parameters: - 0: _unit : - The actual unit - 1: _queueName : - The name of the queue the unit belongs to (used for spawning a new unit in queue) - 2: _group : - The group the unit belongs to (OPTIONAL) - -Returns: - NOTHING - -Examples: - (begin example) - [aUnit,"myQueue",group aUnit] call BLWK_fnc_stdEnemyManCreateCode; - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -params ["_unit","_queueName","_group"]; - -// hit and killed events -[_unit] call BLWK_fnc_addStdEnemyManEHs; - -[_unit] call BLWK_fnc_setSkill; - -if (isNil "_group") then { - _group = group _unit -}; - -[_group] spawn BLWK_fnc_pathing_mainLoop; - -[_unit] spawn BLWK_fnc_pathing_collisionLoop; - -[_group] spawn BLWK_fnc_startStalkingPlayers; - - -// add to server's list of units that must be dead before the round can end -[_unit] remoteExecCall ["BLWK_fnc_addToMustKillList",2]; -[BLWK_zeus, [[_unit],false]] remoteExecCall ["addCuratorEditableObjects",2]; - - -// keep items (maps, nvgs, binoculars, etc.) so that they can just be loot drops -removeAllAssignedItems _unit; - -// for pistol only waves and randomized weapons -[_unit] call BLWK_fnc_handleEnemyWeapons; - -if !(BLWK_autocombatEnabled) then { - _unit disableAI "AUTOCOMBAT"; -}; -if !(BLWK_suppressionEnabled) then { - _unit disableAI "SUPPRESSION"; -}; -if !(BLWK_doDetectMines) then { - _unit disableAI "MINEDETECTION"; -}; \ No newline at end of file diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 4ce88878..8cbf3d2a 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -494,22 +494,12 @@ class BLWK class StandardWaveLibrary { file = "Functions\Wave Type Libraries\Standard Wave Library"; - class addStdEnemyManEHs - {}; class createStdWaveInfantry {}; class handleDefectorWave {}; class handleStandardWave {}; - class stdEnemyHitEvent - {}; - class stdEnemyHitEventLocal - {}; - class stdEnemyKilledEvent - {}; - class stdEnemyManCreateCode - {}; class stdEnemyVehicles {}; class stdVehicleKilledEvent From 3bf5d6e30961d08da5526ba3da834f238ef6519c Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 00:55:09 -0600 Subject: [PATCH 022/133] (#642): updated spawn queue functions --- Functions/Queue/fn_createFromQueue.sqf | 62 ----------------------- Functions/Queue/fn_spawnQueue_add.sqf | 6 +-- Functions/Queue/fn_spawnQueue_create.sqf | 64 ++++++++++++++++++++++-- Headers/descriptionEXT/functions.hpp | 4 +- 4 files changed, 65 insertions(+), 71 deletions(-) delete mode 100644 Functions/Queue/fn_createFromQueue.sqf diff --git a/Functions/Queue/fn_createFromQueue.sqf b/Functions/Queue/fn_createFromQueue.sqf deleted file mode 100644 index b7adcd1e..00000000 --- a/Functions/Queue/fn_createFromQueue.sqf +++ /dev/null @@ -1,62 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_createFromQueue - -Description: - Spawns the first available unit in the specified queue - -Parameters: - 0: _queueName : - The name of the queue from which to spawn - 1: _codeToRun : - What code should run when the unit is created (passed args are [_unit,_queueName,_group]) - 2: _side : - The side the unit will be on - 3: _group : - The group the unit can be in; if empty, a new one is made - -Returns: - OBJECT - The created unit - -Examples: - (begin example) - - ["BLWK_standardInfantryQueue","",OPFOR] call BLWK_fnc_createFromQueue; - - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -params [ - ["_queueName","",[""]], - ["_codeToRun","",[""]], - ["_side",OPFOR], - ["_group",grpNull,[grpNull]] -]; - -if (_queueName isEqualTo "") exitWith { - ["_queueName is empty string ''",true] call KISKA_fnc_log; - objNull -}; - -// check if queue is empty -private _queueArray = missionNamespace getVariable [_queueName,[]]; -if (_queueArray isEqualTo []) exitWith {objNull}; - - -// get the first available unit in the queue -(_queueArray deleteAt 0) params ["_type","_position"]; -missionNamespace setVariable [_queueName,_queueArray]; - - -// create unit -if (isNull _group) then { - _group = createGroup _side; -}; -private _unit = _group createUnit [_type, _position, [], 0, "NONE"]; -[_unit] joinSilent _group; -_group deleteGroupWhenEmpty true; - -// run code on the unit -if !(_codeToRun isEqualTo "") then { - [_unit,_queueName,_group] call (compile _codeToRun); -}; - - -_unit \ No newline at end of file diff --git a/Functions/Queue/fn_spawnQueue_add.sqf b/Functions/Queue/fn_spawnQueue_add.sqf index 608ba289..094e03fc 100644 --- a/Functions/Queue/fn_spawnQueue_add.sqf +++ b/Functions/Queue/fn_spawnQueue_add.sqf @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- -Function: BLWK_fnc_queue_add +Function: BLWK_fnc_spawnQueue_add Description: Adds the given args to the enemy spawn queue. @@ -19,13 +19,13 @@ Examples: "I_Soldier_A_F", [0,0,0], "BLWK_fnc_standardWave_onManCreated" - ] call BLWK_fnc_queue_add; + ] call BLWK_fnc_spawnQueue_add; (end) Author(s): Ansible2 ---------------------------------------------------------------------------- */ -scriptName "BLWK_fnc_queue_add"; +scriptName "BLWK_fnc_spawnQueue_add"; params [ ["_class","",[""]], diff --git a/Functions/Queue/fn_spawnQueue_create.sqf b/Functions/Queue/fn_spawnQueue_create.sqf index c4bc05eb..6b63f4bb 100644 --- a/Functions/Queue/fn_spawnQueue_create.sqf +++ b/Functions/Queue/fn_spawnQueue_create.sqf @@ -16,7 +16,9 @@ Returns: Examples: (begin example) [ - missionConfigFile >> "BLWK_waveTypes" >> "normalWaves" >> "standardWave" + "I_Soldier_A_F", + [0,0,0], + "BLWK_fnc_standardWave_onManCreated" ] call BLWK_fnc_spawnQueue_create; (end) @@ -27,11 +29,65 @@ scriptName "BLWK_fnc_spawnQueue_create"; params [ ["_class","",[""]], - ["_position",[],[objNull,[]]] - ["_onManCreatedFunctionName","BLWK_fnc_standardWave_onManCreated",[""]], + ["_position",[],[objNull,[]]], + ["_onManCreatedFunctionName","BLWK_fnc_standardWave_onManCreated",[""]] ]; - +private _group = createGroup OPFOR; +private _unit = _group createUnit [_class, _position, [], 0, "NONE"]; +// even creating a unit for the group with createUnit does not always have them +// in that group +[_unit] joinSilent _group; +_group deleteGroupWhenEmpty true; // TODO: create man and add him to the mustkill array on the server +[_unit] call BLWK_fnc_setSkill; + +// keep items (maps, nvgs, binoculars, etc.) so that they can just be loot drops +removeAllAssignedItems _unit; + +// for pistol only waves and randomized weapons +[_unit] call BLWK_fnc_handleEnemyWeapons; + +if !(BLWK_autocombatEnabled) then { + _unit disableAI "AUTOCOMBAT"; +}; +if !(BLWK_suppressionEnabled) then { + _unit disableAI "SUPPRESSION"; +}; +if !(BLWK_doDetectMines) then { + _unit disableAI "MINEDETECTION"; +}; + + +/* ---------------------------------------------------------------------------- + Eventhandlers +---------------------------------------------------------------------------- */ +_unit addEventHandler ["Hit", { + params ["_unit", "", "_damage", "_instigator"]; + [_unit,_damage] remoteExec ["BLWK_fnc_event_hitEnemy",_instigator]; +}]; + +_unit addEventHandler ["Killed", { + params ["_killedUnit", "", "_instigator"]; + if (!(isNull _instigator) AND (isPlayer _instigator)) then { + // show a player hit points and add them to there score + [_killedUnit] remoteExec ["BLWK_fnc_event_killedEnemy",_instigator]; + }; + + [] remoteExecCall ["BLWK_fnc_spawnQueue_popAndCreate",2]; +}]; + +_unit addEventHandler ["Deleted", { + [] remoteExecCall ["BLWK_fnc_spawnQueue_popAndCreate",2]; +}]; + + +/* ---------------------------------------------------------------------------- + Update server +---------------------------------------------------------------------------- */ +[_unit] remoteExecCall ["BLWK_fnc_addToMustKillList",2]; +[BLWK_zeus, [[_unit],false]] remoteExecCall ["addCuratorEditableObjects",2]; + + nil diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 8cbf3d2a..8b55df52 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -297,10 +297,10 @@ class BLWK class Queue { file = "Functions\Queue"; - class createFromQueue - {}; class spawnQueue_add {}; + class spawnQueue_create + {}; class spawnQueue_popAndCreate {}; }; From fabfe1dfaeb6ba2bd8ac12150f56cbbc01facb94 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 00:55:51 -0600 Subject: [PATCH 023/133] (#642): added standardWave_onManCreated --- .../fn_standardWave_onManCreated.sqf | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onManCreated.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onManCreated.sqf index e69de29b..4df8af82 100644 --- a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onManCreated.sqf +++ b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onManCreated.sqf @@ -0,0 +1,33 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_standardWave_onManCreated + +Description: + Inits code specific to when a unit is created for the common standard wave. + +Parameters: + 0: _unit : - The created Man unit + +Returns: + NOTHING + +Examples: + (begin example) + [_unit] call BLWK_fnc_standardWave_onManCreated; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_standardWave_onManCreated"; + +params [ + ["_unit",objNull,[objNull]] +]; + +private _group = group _unit; +[_group] spawn BLWK_fnc_pathing_mainLoop; +[_unit] spawn BLWK_fnc_pathing_collisionLoop; +[_group] spawn BLWK_fnc_startStalkingPlayers; + + +nil From 057d8af1375315ee985ffb5ff5f69426c9e0b831 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 01:06:35 -0600 Subject: [PATCH 024/133] (#642): moved wave create function --- .../fn_wave_create.sqf => Waves/fn_waves_create.sqf} | 9 +++++---- Headers/descriptionEXT/functions.hpp | 8 ++------ 2 files changed, 7 insertions(+), 10 deletions(-) rename Functions/{Wave Type Libraries/Common Wave Library/fn_wave_create.sqf => Waves/fn_waves_create.sqf} (99%) diff --git a/Functions/Wave Type Libraries/Common Wave Library/fn_wave_create.sqf b/Functions/Waves/fn_waves_create.sqf similarity index 99% rename from Functions/Wave Type Libraries/Common Wave Library/fn_wave_create.sqf rename to Functions/Waves/fn_waves_create.sqf index ad13580f..82ae08ec 100644 --- a/Functions/Wave Type Libraries/Common Wave Library/fn_wave_create.sqf +++ b/Functions/Waves/fn_waves_create.sqf @@ -51,22 +51,23 @@ params [ /* ---------------------------------------------------------------------------- Create Queue ---------------------------------------------------------------------------- */ -private _generatManClassesFunction = ["generateMenClassnames"] call BLWK_fnc_waves_getFunctionFromConfig; -private _generateSpawnPositionFunction = ["generateManSpawnPosition"] call BLWK_fnc_waves_getFunctionFromConfig; - if (_totalNumEnemiesToSpawnDuringWave < BASE_ENEMY_NUMBER) then { _totalNumEnemiesToSpawnDuringWave = BASE_ENEMY_NUMBER * ((BLWK_enemiesPerWaveMultiplier * BLWK_currentWaveNumber) + 1); _totalNumEnemiesToSpawnDuringWave = _totalNumEnemiesToSpawnDuringWave + (BLWK_enemiesPerPlayerMultiplier * (count (call CBAP_fnc_players))); _totalNumEnemiesToSpawnDuringWave = round _totalNumEnemiesToSpawnDuringWave; }; -private _availableClassnames = call _generatManClassesFunction; + private "_spawnPosition_temp"; if (!BLWK_multipleEnemyPositions) then { _spawnPosition_temp = selectRandom BLWK_infantrySpawnPositions; }; +private _generatManClassesFunction = ["generateMenClassnames"] call BLWK_fnc_waves_getFunctionFromConfig; +private _availableClassnames = call _generatManClassesFunction; +private _generateSpawnPositionFunction = ["generateManSpawnPosition"] call BLWK_fnc_waves_getFunctionFromConfig; private _onManCreatedFunctionName = ["generateManSpawnPosition",true] call BLWK_fnc_waves_getFunctionFromConfig; + for "_i" from 1 to _totalNumEnemiesToSpawnDuringWave do { if (BLWK_multipleEnemyPositions) then { _spawnPosition_temp = call _generateSpawnPositionFunction; diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 8b55df52..691f0d64 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -463,12 +463,6 @@ class BLWK class handleParatrooperWave {}; }; - class CommonWaveLib - { - file = "Functions\Wave Type Libraries\Common Wave Library"; - class wave_create - {}; - }; class StandardWaveLib { file = "Functions\Wave Type Libraries\Standard Wave Lib"; @@ -528,6 +522,8 @@ class BLWK {}; class waves_onInitialized {}; + class waves_create + {}; class addToMustKillList {}; From 74424ce305e5f3e824815f71134849f0ce7fe961 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 01:06:53 -0600 Subject: [PATCH 025/133] (#642): added spawnQueue_get function --- Functions/Queue/fn_spawnQueue_get.sqf | 30 +++++++++++++++++++++++++++ Headers/descriptionEXT/functions.hpp | 2 ++ 2 files changed, 32 insertions(+) create mode 100644 Functions/Queue/fn_spawnQueue_get.sqf diff --git a/Functions/Queue/fn_spawnQueue_get.sqf b/Functions/Queue/fn_spawnQueue_get.sqf new file mode 100644 index 00000000..3d6798dc --- /dev/null +++ b/Functions/Queue/fn_spawnQueue_get.sqf @@ -0,0 +1,30 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_spawnQueue_get + +Description: + Returns the currently queued list of entries to spawn; + +Parameters: + NONE + +Returns: + - the queue of spawn arguments + +Examples: + (begin example) + private _queue = call BLWK_fnc_spawnQueue_get; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_spawnQueue_get"; + +private _queue = localNamespace getVariable ["BLWK_spawnQueue",-1]; +if (_queue isEqualTo -1) then { + _queue = []; + localNamespace setVariable ["BLWK_spawnQueue",_queue]; +}; + + +_queue diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 691f0d64..94620a55 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -299,6 +299,8 @@ class BLWK file = "Functions\Queue"; class spawnQueue_add {}; + class spawnQueue_get + {}; class spawnQueue_create {}; class spawnQueue_popAndCreate From 96ca5eae90e5feed0e3c1607992befa5504e5a5d Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 01:07:48 -0600 Subject: [PATCH 026/133] (#642): used BLWK_fnc_spawnQueue_get in add function --- Functions/Queue/fn_spawnQueue_add.sqf | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Functions/Queue/fn_spawnQueue_add.sqf b/Functions/Queue/fn_spawnQueue_add.sqf index 094e03fc..692b9205 100644 --- a/Functions/Queue/fn_spawnQueue_add.sqf +++ b/Functions/Queue/fn_spawnQueue_add.sqf @@ -33,11 +33,8 @@ params [ ["_onManCreatedFunctionName","BLWK_fnc_standardWave_onManCreated",[""]], ]; -if (isNil {localNamespace getVariable "BLWK_spawnQueue"}) then { - localNamespace setVariable ["BLWK_spawnQueue",[]]; -}; -private _queue = localNamespace getVariable "BLWK_spawnQueue"; +private _queue = call BLWK_fnc_spawnQueue_get; _queue pushBack _this; From 0a9c46c265f5bc1f918a7827dcffbc7f48f97752 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 01:15:18 -0600 Subject: [PATCH 027/133] (#000): removed old todo --- Functions/Music Manager/fn_openMusicManager.sqf | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Functions/Music Manager/fn_openMusicManager.sqf b/Functions/Music Manager/fn_openMusicManager.sqf index 166c44bd..323b57d9 100644 --- a/Functions/Music Manager/fn_openMusicManager.sqf +++ b/Functions/Music Manager/fn_openMusicManager.sqf @@ -25,5 +25,4 @@ if !(call KISKA_fnc_isAdminOrHost) exitWith { ["Only admins and hosts can open the manager"] call KISKA_fnc_errorNotification; }; -// TODO: remove force on top -createDialog ["musicManagerDialog",true]; +createDialog "musicManagerDialog"; From 8a1f30affc7e1bc74588784f863042ae30dba6b3 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 01:29:49 -0600 Subject: [PATCH 028/133] (#642): added and removed todos --- Functions/Queue/fn_spawnQueue_create.sqf | 2 -- Functions/Queue/fn_spawnQueue_popAndCreate.sqf | 9 +++++++-- Functions/Waves/fn_waves_create.sqf | 18 ++++++++---------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/Functions/Queue/fn_spawnQueue_create.sqf b/Functions/Queue/fn_spawnQueue_create.sqf index 6b63f4bb..4b4f4e74 100644 --- a/Functions/Queue/fn_spawnQueue_create.sqf +++ b/Functions/Queue/fn_spawnQueue_create.sqf @@ -39,13 +39,11 @@ private _unit = _group createUnit [_class, _position, [], 0, "NONE"]; // in that group [_unit] joinSilent _group; _group deleteGroupWhenEmpty true; -// TODO: create man and add him to the mustkill array on the server [_unit] call BLWK_fnc_setSkill; // keep items (maps, nvgs, binoculars, etc.) so that they can just be loot drops removeAllAssignedItems _unit; - // for pistol only waves and randomized weapons [_unit] call BLWK_fnc_handleEnemyWeapons; diff --git a/Functions/Queue/fn_spawnQueue_popAndCreate.sqf b/Functions/Queue/fn_spawnQueue_popAndCreate.sqf index 476e6662..f765128c 100644 --- a/Functions/Queue/fn_spawnQueue_popAndCreate.sqf +++ b/Functions/Queue/fn_spawnQueue_popAndCreate.sqf @@ -25,8 +25,13 @@ if (!isServer) exitWith {}; // check if queue is empty private _queue = localNamespace getVariable ["BLWK_spawnQueue",[]]; -if (_queue isEqualTo []) exitWith {}; +if (_queue isEqualTo []) exitWith { + // TODO: end wave +}; private _spawnArgs = _queue deleteAt 0; _spawnArgs remoteExecCall ["BLWK_fnc_spawnQueue_create",BLWK_theAIHandlerOwnerID]; -// params ["_type","_position","_onManCreatedFunctionName"] \ No newline at end of file + + + +nil diff --git a/Functions/Waves/fn_waves_create.sqf b/Functions/Waves/fn_waves_create.sqf index 82ae08ec..6085b991 100644 --- a/Functions/Waves/fn_waves_create.sqf +++ b/Functions/Waves/fn_waves_create.sqf @@ -83,19 +83,16 @@ for "_i" from 1 to _totalNumEnemiesToSpawnDuringWave do { -// TODO: spawn enemies - // spawn the enemies for wave start -private _numStartingEnemies = BLWK_maxEnemyInfantryAtOnce; -private _spawnQueueCount = count (missionNamespace getVariable [STANDARD_ENEMY_INFANTRY_QUEUE,[]]); -if (_spawnQueueCount < BLWK_maxEnemyInfantryAtOnce) then { - _numStartingEnemies = _spawnQueueCount; +private _numberOfStartingEnemies = BLWK_maxEnemyInfantryAtOnce; +private _numberOfUnitsInQueue = count (call BLWK_fnc_spawnQueue_get); +if (_numberOfUnitsInQueue < BLWK_maxEnemyInfantryAtOnce) then { + _numberOfStartingEnemies = _numberOfUnitsInQueue; }; private _unit = objNull; private _units = []; -for "_i" from 1 to _numStartingEnemies do { - _unit = [STANDARD_ENEMY_INFANTRY_QUEUE,"_this call BLWK_fnc_stdEnemyManCreateCode"] call BLWK_fnc_createFromQueue; - _units pushBack _unit; +for "_i" from 1 to _numberOfStartingEnemies do { + call BLWK_fnc_spawnQueue_popAndCreate; }; @@ -104,7 +101,8 @@ for "_i" from 1 to _numStartingEnemies do { ---------------------------------------------------------------------------- */ localNamespace setVariable ["BLWK_currentWaveConfig",_waveConfig]; [_waveConfig] spawn { - // TODO: wait for enemies spawned from ai handler owner + // TODO: wait for inital enemies spawned from ai handler owner + // use onInitalized function }; From 10c895a04255066100edffba1c25421667979345 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 15:50:11 -0600 Subject: [PATCH 029/133] (#642): WIP setting up on init for wave --- .../fn_standardWave_onWaveInit.sqf | 21 +++++++++++ .../fn_standardWave_onWaveSelected.sqf | 0 Functions/Waves/fn_waves_create.sqf | 37 +++++++++---------- .../Waves/fn_waves_getFunctionFromConfig.sqf | 21 +++++++++-- Functions/Waves/fn_waves_onInitialized.sqf | 11 +++++- Headers/descriptionEXT/Wave Types.hpp | 12 +----- 6 files changed, 67 insertions(+), 35 deletions(-) create mode 100644 Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveInit.sqf delete mode 100644 Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveSelected.sqf diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveInit.sqf new file mode 100644 index 00000000..7a1cadd1 --- /dev/null +++ b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveInit.sqf @@ -0,0 +1,21 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_standardWave_onWaveInit + +Description: + The on wave init for standard waves. + +Parameters: + NONE + +Returns: + NOTHING + +Examples: + (begin example) + call BLWK_fnc_standardWave_onWaveInit; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +[_startingWaveUnits] call BLWK_fnc_stdEnemyVehicles; \ No newline at end of file diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveSelected.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveSelected.sqf deleted file mode 100644 index e69de29b..00000000 diff --git a/Functions/Waves/fn_waves_create.sqf b/Functions/Waves/fn_waves_create.sqf index 6085b991..7bbe1761 100644 --- a/Functions/Waves/fn_waves_create.sqf +++ b/Functions/Waves/fn_waves_create.sqf @@ -63,10 +63,10 @@ if (!BLWK_multipleEnemyPositions) then { _spawnPosition_temp = selectRandom BLWK_infantrySpawnPositions; }; -private _generatManClassesFunction = ["generateMenClassnames"] call BLWK_fnc_waves_getFunctionFromConfig; +private _generatManClassesFunction = [_waveConfig,"generateMenClassnames"] call BLWK_fnc_waves_getFunctionFromConfig; private _availableClassnames = call _generatManClassesFunction; -private _generateSpawnPositionFunction = ["generateManSpawnPosition"] call BLWK_fnc_waves_getFunctionFromConfig; -private _onManCreatedFunctionName = ["generateManSpawnPosition",true] call BLWK_fnc_waves_getFunctionFromConfig; +private _generateSpawnPositionFunction = [_waveConfig,"generateManSpawnPosition"] call BLWK_fnc_waves_getFunctionFromConfig; +private _onManCreatedFunctionName = [_waveConfig,"generateManSpawnPosition",true] call BLWK_fnc_waves_getFunctionFromConfig; for "_i" from 1 to _totalNumEnemiesToSpawnDuringWave do { if (BLWK_multipleEnemyPositions) then { @@ -82,8 +82,11 @@ for "_i" from 1 to _totalNumEnemiesToSpawnDuringWave do { }; +localNamespace setVariable ["BLWK_currentWaveConfig",_waveConfig]; -// spawn the enemies for wave start +/* ---------------------------------------------------------------------------- + Spawn initial enemies +---------------------------------------------------------------------------- */ private _numberOfStartingEnemies = BLWK_maxEnemyInfantryAtOnce; private _numberOfUnitsInQueue = count (call BLWK_fnc_spawnQueue_get); if (_numberOfUnitsInQueue < BLWK_maxEnemyInfantryAtOnce) then { @@ -99,22 +102,18 @@ for "_i" from 1 to _numberOfStartingEnemies do { /* ---------------------------------------------------------------------------- Activate Initialization ---------------------------------------------------------------------------- */ -localNamespace setVariable ["BLWK_currentWaveConfig",_waveConfig]; -[_waveConfig] spawn { - // TODO: wait for inital enemies spawned from ai handler owner - // use onInitalized function +[_waveConfig,_numberOfStartingEnemies] spawn { + params ["_waveConfig","_numberOfStartingEnemies"]; + + waitUntil { + (count (call BLWK_fnc_getMustKillList) >= _numberOfStartingEnemies) + }; + + [ + BLWK_fnc_waves_onInitialized, + [_waveConfig] + ] call CBAP_fnc_directCall; }; nil - - - - - - - - - - - diff --git a/Functions/Waves/fn_waves_getFunctionFromConfig.sqf b/Functions/Waves/fn_waves_getFunctionFromConfig.sqf index 2375eae2..d06a9359 100644 --- a/Functions/Waves/fn_waves_getFunctionFromConfig.sqf +++ b/Functions/Waves/fn_waves_getFunctionFromConfig.sqf @@ -40,12 +40,27 @@ scriptName "BLWK_fnc_waves_getFunctionFromConfig"; params [ ["_waveConfig",configNull,[configNull]], ["_configProperty","",""], - ["_justName",false,[true]] + ["_justName",false,[true]], + ["_allowDefault",true,[true]] ]; -private _requestedFunctionName = getText(_waveConfig >> _configProperty); + +private _requestedConfig = _waveConfig >> _configProperty; +private _requestedFunctionName = getText(_requestedConfig); +private _functionNameIsEmpty = _requestedFunctionName isEqualTo ""; +private _configIsDefinedEmpty = !(isNull _requestedConfig) AND _functionNameIsEmpty; +if (_configIsDefinedEmpty) exitWith { + [] call KISKA_fnc_log; + if (_justName) then { + "" + } else { + {} + }; +}; + + private _default_functionName = getText(DEFAULT_WAVE_CONFIG_PATH >> _configProperty); -if (_requestedFunctionName isEqualTo "") then { +if (_functionNameIsEmpty) then { _requestedFunctionName = _default_functionName }; diff --git a/Functions/Waves/fn_waves_onInitialized.sqf b/Functions/Waves/fn_waves_onInitialized.sqf index f93db56f..4a49fa4e 100644 --- a/Functions/Waves/fn_waves_onInitialized.sqf +++ b/Functions/Waves/fn_waves_onInitialized.sqf @@ -4,7 +4,7 @@ Function: BLWK_fnc_waves_onInitialized Description: Activates some basic events after a wave has been fully initialized. - Meaning that the initial group of units has been spawned. + Meaning that the initial set of units has been spawned. Parameters: 0: _waveConfig - The config path of the wave that was created @@ -32,6 +32,14 @@ params [ ["_waveConfigPath",configNull,[configNull]] ]; + +private _onInit = [ + _waveConfigPath, + "onWaveInit" +] call BLWK_fnc_waves_getFunctionFromConfig; +call _onInit; + + private _notification = []; _notification pushBack (getText(_waveConfigPath >> "creationNotificationTemplate")); @@ -54,7 +62,6 @@ if (_isSpecialWave) then { }; - [["Start Wave: ",BLWK_currentWaveNumber],false] call KISKA_fnc_log; [missionNamespace,"BLWK_onWaveStart"] remoteExecCall ["BIS_fnc_callScriptedEventHandler",0]; diff --git a/Headers/descriptionEXT/Wave Types.hpp b/Headers/descriptionEXT/Wave Types.hpp index faf28981..24164807 100644 --- a/Headers/descriptionEXT/Wave Types.hpp +++ b/Headers/descriptionEXT/Wave Types.hpp @@ -10,21 +10,11 @@ class BLWK_waveTypes // For context of execution see BLWK_fnc_startWave's use of BLWK_fnc_getConfigForWave // onSelected = "remoteExecCall ['BLWK_fnc_handleStandardWave',BLWK_theAIHandlerOwnerID]"; - // a function that returns a list of queue entries of enemies to spawn - // an example of the expected return shape: - /* - [ - [ - "I_Soldier_A_F", // enemy class name - [0,0,0] // spawn position ATL - ] - ] - */ generateMenClassnames = "BLWK_fnc_standardWave_generateMenClassnames"; generateManSpawnPosition = "BLWK_fnc_standardWave_generateManSpawnPosition"; // The name of a function that exists on the AI handler owner that will be called - onWaveSelected = "BLWK_fnc_standardWave_onWaveSelected"; + onWaveInit = "BLWK_fnc_standardWave_onWaveInit"; onManCreated = "BLWK_fnc_standardWave_onManCreated"; // uncompiled code that is run on the server when the wave is ended From 2689be7aaa41cdd73c21454ed992ca30dfbffb83 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 17:20:41 -0600 Subject: [PATCH 030/133] (#642): replaced several old standard wave functions --- .../fn_standardWave_onWaveInit.sqf | 6 +- .../fn_standardWave_vehicles.sqf | 169 ++++++++++++++++++ .../fn_handleDefectorWave.sqf | 27 --- .../fn_handleStandardWave.sqf | 27 --- .../fn_stdEnemyVehicles.sqf | 160 ----------------- .../fn_stdVehicleKilledEvent.sqf | 36 ---- .../Waves/fn_waves_getFunctionFromConfig.sqf | 11 +- Headers/descriptionEXT/functions.hpp | 10 +- 8 files changed, 186 insertions(+), 260 deletions(-) create mode 100644 Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_vehicles.sqf delete mode 100644 Functions/Wave Type Libraries/Standard Wave Library/fn_handleDefectorWave.sqf delete mode 100644 Functions/Wave Type Libraries/Standard Wave Library/fn_handleStandardWave.sqf delete mode 100644 Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyVehicles.sqf delete mode 100644 Functions/Wave Type Libraries/Standard Wave Library/fn_stdVehicleKilledEvent.sqf diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveInit.sqf index 7a1cadd1..3ef02f92 100644 --- a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveInit.sqf +++ b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveInit.sqf @@ -18,4 +18,8 @@ Examples: Author(s): Ansible2 ---------------------------------------------------------------------------- */ -[_startingWaveUnits] call BLWK_fnc_stdEnemyVehicles; \ No newline at end of file +private _startingWaveUnits = call BLWK_fnc_getMustKillList; +[_startingWaveUnits] call BLWK_fnc_stdEnemyVehicles; + + +nil diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_vehicles.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_vehicles.sqf new file mode 100644 index 00000000..45e00364 --- /dev/null +++ b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_vehicles.sqf @@ -0,0 +1,169 @@ +#include "..\..\..\Headers\Faction Map Ids.hpp" +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_standardWave_vehicles + +Description: + Roles for the chance of vehicles spawning during a wave. + Automatically sifts through available classes based on levels/wave number. + + Will not spawn more then two vehicles which is already rare. + +Parameters: + 0: _availableInfantry : - An array of units to choose from to crew the vehicles + 1: _isDefectorWave : - Creates vehicles from friendly vehicle classes if used + +Returns: + - The spawned vehicles + +Examples: + (begin example) + private _vehiclesArray = [myUnits] call BLWK_fnc_standardWave_vehicles; + (end) + +Author(s): + Hilltop(Willtop) & omNomios, + Modified by: Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_standardWave_vehicles"; + +#define VEHICLE_TYPES [LIGHT_CAR_FACTION_MAP_ID,HEAVY_CAR_FACTION_MAP_ID,LIGHT_ARMOR_FACTION_MAP_ID,HEAVY_ARMOR_FACTION_MAP_ID] +#define VEHICLE_LIKELIHOODS [BLWK_lightCarLikelihood,BLWK_heavyCarLikelihood,BLWK_lightArmorLikelihood,BLWK_heavyArmorLikelihood] +#define SECOND_VEHICLE_DIVIDER 1.35 +#define VEHICLE_SPAWN_INCREMENT 0.05 // how much to increase likelihood by each round + +if !(BLWK_currentWaveNumber >= BLWK_vehicleStartWave) exitWith {[]}; + + +params [ + "_availableInfantry", + ["_isDefectorWave",false,[true]] +]; + + +if ((count _availableInfantry) < 2) exitWith { + ["There is less than 2 infantry available to crew a vehicle"] call KISKA_fnc_log; + [] +}; + + +// special waves will not contribute to this count +private _roundsSinceVehicleSpawned = missionNamespace getVariable ["BLWK_roundsSinceVehicleSpawned",1]; +// wait until it has been at least one round since a vehicle spawn to get another one +if (_roundsSinceVehicleSpawned < BLWK_minRoundsSinceVehicleSpawned) exitWith { + BLWK_roundsSinceVehicleSpawned = _roundsSinceVehicleSpawned + 1; + [] +}; + + +// each round increases the likelihood of a vehicle spawn by 5% +private _howLikelyIsAVehicleToSpawn = (_roundsSinceVehicleSpawned * VEHICLE_SPAWN_INCREMENT) + BLWK_baseVehicleSpawnLikelihood; +if (_howLikelyIsAVehicleToSpawn > 1) then { + _howLikelyIsAVehicleToSpawn = 1; +}; + +[["Vehicle spawn likelihood is ",_howLikelyIsAVehicleToSpawn],false] call KISKA_fnc_log; + +private _howLikelyIsAVehicleNOTToSpawn = 1 - _howLikelyIsAVehicleToSpawn; +private _vehicleWillSpawn = [true,false] selectRandomWeighted [_howLikelyIsAVehicleToSpawn,_howLikelyIsAVehicleNOTToSpawn]; +if !(_vehicleWillSpawn) exitWith { + BLWK_roundsSinceVehicleSpawned = _roundsSinceVehicleSpawned + 1; + [] +}; + +missionNamespace setVariable ["BLWK_roundsSinceVehicleSpawned",0]; + + +// decide what type of vehicles can spawn +private _vehicleTypeHash = createHashMap; +private _likelihoodWeights = []; +private _vehicleTypeValues = []; +{ + private _vehicleClasses = []; + if (_isDefectorWave) then { + _vehicleClasses = BLWK_friendlyFaction_map get _x; + + } else { + _vehicleClasses = [_x,false] call BLWK_fnc_getEnemyVehicleClasses; + + }; + + if (_vehicleClasses isNotEqualTo []) then { + _vehicleTypeHash set [_x,_vehicleClasses]; + _likelihoodWeights pushBack (VEHICLE_LIKELIHOODS select _forEachIndex); + _vehicleTypeValues pushBack _x; + + }; + +} forEach VEHICLE_TYPES; + + +if (_vehicleTypeValues isEqualTo []) exitWith { + ["No vehicles to spawn for enemy factions, exiting",false] call KISKA_fnc_log; + [] +}; + + +private _returnedVehicles = []; +private _fn_spawnAVehicle = { + params [ + ["_vehicleNumber",1] + ]; + // [str _likelihoodWeights,false,true,false] call KISKA_fnc_log; + // [str _vehicleTypeValues,false,true,false] call KISKA_fnc_log; + private _vehicleType = _vehicleTypeValues selectRandomWeighted _likelihoodWeights; + + // Don't duplicate vehicles if possible for the sake of variety + if ((count _vehicleTypeValues) > 1) then { + private _index = _vehicleTypeValues find _vehicleType; + _vehicleTypeValues deleteAt _index; + _likelihoodWeights deleteAt _index; + }; + + [["Selected vehicle type: ",_vehicleType],false] call KISKA_fnc_log; + + private _vehicleClass = selectRandom (_vehicleTypeHash get _vehicleType); + private _spawnPosition = selectRandom BLWK_vehicleSpawnPositions; + private _vehicle = _vehicleClass createVehicle _spawnPosition; + + private _crewCount = 3; + private _topIndex = (_crewCount * _vehicleNumber) - 1; + private _bottomIndex = (_crewCount * _vehicleNumber) - _crewCount; + private _crew = _availableInfantry select [_bottomIndex,_topIndex]; + + private _group = createGroup (side (_crew select 0)); + _group deleteGroupWhenEmpty true; + _group allowFleeing 0; + + _crew joinSilent _group; + [_group,_vehicle] call KISKA_fnc_setCrew; + _crew doMove (getPosATL BLWK_mainCrate); + + [BLWK_zeus, [[_vehicle],false]] remoteExecCall ["addCuratorEditableObjects",2]; + + + _returnedVehicles pushBack _vehicle; + _vehicle addEventHandler ["KILLED", { + params ["_killedUnit", "", "_instigator"]; + + if (!(isNull _instigator) AND (isPlayer _instigator)) then { + // show a player hit points and add them to there score + [_killedUnit,true] remoteExecCall ["BLWK_fnc_event_killedEnemy",_instigator]; + }; + }]; +}; + + +call _fn_spawnAVehicle; + +// do a role for a second vehicle +// make sure there are enough AI to even crew a ground vehicle +if ((count _availableInfantry) > 1) then { + private _howLikelyIsASecondVehicleToSpawn = _howLikelyIsAVehicleToSpawn / SECOND_VEHICLE_DIVIDER; + private _secondVehicleWillSpawn = [true,false] selectRandomWeighted [_howLikelyIsASecondVehicleToSpawn,1 - _howLikelyIsASecondVehicleToSpawn]; + if (_secondVehicleWillSpawn) then { + [2] call _fn_spawnAVehicle; + }; +}; + + +_returnedVehicles diff --git a/Functions/Wave Type Libraries/Standard Wave Library/fn_handleDefectorWave.sqf b/Functions/Wave Type Libraries/Standard Wave Library/fn_handleDefectorWave.sqf deleted file mode 100644 index f7c379ed..00000000 --- a/Functions/Wave Type Libraries/Standard Wave Library/fn_handleDefectorWave.sqf +++ /dev/null @@ -1,27 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_handleDefectorWave - -Description: - This is simply an alias for the below functions. It is used to exec - both on whomever the AI handler is without using multiple remoteExecs - - Executed from "BLWK_fnc_spawnWaveEnemies" - -Parameters: - NONE - -Returns: - NOTHING - -Examples: - (begin example) - - call BLWK_fnc_handleDefectorWave; - - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -private _startingWaveUnits = [true] call BLWK_fnc_createStdWaveInfantry; -[_startingWaveUnits,true] call BLWK_fnc_stdEnemyVehicles; \ No newline at end of file diff --git a/Functions/Wave Type Libraries/Standard Wave Library/fn_handleStandardWave.sqf b/Functions/Wave Type Libraries/Standard Wave Library/fn_handleStandardWave.sqf deleted file mode 100644 index 8835131b..00000000 --- a/Functions/Wave Type Libraries/Standard Wave Library/fn_handleStandardWave.sqf +++ /dev/null @@ -1,27 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_handleStandardWave - -Description: - This is simply an alias for the below functions. It is used to exec - both on whomever the AI handler is without using multiple remoteExecs - - Executed from "BLWK_fnc_spawnWaveEnemies" - -Parameters: - NONE - -Returns: - NOTHING - -Examples: - (begin example) - - call BLWK_fnc_handleStandardWave; - - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -private _startingWaveUnits = call BLWK_fnc_createStdWaveInfantry; -[_startingWaveUnits] call BLWK_fnc_stdEnemyVehicles; \ No newline at end of file diff --git a/Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyVehicles.sqf b/Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyVehicles.sqf deleted file mode 100644 index a325cb6c..00000000 --- a/Functions/Wave Type Libraries/Standard Wave Library/fn_stdEnemyVehicles.sqf +++ /dev/null @@ -1,160 +0,0 @@ -#include "..\..\..\Headers\Faction Map Ids.hpp" -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_stdEnemyVehicles - -Description: - Roles for the chance of vehicles spawning during a wave. - Automatically sifts through available classes based on levels/wave number. - - Will not spawn more then two vehicles which is already rare. - -Parameters: - 0: _availableInfantry : - An array of units to choose from to crew the vehicles - 1: _isDefectorWave : - Creates vehicles from friendly vehicle classes if used - -Returns: - ARRAY - The spawned vehicles - -Examples: - (begin example) - _vehiclesArray = [myUnits,false] call BLWK_fnc_stdEnemyVehicles; - (end) - -Author(s): - Hilltop(Willtop) & omNomios, - Modified by: Ansible2 // Cipher ----------------------------------------------------------------------------- */ -scriptName "BLWK_fnc_stdEnemyVehicles"; - -#define VEHICLE_TYPES [LIGHT_CAR_FACTION_MAP_ID,HEAVY_CAR_FACTION_MAP_ID,LIGHT_ARMOR_FACTION_MAP_ID,HEAVY_ARMOR_FACTION_MAP_ID] -#define VEHICLE_LIKELIHOODS [BLWK_lightCarLikelihood,BLWK_heavyCarLikelihood,BLWK_lightArmorLikelihood,BLWK_heavyArmorLikelihood] -#define SECOND_VEHICLE_DIVIDER 1.35 -#define VEHICLE_SPAWN_INCREMENT 0.05 // how much to increase likelihood by each round - -if !(BLWK_currentWaveNumber >= BLWK_vehicleStartWave) exitWith {[]}; - - -params [ - "_availableInfantry", - ["_isDefectorWave",false,[true]] -]; - -if (clientOwner isNotEqualTo BLWK_theAIHandlerOwnerID) exitWith {[]}; - -if (count _availableInfantry < 2) exitWith { - ["There is less than 2 infantry available to crew a vehicle"] call KISKA_fnc_log; - [] -}; - -// special waves will not contribute to this count -private _roundsSinceVehicleSpawned = missionNamespace getVariable ["BLWK_roundsSinceVehicleSpawned",1]; -// wait until it has been at least one round since a vehicle spawn to get another one -if (_roundsSinceVehicleSpawned < BLWK_minRoundsSinceVehicleSpawned) exitWith { - BLWK_roundsSinceVehicleSpawned = _roundsSinceVehicleSpawned + 1; - [] -}; - - -// each round increases the likelihood of a vehicle spawn by 5% -private _howLikelyIsAVehicleToSpawn = (_roundsSinceVehicleSpawned * VEHICLE_SPAWN_INCREMENT) + BLWK_baseVehicleSpawnLikelihood; -if (_howLikelyIsAVehicleToSpawn > 1) then { - _howLikelyIsAVehicleToSpawn = 1; -}; - -[["Vehicle spawn likelihood is ",_howLikelyIsAVehicleToSpawn],false] call KISKA_fnc_log; -private _howLikelyIsAVehicleNOTToSpawn = 1 - _howLikelyIsAVehicleToSpawn; - -private _vehicleWillSpawn = [true,false] selectRandomWeighted [_howLikelyIsAVehicleToSpawn,_howLikelyIsAVehicleNOTToSpawn]; -if !(_vehicleWillSpawn) exitWith { - BLWK_roundsSinceVehicleSpawned = _roundsSinceVehicleSpawned + 1; - [] -}; - -missionNamespace setVariable ["BLWK_roundsSinceVehicleSpawned",0]; - - -// decide what type of vehicles can spawn -private _vehicleTypeHash = createHashMap; -private _likelihoodWeights = []; -private _vehicleTypeValues = []; -{ - private _vehicleClasses = []; - if (_isDefectorWave) then { - _vehicleClasses = BLWK_friendlyFaction_map get _x; - - } else { - _vehicleClasses = [_x,false] call BLWK_fnc_getEnemyVehicleClasses; - - }; - - if (_vehicleClasses isNotEqualTo []) then { - _vehicleTypeHash set [_x,_vehicleClasses]; - _likelihoodWeights pushBack (VEHICLE_LIKELIHOODS select _forEachIndex); - _vehicleTypeValues pushBack _x; - - }; - -} forEach VEHICLE_TYPES; - - -if (_vehicleTypeValues isEqualTo []) exitWith { - ["No vehicles to spawn for enemy factions, exiting",false] call KISKA_fnc_log; - [] -}; - - - -private _returnedVehicles = []; -private _fn_spawnAVehicle = { - [str _likelihoodWeights,false,true,false] call KISKA_fnc_log; - [str _vehicleTypeValues,false,true,false] call KISKA_fnc_log; - private _vehicleType = _vehicleTypeValues selectRandomWeighted _likelihoodWeights; - - // Don't duplicate vehicles if possible for the sake of variety - if (count _vehicleTypeValues > 1) then { - private _index = _vehicleTypeValues find _vehicleType; - _vehicleTypeValues deleteAt _index; - _likelihoodWeights deleteAt _index; - }; - - [["Selected vehicle type: ",_vehicleType],false] call KISKA_fnc_log; - - private _vehicleClass = selectRandom (_vehicleTypeHash get _vehicleType); - private _spawnPosition = selectRandom BLWK_vehicleSpawnPositions; - private _vehicle = _vehicleClass createVehicle _spawnPosition; - - private _crew = _availableInfantry select [0,3]; - _availableInfantry deleteRange [0,3]; - - private _group = createGroup (side (_crew select 0)); - _group deleteGroupWhenEmpty true; - _group allowFleeing 0; - - _crew joinSilent _group; - [_group,_vehicle] call KISKA_fnc_setCrew; - _crew doMove (getPosATL BLWK_mainCrate); - - [BLWK_zeus, [[_vehicle],false]] remoteExecCall ["addCuratorEditableObjects",2]; - - - _returnedVehicles pushBack _vehicle; - _vehicle addEventHandler ["KILLED",{ - _this call BLWK_fnc_stdVehicleKilledEvent; - }]; -}; - - -call _fn_spawnAVehicle; - -// do a role for a second vehicle -// make sure there are enough AI to even crew a ground vehicle -if (count _availableInfantry > 1) then { - private _howLikelyIsASecondVehicleToSpawn = _howLikelyIsAVehicleToSpawn / SECOND_VEHICLE_DIVIDER; - private _secondVehicleWillSpawn = [true,false] selectRandomWeighted [_howLikelyIsASecondVehicleToSpawn,1 - _howLikelyIsASecondVehicleToSpawn]; - if (_secondVehicleWillSpawn) then { - call _fn_spawnAVehicle; - }; -}; - - -_returnedVehicles diff --git a/Functions/Wave Type Libraries/Standard Wave Library/fn_stdVehicleKilledEvent.sqf b/Functions/Wave Type Libraries/Standard Wave Library/fn_stdVehicleKilledEvent.sqf deleted file mode 100644 index ceced575..00000000 --- a/Functions/Wave Type Libraries/Standard Wave Library/fn_stdVehicleKilledEvent.sqf +++ /dev/null @@ -1,36 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_stdVehicleKilledEvent - -Description: - Executes the code in the standard enemy vehicles killed event - for adding points to players and markers. - - Executed from the event added by "BLWK_fnc_stdEnemyVehicles" - -Parameters: - 0: _killedUnit : - Object the event handler is assigned to - 1: _killer : - Object that killed _killedUnit – contains unit itself in case of collisions (not used) - 2: _instigator : - Person who pulled the trigger - 3: _useEffects : - same as useEffects in setDamage alt syntax (not used) - - -Returns: - NOTHING - -Examples: - (begin example) - - _this call BLWK_fnc_stdVehicleKilledEvent; - - (end) - -Author(s): - Hilltop(Willtop) & omNomios, - Modified by: Ansible2 // Cipher ----------------------------------------------------------------------------- */ -params ["_killedUnit", "_killer", "_instigator", "_useEffects"]; - -if (!(isNull _instigator) AND {isPlayer _instigator}) then { - // show a player hit points and add them to there score - [_killedUnit,true] remoteExecCall ["BLWK_fnc_handleKillEventPlayer",_instigator]; -}; \ No newline at end of file diff --git a/Functions/Waves/fn_waves_getFunctionFromConfig.sqf b/Functions/Waves/fn_waves_getFunctionFromConfig.sqf index d06a9359..00c4dc14 100644 --- a/Functions/Waves/fn_waves_getFunctionFromConfig.sqf +++ b/Functions/Waves/fn_waves_getFunctionFromConfig.sqf @@ -50,7 +50,16 @@ private _requestedFunctionName = getText(_requestedConfig); private _functionNameIsEmpty = _requestedFunctionName isEqualTo ""; private _configIsDefinedEmpty = !(isNull _requestedConfig) AND _functionNameIsEmpty; if (_configIsDefinedEmpty) exitWith { - [] call KISKA_fnc_log; + [ + [ + "found empty definition for ", + _configProperty, + " at config: ", + _waveConfig + ], + false + ] call KISKA_fnc_log; + if (_justName) then { "" } else { diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 94620a55..fcd77891 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -476,6 +476,8 @@ class BLWK {}; class standardWave_onWaveSelected {}; + class standardWave_vehicles + {}; }; class Events @@ -492,14 +494,6 @@ class BLWK file = "Functions\Wave Type Libraries\Standard Wave Library"; class createStdWaveInfantry {}; - class handleDefectorWave - {}; - class handleStandardWave - {}; - class stdEnemyVehicles - {}; - class stdVehicleKilledEvent - {}; }; class SuicideWaveLibrary From e654f9d11a1361d610e2e2ad0f600aaafc9c22dd Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 17:22:18 -0600 Subject: [PATCH 031/133] (#642): fixed function definiton and removed olf wave lib --- .../fn_createStdWaveInfantry.sqf | 116 ------------------ Headers/descriptionEXT/functions.hpp | 9 +- 2 files changed, 1 insertion(+), 124 deletions(-) delete mode 100644 Functions/Wave Type Libraries/Standard Wave Library/fn_createStdWaveInfantry.sqf diff --git a/Functions/Wave Type Libraries/Standard Wave Library/fn_createStdWaveInfantry.sqf b/Functions/Wave Type Libraries/Standard Wave Library/fn_createStdWaveInfantry.sqf deleted file mode 100644 index f485971b..00000000 --- a/Functions/Wave Type Libraries/Standard Wave Library/fn_createStdWaveInfantry.sqf +++ /dev/null @@ -1,116 +0,0 @@ -#include "..\..\..\Headers\String Constants.hpp" -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_createStdWaveInfantry - -Description: - Creates the standard infantry for a normal wave. - - Also has the ability to queue up units based upon the mission param size of - units allowed at once. - -Parameters: - 0: _isDefectorWave : - Will this be a wave of defectors - 1: _totalNumEnemiesToSpawnDuringWave : - The number of units that will spawn in the wave - if less than BASE_ENEMY_NUMBER, total will be auto calculated - -Returns: - ARRAY - the units created - -Examples: - (begin example) - [false] call BLWK_fnc_createStdWaveInfantry; - (end) - -Author(s): - Hilltop(Willtop) & omNomios, - Modified by: Ansible2 // Cipher ----------------------------------------------------------------------------- */ -#define BASE_ENEMY_NUMBER 2 - -params [ - ["_isDefectorWave",false,[true]], - ["_totalNumEnemiesToSpawnDuringWave",-1,[123]] -]; - -private _fn_getAvailableEnemyLists = { - if (_isDefectorWave) exitWith { - [BLWK_friendlyFaction_menClasses,1] - }; - - private _returnedLists = []; - - // classes - _returnedLists pushback BLWK_level1Faction_menClasses; - // weight of class - _returnedLists pushBack BLWK_level1Faction_weight; - - if (BLWK_currentWaveNumber >= BLWK_level2Faction_startWave) then { - _returnedLists pushback BLWK_level2Faction_menClasses; - _returnedLists pushBack BLWK_level2Faction_weight; - }; - if (BLWK_currentWaveNumber > BLWK_level3Faction_startWave) then { - _returnedLists pushback BLWK_level3Faction_menClasses; - _returnedLists pushBack BLWK_level3Faction_weight; - }; - if (BLWK_currentWaveNumber > BLWK_level4Faction_startWave) then { - _returnedLists pushback BLWK_level4Faction_menClasses; - _returnedLists pushBack BLWK_level4Faction_weight; - }; - if (BLWK_currentWaveNumber > BLWK_level5Faction_startWave) then { - _returnedLists pushback BLWK_level5Faction_menClasses; - _returnedLists pushBack BLWK_level5Faction_weight; - }; - - _returnedLists -}; - -// get the total enemy number for this round -private _availableMenClassesWeighted = call _fn_getAvailableEnemyLists; -if (_totalNumEnemiesToSpawnDuringWave < BASE_ENEMY_NUMBER) then { - _totalNumEnemiesToSpawnDuringWave = BASE_ENEMY_NUMBER * ((BLWK_enemiesPerWaveMultiplier * BLWK_currentWaveNumber) + 1); - _totalNumEnemiesToSpawnDuringWave = _totalNumEnemiesToSpawnDuringWave + (BLWK_enemiesPerPlayerMultiplier * (count (call CBAP_fnc_players))); - _totalNumEnemiesToSpawnDuringWave = round _totalNumEnemiesToSpawnDuringWave; -}; - - -private "_selectedEnemyLevelTemp"; -private _fn_selectEnemyType = { - // select enemy level - _selectedEnemyLevelTemp = selectRandomWeighted _availableMenClassesWeighted; - // return a random entry from the selected level's array - selectRandom _selectedEnemyLevelTemp -}; - -// cache AI spawn info for queue -private ["_spawnPositionTemp","_typeTemp"]; -if (!BLWK_multipleEnemyPositions) then { - _spawnPositionTemp = selectRandom BLWK_infantrySpawnPositions; -}; - -for "_i" from 1 to _totalNumEnemiesToSpawnDuringWave do { - if (BLWK_multipleEnemyPositions) then { - _spawnPositionTemp = selectRandom BLWK_infantrySpawnPositions; - }; - _typeTemp = call _fn_selectEnemyType; - - [STANDARD_ENEMY_INFANTRY_QUEUE,_typeTemp,_spawnPositionTemp] call BLWK_fnc_addToQueue; -}; - - -// spawn the enemies for wave start -private _numStartingEnemies = BLWK_maxEnemyInfantryAtOnce; -private _spawnQueueCount = count (missionNamespace getVariable [STANDARD_ENEMY_INFANTRY_QUEUE,[]]); -if (_spawnQueueCount < BLWK_maxEnemyInfantryAtOnce) then { - _numStartingEnemies = _spawnQueueCount; -}; -private _unit = objNull; -private _units = []; -for "_i" from 1 to _numStartingEnemies do { - _unit = [STANDARD_ENEMY_INFANTRY_QUEUE,"_this call BLWK_fnc_stdEnemyManCreateCode"] call BLWK_fnc_createFromQueue; - _units pushBack _unit; -}; - -missionNamespace setVariable ["BLWK_initialWaveSpawnComplete",true]; - - -_units diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index fcd77891..41a77e38 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -474,7 +474,7 @@ class BLWK {}; class standardWave_onManCreated {}; - class standardWave_onWaveSelected + class standardWave_onWaveInit {}; class standardWave_vehicles {}; @@ -489,13 +489,6 @@ class BLWK {}; }; - class StandardWaveLibrary - { - file = "Functions\Wave Type Libraries\Standard Wave Library"; - class createStdWaveInfantry - {}; - }; - class SuicideWaveLibrary { file = "Functions\Wave Type Libraries\Suicide Wave Library"; From 36c8e82aa6b3e81da07d586c77f7b8e7699b2cf9 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 17:25:04 -0600 Subject: [PATCH 032/133] (#642): removed old comments --- Functions/Other/fn_handleEnemyWeapons.sqf | 2 -- Functions/Waves/fn_waves_create.sqf | 15 --------------- 2 files changed, 17 deletions(-) diff --git a/Functions/Other/fn_handleEnemyWeapons.sqf b/Functions/Other/fn_handleEnemyWeapons.sqf index 18806a08..76bc1022 100644 --- a/Functions/Other/fn_handleEnemyWeapons.sqf +++ b/Functions/Other/fn_handleEnemyWeapons.sqf @@ -6,8 +6,6 @@ Description: Also calls BLWK_fnc_randomizeWeapons if random enemy kits param is active. - Executed from "BLWK_fnc_stdEnemyManCreateCode" - Parameters: NONE diff --git a/Functions/Waves/fn_waves_create.sqf b/Functions/Waves/fn_waves_create.sqf index 7bbe1761..ab238b8d 100644 --- a/Functions/Waves/fn_waves_create.sqf +++ b/Functions/Waves/fn_waves_create.sqf @@ -25,21 +25,6 @@ Author(s): ---------------------------------------------------------------------------- */ scriptName "BLWK_fnc_wave_create"; -// if (clientOwner isNotEqualTo BLWK_theAIHandlerOwnerID) exitWith { -// private _message = [ -// "Executed BLWK_fnc_wave_create on clientOwner: ", -// clientOwner, -// " while BLWK_theAIHandlerOwnerID was: ", -// BLWK_theAIHandlerOwnerID, -// " on this machine! Defaulting to sever to handle the wave" -// ] joinString ""; -// [_message,5] remoteExecCall ["KISKA_fnc_errorNotification",0]; -// [_message,true] remoteExecCall ["KISKA_fnc_log",2]; - -// _this remoteExecCall ["BLWK_fnc_wave_create",2]; -// }; - -// #define DEFAULT_ON_WAVE_SELECTED_NAME "BLWK_fnc_standardWave_onWaveSelected" #define BASE_ENEMY_NUMBER 2 params [ From a2e2e8f162b45caa31f015d71e31bece68216735 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 17:33:14 -0600 Subject: [PATCH 033/133] (#642): fixed incorrect function name --- Functions/Waves/fn_startWave.sqf | 2 +- Functions/Waves/fn_waves_create.sqf | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Functions/Waves/fn_startWave.sqf b/Functions/Waves/fn_startWave.sqf index 6d038509..2bc6110b 100644 --- a/Functions/Waves/fn_startWave.sqf +++ b/Functions/Waves/fn_startWave.sqf @@ -62,7 +62,7 @@ if (missionNamespace getVariable ["BLWK_extractionQueued",false]) then { } else { private _waveConfig = call BLWK_fnc_getConfigForWave; - [_waveConfig] call BLWK_fnc_wave_create; + [_waveConfig] call BLWK_fnc_waves_create; // loot is spawned before the wave starts at round 1 if (BLWK_currentWaveNumber > BLWK_startingFromWaveNumber) then { diff --git a/Functions/Waves/fn_waves_create.sqf b/Functions/Waves/fn_waves_create.sqf index ab238b8d..be8399f6 100644 --- a/Functions/Waves/fn_waves_create.sqf +++ b/Functions/Waves/fn_waves_create.sqf @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- -Function: BLWK_fnc_wave_create +Function: BLWK_fnc_waves_create Description: Takes the first entry in the enemy man spawn queue, removes the item and then @@ -17,13 +17,13 @@ Examples: (begin example) [ missionConfigFile >> "BLWK_waveTypes" >> "normalWaves" >> "standardWave" - ] call BLWK_fnc_wave_create; + ] call BLWK_fnc_waves_create; (end) Author(s): Ansible2 ---------------------------------------------------------------------------- */ -scriptName "BLWK_fnc_wave_create"; +scriptName "BLWK_fnc_waves_create"; #define BASE_ENEMY_NUMBER 2 From 750f68ae34cc0b2ef2b8a8c892b981105f6d1e1f Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 17:39:49 -0600 Subject: [PATCH 034/133] (#642): updated wave config documentation --- Headers/descriptionEXT/Wave Types.hpp | 28 ++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/Headers/descriptionEXT/Wave Types.hpp b/Headers/descriptionEXT/Wave Types.hpp index 24164807..44de0bbd 100644 --- a/Headers/descriptionEXT/Wave Types.hpp +++ b/Headers/descriptionEXT/Wave Types.hpp @@ -6,15 +6,33 @@ class BLWK_waveTypes { class standardWave { - // uncompiled code that is run on the server when the wave is selected (started). - // For context of execution see BLWK_fnc_startWave's use of BLWK_fnc_getConfigForWave - // onSelected = "remoteExecCall ['BLWK_fnc_handleStandardWave',BLWK_theAIHandlerOwnerID]"; - + // The name of a missionNamespace variable that must be code that will return + // an array of weighted or unweighted classnames () + // that will be randomly selected from when spawning an enemy man + // Executes on the SERVER + // (see BLWK_fnc_waves_create for context) generateMenClassnames = "BLWK_fnc_standardWave_generateMenClassnames"; + + // The name of a missionNamespace variable that must be code that will return + // a single position in ATL format () + // Executes on the SERVER + // (see BLWK_fnc_waves_create for context) generateManSpawnPosition = "BLWK_fnc_standardWave_generateManSpawnPosition"; - // The name of a function that exists on the AI handler owner that will be called + // The name of a missionNamespace variable that must be code. + // This will be executed after all initial units have spawned for the start of a wave + // Executes on the SERVER + // (see BLWK_fnc_waves_create and BLWK_fnc_waves_onInitialized for context) + // Parameters: + /// 0: - the config of the wave onWaveInit = "BLWK_fnc_standardWave_onWaveInit"; + + // The name of a missionNamespace variable that must be code. + // Runs once a unit is created from the queue of enemies to spawn. + // Executes on the AI Handler (either headless or server) + // (see BLWK_fnc_spawnQueue_create for context) + // Parameters: + /// 0: - the unit created onManCreated = "BLWK_fnc_standardWave_onManCreated"; // uncompiled code that is run on the server when the wave is ended From 69247cded4831f5ed0fd60804a387e3d8c734d80 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 17:40:17 -0600 Subject: [PATCH 035/133] (#642): added config event call for when a man is created --- Functions/Queue/fn_spawnQueue_create.sqf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Functions/Queue/fn_spawnQueue_create.sqf b/Functions/Queue/fn_spawnQueue_create.sqf index 4b4f4e74..ecd13ae1 100644 --- a/Functions/Queue/fn_spawnQueue_create.sqf +++ b/Functions/Queue/fn_spawnQueue_create.sqf @@ -88,4 +88,7 @@ _unit addEventHandler ["Deleted", { [BLWK_zeus, [[_unit],false]] remoteExecCall ["addCuratorEditableObjects",2]; +[_unit] call (missionNamespace getVariable [_onManCreatedFunctionName,{}]); + + nil From cdba971db1bdf513d0b47cd04dcefaae0af24bd1 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 17:45:47 -0600 Subject: [PATCH 036/133] (#642): updated wave cleared logic and renamed --- ...WaveCleared.sqf => fn_waves_isCleared.sqf} | 26 +++++++++---------- Headers/descriptionEXT/functions.hpp | 7 ++--- 2 files changed, 17 insertions(+), 16 deletions(-) rename Functions/Waves/{fn_isWaveCleared.sqf => fn_waves_isCleared.sqf} (62%) diff --git a/Functions/Waves/fn_isWaveCleared.sqf b/Functions/Waves/fn_waves_isCleared.sqf similarity index 62% rename from Functions/Waves/fn_isWaveCleared.sqf rename to Functions/Waves/fn_waves_isCleared.sqf index f12dc214..8737821c 100644 --- a/Functions/Waves/fn_isWaveCleared.sqf +++ b/Functions/Waves/fn_waves_isCleared.sqf @@ -1,35 +1,35 @@ /* ---------------------------------------------------------------------------- -Function: BLWK_fnc_isWaveCleared +Function: BLWK_fnc_waves_isCleared Description: - Checks all the units in the global must kill list to see if any are still alive. - - Executed from "BLWK_fnc_startWave" + Checks if the wave can be considered over. Parameters: - NONE + NONE Returns: - - whether or not all the rquired enemies to kill are dead + - whether or not all the rquired enemies to kill are dead Examples: (begin example) - private _areEnemiesDead = call BLWK_fnc_isWaveCleared; + private _areEnemiesDead = call BLWK_fnc_waves_isCleared; (end) Author(s): - Ansible2 + Ansible2 ---------------------------------------------------------------------------- */ if (!isServer) exitWith { false }; +if ((call BLWK_fnc_spawnQueue_get) isNotEqualTo []) exitWith { false }; + private _index = (call BLWK_fnc_getMustKillList) findIf { alive _x }; private _aUnitIsStillAlive = _index isNotEqualTo -1; +if (_aUnitIsStillAlive) exitWith { false }; + // not all special wave drones spawn right away, so checking that they have // (and that they are therefore in the kill list) // before checking if all enemies are dead private _allDronesCreated = missionNamespace getVariable ["BLWK_allDronesCreated",true]; -if (_aUnitIsStillAlive OR (!_allDronesCreated)) then { - false -} else { - true -}; \ No newline at end of file +if (!_allDronesCreated) exitWith { false }; + +true diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 41a77e38..43dd0fd2 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -513,7 +513,9 @@ class BLWK {}; class waves_create {}; - + class waves_isCleared + {}; + class addToMustKillList {}; class cacheEnemyMenSpawnPositions @@ -528,8 +530,7 @@ class BLWK {}; class getMustKillList {}; - class isWaveCleared - {}; + class setSkill {}; class spawnLoot From f71dc02faa3167e476bc1608b60550e50bae2e3a Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 18:38:45 -0600 Subject: [PATCH 037/133] (#642): added BLWK_fnc_spawnQueue_unitKilled --- Functions/Queue/fn_spawnQueue_create.sqf | 4 +- .../Queue/fn_spawnQueue_popAndCreate.sqf | 10 ++--- Functions/Queue/fn_spawnQueue_unitKilled.sqf | 37 +++++++++++++++++++ Headers/descriptionEXT/functions.hpp | 2 + 4 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 Functions/Queue/fn_spawnQueue_unitKilled.sqf diff --git a/Functions/Queue/fn_spawnQueue_create.sqf b/Functions/Queue/fn_spawnQueue_create.sqf index ecd13ae1..7324cd5c 100644 --- a/Functions/Queue/fn_spawnQueue_create.sqf +++ b/Functions/Queue/fn_spawnQueue_create.sqf @@ -73,11 +73,11 @@ _unit addEventHandler ["Killed", { [_killedUnit] remoteExec ["BLWK_fnc_event_killedEnemy",_instigator]; }; - [] remoteExecCall ["BLWK_fnc_spawnQueue_popAndCreate",2]; + [] remoteExec ["BLWK_fnc_spawnQueue_unitKilled",2]; }]; _unit addEventHandler ["Deleted", { - [] remoteExecCall ["BLWK_fnc_spawnQueue_popAndCreate",2]; + [] remoteExec ["BLWK_fnc_spawnQueue_unitKilled",2]; }]; diff --git a/Functions/Queue/fn_spawnQueue_popAndCreate.sqf b/Functions/Queue/fn_spawnQueue_popAndCreate.sqf index f765128c..d2a57dd8 100644 --- a/Functions/Queue/fn_spawnQueue_popAndCreate.sqf +++ b/Functions/Queue/fn_spawnQueue_popAndCreate.sqf @@ -9,11 +9,12 @@ Parameters: NONE Returns: - NOTHING + <[STRING, PositionATL[] OR OBJECT, STRING]> - the element removed or empty `[]` + if no items were in queue Examples: (begin example) - call BLWK_fnc_spawnQueue_popAndCreate; + private _poppedElement = call BLWK_fnc_spawnQueue_popAndCreate; (end) Author(s): @@ -26,12 +27,11 @@ if (!isServer) exitWith {}; // check if queue is empty private _queue = localNamespace getVariable ["BLWK_spawnQueue",[]]; if (_queue isEqualTo []) exitWith { - // TODO: end wave + [] }; private _spawnArgs = _queue deleteAt 0; _spawnArgs remoteExecCall ["BLWK_fnc_spawnQueue_create",BLWK_theAIHandlerOwnerID]; - -nil +_spawnArgs diff --git a/Functions/Queue/fn_spawnQueue_unitKilled.sqf b/Functions/Queue/fn_spawnQueue_unitKilled.sqf new file mode 100644 index 00000000..942261a0 --- /dev/null +++ b/Functions/Queue/fn_spawnQueue_unitKilled.sqf @@ -0,0 +1,37 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_spawnQueue_unitKilled + +Description: + Informs the server that a unit from the queue has died. This will either + trigger another unit to be popped and created or to end the wave. + +Parameters: + NONE + +Returns: + NOTHING + +Examples: + (begin example) + [] remoteExec ["BLWK_fnc_spawnQueue_unitKilled",2]; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_spawnQueue_unitKilled"; + +if (!isServer) exitWith {}; + +private _queueItem = call BLWK_fnc_popAndCreate; +private _queueIsEmpty = _queueItem isEqualTo []; +if (_queueIsEmpty AND {call BLWK_fnc_waves_isCleared}) then { + [ + { + // TODO: call end wave + } + ] call CBAP_fnc_directCall; +}; + + +nil diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 43dd0fd2..66a0e21d 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -305,6 +305,8 @@ class BLWK {}; class spawnQueue_popAndCreate {}; + class spawnQueue_unitKilled + {}; }; class SatelliteShop From 2dda426ee9dcb508ef9a92df59340eb140e12101 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 19:00:49 -0600 Subject: [PATCH 038/133] (#642): adjusted BLWK_fnc_standardWave_vehicles to use dynamic crew count --- .../fn_standardWave_vehicles.sqf | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_vehicles.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_vehicles.sqf index 45e00364..d72384a4 100644 --- a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_vehicles.sqf +++ b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_vehicles.sqf @@ -106,7 +106,7 @@ if (_vehicleTypeValues isEqualTo []) exitWith { private _returnedVehicles = []; private _fn_spawnAVehicle = { params [ - ["_vehicleNumber",1] + ["_startingIndex",0] ]; // [str _likelihoodWeights,false,true,false] call KISKA_fnc_log; // [str _vehicleTypeValues,false,true,false] call KISKA_fnc_log; @@ -125,10 +125,27 @@ private _fn_spawnAVehicle = { private _spawnPosition = selectRandom BLWK_vehicleSpawnPositions; private _vehicle = _vehicleClass createVehicle _spawnPosition; - private _crewCount = 3; - private _topIndex = (_crewCount * _vehicleNumber) - 1; - private _bottomIndex = (_crewCount * _vehicleNumber) - _crewCount; - private _crew = _availableInfantry select [_bottomIndex,_topIndex]; + private _totalNumberOfAvailableUnits = (count _availableInfantry) - (_startingIndex + 1); + if (_totalNumberOfAvailableUnits isEqualTo 0) exitWith { + ["Could not find any units to for vehicle",false] call KISKA_fnc_log; + _totalNumberOfAvailableUnits - 1 + }; + + private _configCrewCount = [_vehicleClass, false] call BIS_fnc_crewCount; + private _crewCount = _configCrewCount min _totalNumberOfAvailableUnits; + if ( + (_crewCount isEqualTo _totalNumberOfAvailableUnits) AND + (_configCrewCount isNotEqualTo _totalNumberOfAvailableUnits) AND + // A vehicle can get by with 3 crew usually + (_crewCount < 3) + ) exitWith { + ["Did not find enough units to fit into vehicle",false] call KISKA_fnc_log; + _startingIndex + }; + + private _nextAvailableIndex = _startingIndex + _crewCount; + private _selectionEndIndex = _nextAvailableIndex - 1; + private _crew = _availableInfantry select [_startingIndex,_lastIndex]; private _group = createGroup (side (_crew select 0)); _group deleteGroupWhenEmpty true; @@ -150,10 +167,12 @@ private _fn_spawnAVehicle = { [_killedUnit,true] remoteExecCall ["BLWK_fnc_event_killedEnemy",_instigator]; }; }]; + + _nextAvailableIndex }; -call _fn_spawnAVehicle; +private _nextAvailableIndex = call _fn_spawnAVehicle; // do a role for a second vehicle // make sure there are enough AI to even crew a ground vehicle @@ -161,7 +180,7 @@ if ((count _availableInfantry) > 1) then { private _howLikelyIsASecondVehicleToSpawn = _howLikelyIsAVehicleToSpawn / SECOND_VEHICLE_DIVIDER; private _secondVehicleWillSpawn = [true,false] selectRandomWeighted [_howLikelyIsASecondVehicleToSpawn,1 - _howLikelyIsASecondVehicleToSpawn]; if (_secondVehicleWillSpawn) then { - [2] call _fn_spawnAVehicle; + [_nextAvailableIndex] call _fn_spawnAVehicle; }; }; From f288ed69a5f09a10e21d3bcfa95673586ab85625 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 19:52:46 -0600 Subject: [PATCH 039/133] (#642): updated extraction script with new wave creation --- Functions/Extraction/fn_extraction.sqf | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Functions/Extraction/fn_extraction.sqf b/Functions/Extraction/fn_extraction.sqf index 7a4aa633..5763137b 100644 --- a/Functions/Extraction/fn_extraction.sqf +++ b/Functions/Extraction/fn_extraction.sqf @@ -25,7 +25,7 @@ scriptName "BLWK_fnc_extraction"; #define TOO_LITTLE_SEATS 3 #define SPACE_BUFFER 5 #define MIN_VEHICLE_SIZE 15 -#define NUMBER_OF_ENEMIES 5000 +#define NUMBER_OF_ENEMIES 10000 #define TELEPORT_TIME 8 #define MAX_ATTEMPTS 300 @@ -257,7 +257,12 @@ private _fn_startExtractionDefense = { ] call BIS_fnc_respawnTickets; missionNamespace setVariable ["BLWK_numRespawnTickets",0,true]; - [false,NUMBER_OF_ENEMIES] remoteExec ["BLWK_fnc_createStdWaveInfantry",BLWK_theAIHandlerOwnerID]; + [ + missionConfigFile >> "BLWK_waveTypes" >> "normalWaves" >> "standardWave", + NUMBER_OF_ENEMIES + ] call BLWK_fnc_waves_create; + + // [false,NUMBER_OF_ENEMIES] remoteExec ["BLWKs_fnc_createStdWaveInfantry",BLWK_theAIHandlerOwnerID]; [ "SpecialWarning", From 332b9175d16a130b86a0dd2d6c611f43f9f39cc3 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 20:01:55 -0600 Subject: [PATCH 040/133] (#642): added defector wave config and fixed function call for standard wave --- .../fn_defectorWave_generateMenClassnames.sqf | 23 ++++++++++++++++ .../fn_defectorWave_onWaveInit.sqf | 27 +++++++++++++++++++ .../fn_standardWave_onWaveInit.sqf | 4 ++- Headers/descriptionEXT/Wave Types.hpp | 3 ++- Headers/descriptionEXT/functions.hpp | 10 +++++++ 5 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 Functions/Wave Type Libraries/Defector Wave Lib/fn_defectorWave_generateMenClassnames.sqf create mode 100644 Functions/Wave Type Libraries/Defector Wave Lib/fn_defectorWave_onWaveInit.sqf diff --git a/Functions/Wave Type Libraries/Defector Wave Lib/fn_defectorWave_generateMenClassnames.sqf b/Functions/Wave Type Libraries/Defector Wave Lib/fn_defectorWave_generateMenClassnames.sqf new file mode 100644 index 00000000..94bfa385 --- /dev/null +++ b/Functions/Wave Type Libraries/Defector Wave Lib/fn_defectorWave_generateMenClassnames.sqf @@ -0,0 +1,23 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_defectorWave_generateMenClassnames + +Description: + Gets the defector list of available men classes. + +Parameters: + NONE + +Returns: + - An array of classNames + +Examples: + (begin example) + private _availableClasses = call BLWK_fnc_standardWave_generateMenClassnames; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_standardWave_generateMenClassnames"; + +BLWK_friendlyFaction_menClasses diff --git a/Functions/Wave Type Libraries/Defector Wave Lib/fn_defectorWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Defector Wave Lib/fn_defectorWave_onWaveInit.sqf new file mode 100644 index 00000000..3526f39c --- /dev/null +++ b/Functions/Wave Type Libraries/Defector Wave Lib/fn_defectorWave_onWaveInit.sqf @@ -0,0 +1,27 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_defectorWave_onWaveInit + +Description: + The on wave init for defector waves. + +Parameters: + NONE + +Returns: + NOTHING + +Examples: + (begin example) + call BLWK_fnc_defectorWave_onWaveInit; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_defectorWave_onWaveInit"; + +private _startingWaveUnits = call BLWK_fnc_getMustKillList; +[_startingWaveUnits,true] call BLWK_fnc_standardWave_vehicles; + + +nil diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveInit.sqf index 3ef02f92..9b91d0b2 100644 --- a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveInit.sqf +++ b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveInit.sqf @@ -18,8 +18,10 @@ Examples: Author(s): Ansible2 ---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_standardWave_onWaveInit"; + private _startingWaveUnits = call BLWK_fnc_getMustKillList; -[_startingWaveUnits] call BLWK_fnc_stdEnemyVehicles; +[_startingWaveUnits] call BLWK_fnc_standardWave_vehicles; nil diff --git a/Headers/descriptionEXT/Wave Types.hpp b/Headers/descriptionEXT/Wave Types.hpp index 44de0bbd..3dc170af 100644 --- a/Headers/descriptionEXT/Wave Types.hpp +++ b/Headers/descriptionEXT/Wave Types.hpp @@ -59,8 +59,9 @@ class BLWK_waveTypes }; class defectorWave : standardWave { - onSelected = "remoteExecCall ['BLWK_fnc_handleDefectorWave',BLWK_theAIHandlerOwnerID]"; + generateMenClassnames = "BLWK_fnc_defectorWave_generateMenClassnames"; weightVariable = "BLWK_defectorWaveWeight"; + onWaveInit = "BLWK_fnc_defectorWave_onWaveInit"; }; }; diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 66a0e21d..88742ebb 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -467,6 +467,16 @@ class BLWK class handleParatrooperWave {}; }; + + class DefectorWaveLib + { + file = "Functions\Wave Type Libraries\Defector Wave Lib"; + class defectorWave_generateMenClassnames + {}; + class defectorWave_onWaveInit + {}; + }; + class StandardWaveLib { file = "Functions\Wave Type Libraries\Standard Wave Lib"; From b2afc5342a6c04b8f76ce3c630433a7bd335d6ba Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 20:13:19 -0600 Subject: [PATCH 041/133] (#642): reconfigured paratrooper wave --- .../fn_paratrooperWave_onWaveInit.sqf | 87 +++++++++++++++++++ .../fn_handleParatrooperWave.sqf | 78 ----------------- Headers/descriptionEXT/Wave Types.hpp | 2 +- Headers/descriptionEXT/functions.hpp | 8 +- 4 files changed, 92 insertions(+), 83 deletions(-) create mode 100644 Functions/Wave Type Libraries/Paratrooper Wave Lib/fn_paratrooperWave_onWaveInit.sqf delete mode 100644 Functions/Wave Type Libraries/Paratrooper Wave Library/fn_handleParatrooperWave.sqf diff --git a/Functions/Wave Type Libraries/Paratrooper Wave Lib/fn_paratrooperWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Paratrooper Wave Lib/fn_paratrooperWave_onWaveInit.sqf new file mode 100644 index 00000000..0e9b1c5c --- /dev/null +++ b/Functions/Wave Type Libraries/Paratrooper Wave Lib/fn_paratrooperWave_onWaveInit.sqf @@ -0,0 +1,87 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_paratrooperWave_onWaveInit + +Description: + The on wave init for paratrooper waves. + +Parameters: + NONE + +Returns: + NOTHING + +Examples: + (begin example) + call BLWK_fnc_paratrooperWave_onWaveInit; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_paratrooperWave_onWaveInit"; + +#define FLY_IN_HEIGHT 200 +#define APPROACH_DIRECTION -1 +#define NUMBER_OF_UNITS_TO_DROP -1 + +private _startingWaveUnits = call BLWK_fnc_getMustKillList; +private _unitCount = count _startingWaveUnits; +private _dropVehicleClass = selectRandom ([4] call BLWK_fnc_getEnemyVehicleClasses); +private _vehicleCargoCapacity = ([_dropVehicleClass,true] call BIS_fnc_crewCount) - ([_dropVehicleClass,false] call BIS_fnc_crewCount); + +private "_numberOfUnitsToDrop"; +private _startingUnitsCount = count _startingWaveUnits; +if (_startingUnitsCount < MAX_NUM_PARAS) then { + _numberOfUnitsToDrop = _startingUnitsCount; +} else { + _numberOfUnitsToDrop = MAX_NUM_PARAS; +}; + +// if everyone fits into one vehicle then just exit with one vehicle spawn +if (_numberOfUnitsToDrop <= _vehicleCargoCapacity) exitWith { + private _dropZone = [BLWK_mainCrate,DROP_AREA_RADIUS] call CBAP_fnc_randPos; + [ + _dropZone, + _startingWaveUnits, + _dropVehicleClass, + NUMBER_OF_UNITS_TO_DROP, + APPROACH_DIRECTION, + FLY_IN_HEIGHT, + OPFOR + ] spawn KISKA_fnc_paratroopers; +}; + + +private _parasAllocated = false; +private _startCount = 0; +private _numUnitsAllocated = 0; +while {!_parasAllocated} do { + // get units to put into vehicle + private _unitsToDropForStick = _startingWaveUnits select [_startCount,_vehicleCargoCapacity]; + + // drop around The Crate + private _dropZoneForStick = [BLWK_mainCrate,DROP_AREA_RADIUS] call CBAP_fnc_randPos; + [ + _dropZoneForStick, + _unitsToDropForStick, + _dropVehicleClass, + NUMBER_OF_UNITS_TO_DROP, + APPROACH_DIRECTION, + FLY_IN_HEIGHT, + OPFOR + ] spawn KISKA_fnc_paratroopers; + + // check if the amount to drop has been reached + _numUnitsAllocated = _numUnitsAllocated + _vehicleCargoCapacity; + if (_numUnitsAllocated >= _numberOfUnitsToDrop) then { + _parasAllocated = true; + } else { + // update select start count + _startCount = _numUnitsAllocated - 1; // want actual array index + }; + + sleep 5; +}; + + +nil diff --git a/Functions/Wave Type Libraries/Paratrooper Wave Library/fn_handleParatrooperWave.sqf b/Functions/Wave Type Libraries/Paratrooper Wave Library/fn_handleParatrooperWave.sqf deleted file mode 100644 index 4c31a996..00000000 --- a/Functions/Wave Type Libraries/Paratrooper Wave Library/fn_handleParatrooperWave.sqf +++ /dev/null @@ -1,78 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_handleParatrooperWave - -Description: - This is simply an alias for the below functions. It is used to exec - both on whomever the AI handler is without using multiple remoteExecs - - Executed from "BLWK_fnc_spawnWaveEnemies" - -Parameters: - NONE - -Returns: - NOTHING - -Examples: - (begin example) - - [] spawn BLWK_fnc_handleParatrooperWave; - - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -#define MAX_NUM_PARAS 14 -#define DROP_AREA_RADIUS 50 - -if (!canSuspend) exitWith { - ["Needs to be run in scheduled, exiting to scheduled...",true] call KISKA_fnc_log; - [] spawn BLWK_fnc_handleParatrooperWave; -}; - -private _startingWaveUnits = call BLWK_fnc_createStdWaveInfantry; - -private _unitCount = count _startingWaveUnits; -private _dropVehicleClass = selectRandom ([4] call BLWK_fnc_getEnemyVehicleClasses); -private _vehicleCargoCapacity = ([_dropVehicleClass,true] call BIS_fnc_crewCount) - ([_dropVehicleClass,false] call BIS_fnc_crewCount); - -private "_numberOfUnitsToDrop"; -private _startingUnitsCount = count _startingWaveUnits; -if (_startingUnitsCount < MAX_NUM_PARAS) then { - _numberOfUnitsToDrop = _startingUnitsCount; -} else { - _numberOfUnitsToDrop = MAX_NUM_PARAS; -}; - -// if everyone fits into one vehicle then just exit with one vehicle spawn -if (_numberOfUnitsToDrop <= _vehicleCargoCapacity) exitWith { - private _dropZone = [BLWK_mainCrate,DROP_AREA_RADIUS] call CBAP_fnc_randPos; - [_dropZone,_startingWaveUnits,_dropVehicleClass,-1,-1,200,OPFOR] spawn KISKA_fnc_paratroopers; -}; - - -private _parasAllocated = false; -private _startCount = 0; -private _unitsToDrop_temp = []; -private _numUnitsAllocated = 0; -private "_dropZone_temp"; -while {!_parasAllocated} do { - // get units to put into vehicle - _unitsToDrop_temp = _startingWaveUnits select [_startCount,_vehicleCargoCapacity]; - - // drop around The Crate - _dropZone_temp = [BLWK_mainCrate,DROP_AREA_RADIUS] call CBAP_fnc_randPos; - [_dropZone_temp,_unitsToDrop_temp,_dropVehicleClass,-1,-1,200,OPFOR] spawn KISKA_fnc_paratroopers; - - // check if the amount to drop has been reached - _numUnitsAllocated = _numUnitsAllocated + _vehicleCargoCapacity; - if (_numUnitsAllocated >= _numberOfUnitsToDrop) then { - _parasAllocated = true; - } else { - // update select start count - _startCount = _numUnitsAllocated - 1; // want actual array index - }; - - sleep 5; -}; diff --git a/Headers/descriptionEXT/Wave Types.hpp b/Headers/descriptionEXT/Wave Types.hpp index 3dc170af..b03e09cd 100644 --- a/Headers/descriptionEXT/Wave Types.hpp +++ b/Headers/descriptionEXT/Wave Types.hpp @@ -54,7 +54,7 @@ class BLWK_waveTypes }; class paratrooperWave : standardWave { - onSelected = "remoteExecCall ['BLWK_fnc_handleParatrooperWave',BLWK_theAIHandlerOwnerID]"; + onWaveInit = "BLWK_fnc_paratrooperWave_onWaveInit"; weightVariable = "BLWK_paratrooperWaveWeight"; }; class defectorWave : standardWave diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 88742ebb..0e54c75d 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -460,11 +460,11 @@ class BLWK class overrunTheCrateWave {}; }; - - class ParatrooperWaveLibrary + + class ParatrooperWaveLib { - file = "Functions\Wave Type Libraries\Paratrooper Wave Library"; - class handleParatrooperWave + file = "Functions\Wave Type Libraries\Paratrooper Wave Lib"; + class paratrooperWave_onWaveInit {}; }; From 53da81f6528e21e27d760baf258bfea5d47e26ad Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 9 Jul 2023 21:21:12 -0600 Subject: [PATCH 042/133] (#642): replaced suicide wave with new wave system --- .../fn_suicideWave_bomberLoop.sqf | 52 +++++++++++ .../fn_suicideWave_explodeBomber.sqf | 45 ++++++++++ .../fn_suicideWave_onWaveInit.sqf | 90 +++++++++++++++++++ .../fn_suicideWave_playBomberAudio.sqf} | 0 .../fn_createSuicideWave.sqf | 75 ---------------- .../fn_explodeSuicideBomberEvent.sqf | 41 --------- .../fn_handleSuicideWave.sqf | 27 ------ .../fn_suicideBomberLoop.sqf | 44 --------- Headers/descriptionEXT/Wave Types.hpp | 2 +- Headers/descriptionEXT/functions.hpp | 28 +++--- 10 files changed, 201 insertions(+), 203 deletions(-) create mode 100644 Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_bomberLoop.sqf create mode 100644 Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_explodeBomber.sqf create mode 100644 Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_onWaveInit.sqf rename Functions/Wave Type Libraries/{Suicide Wave Library/fn_playBomberAudio.sqf => Suicide Wave Lib/fn_suicideWave_playBomberAudio.sqf} (100%) delete mode 100644 Functions/Wave Type Libraries/Suicide Wave Library/fn_createSuicideWave.sqf delete mode 100644 Functions/Wave Type Libraries/Suicide Wave Library/fn_explodeSuicideBomberEvent.sqf delete mode 100644 Functions/Wave Type Libraries/Suicide Wave Library/fn_handleSuicideWave.sqf delete mode 100644 Functions/Wave Type Libraries/Suicide Wave Library/fn_suicideBomberLoop.sqf diff --git a/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_bomberLoop.sqf b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_bomberLoop.sqf new file mode 100644 index 00000000..492d0824 --- /dev/null +++ b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_bomberLoop.sqf @@ -0,0 +1,52 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_suicideWave_bomberLoop + +Description: + Starts the loop that checks a bombers surroundings to see if they should explode. + + Also plays their weird audio. + +Parameters: + 0: _bomber : - The suicide bomber + +Returns: + NOTHING + +Examples: + (begin example) + [myBomber] spawn BLWK_fnc_suicideWave_bomberLoop; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_suicideWave_bomberLoop"; + +if (!canSuspend) exitWith { + _this spawn BLWK_fnc_suicideWave_bomberLoop; + nil +}; + +params ["_bomber"]; + +private ["_players","_nearPlayer"]; +private _bomberDistanceToBlow = random [10,15,20]; +while {alive _bomber} do { + _players = call CBAP_fnc_players; + + [_bomber] remoteExec ["BLWK_fnc_suicideWave_playBomberAudio",_players]; + + _nearPlayer = _players findIf { + (_bomber distance2D _x) <= _bomberDistanceToBlow + }; + + private _aPlayerIsNear = _nearPlayer isNotEqualTo -1; + if (_aPlayerIsNear OR {(_bomber distance2D BLWK_mainCrate) <= 10}) exitWith { + [_bomber] call BLWK_fnc_suicideWave_explodeBomber; + }; + + sleep 3; +}; + + +nil diff --git a/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_explodeBomber.sqf b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_explodeBomber.sqf new file mode 100644 index 00000000..c81a251a --- /dev/null +++ b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_explodeBomber.sqf @@ -0,0 +1,45 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_suicideWave_explodeBomber + +Description: + Creates the explosion at a given unit's position for to look like a suicide bomb + +Parameters: + 0: _bomber : - The suicide bomber + +Returns: + NOTHING + +Examples: + (begin example) + [mySuicideBomber] call BLWK_fnc_suicideWave_explodeBomber; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_suicideWave_explodeBomber"; + +params ["_bomber"]; + +if (isNull _bomber) exitWith {}; + +private _explosiveType = selectRandom [ + "DemoCharge_Remote_Ammo_Scripted", + "SatchelCharge_Remote_Ammo_Scripted", + "ClaymoreDirectionalMine_Remote_Ammo_Scripted" +]; + +private _explosive = _explosiveType createVehicle (getPosATLVisual _bomber); +_explosive setDamage 1; +// give time for BLWK_fnc_event_killedEnemy to execute +[ + { + deleteVehicle (_this select 0); + }, + [_bomber], + 0.5 +] call CBAP_fnc_waitAndExecute; + + +nil diff --git a/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_onWaveInit.sqf new file mode 100644 index 00000000..3a400e3d --- /dev/null +++ b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_onWaveInit.sqf @@ -0,0 +1,90 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_suicideWave_onWaveInit + +Description: + The on wave init for suicide waves. + +Parameters: + NONE + +Returns: + NOTHING + +Examples: + (begin example) + call BLWK_fnc_suicideWave_onWaveInit; + (end) + +Author(s): + Hilltop(Willtop) & omNomios, + Modified by: Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_suicideWave_onWaveInit"; + +#define VEST_CHARGE "DemoCharge_Remote_Ammo" + +private _startingWaveUnits = call BLWK_fnc_getMustKillList; +private _numberOfBombers = round (count _startingWaveUnits / 4); +private _bombers = _startingWaveUnits select [0,_numberOfBombers]; + +_bombers apply { + private _unit = _unit; + private _unitGroup = group _unit; + + _unitGroup setBehaviour "CARELESS"; + + private _owner = groupOwner _unitGroup; + [_unitGroup,(getPosATL BLWK_mainCrate)] remoteExec ["move", _owner]; + [_unitGroup,"full"] remoteExec ["setSpeedMode", _owner]; + + removeAllWeapons _unit; + removeHeadgear _unit; + removeVest _unit; + _unit addVest "V_HarnessOGL_brn"; + _unit addHeadgear "H_ShemagOpen_khk"; + + private _unitPosition = position _unit; + private _bombs = [ + [ + [-0.1, 0.1, 0.15], + [ [0.5, 0.5, 0], [-0.5, 0.5, 0] ] + ], + [ + [0.1, 0.1, 0.15],, + [ [0.5, -0.5, 0], [0.5, 0.5, 0] ] + ], + [ + [0, 0.15, 0.15], + [ [1, 0, 0], [0, 1, 0] ] + ] + ] apply { + _x params ["_attachmentPoint","_vectorDirAndUp"]; + + private _explosive = VEST_CHARGE createVehicle _unitPosition; + _explosive attachTo [_unit, _attachmentPoint, "Pelvis"]; + _explosive setVectorDirAndUp _vectorDirAndUp; + + _explosive + }; + _unit setVariable ["BLWK_suicideBombs",_bombs]; + + + _unit addEventHandler ["KILLED",{ + params ["_bomber"]; + [_bomber] call BLWK_fnc_suicideWave_explodeBomber; + }]; + + _unit addEventHandler ["Deleted", { + params ["_unit"]; + + (_unit getVariable ["BLWK_suicideBombs",[]]) apply { + deleteVehicle _unit; + }; + }]; + + + [_unit] spawn BLWK_fnc_suicideWave_bomberLoop; +}; + + +nil diff --git a/Functions/Wave Type Libraries/Suicide Wave Library/fn_playBomberAudio.sqf b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_playBomberAudio.sqf similarity index 100% rename from Functions/Wave Type Libraries/Suicide Wave Library/fn_playBomberAudio.sqf rename to Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_playBomberAudio.sqf diff --git a/Functions/Wave Type Libraries/Suicide Wave Library/fn_createSuicideWave.sqf b/Functions/Wave Type Libraries/Suicide Wave Library/fn_createSuicideWave.sqf deleted file mode 100644 index 3ff07b43..00000000 --- a/Functions/Wave Type Libraries/Suicide Wave Library/fn_createSuicideWave.sqf +++ /dev/null @@ -1,75 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_createSuicideWave - -Description: - creates the suicide bombers and sends them towards The Crate - - Executed from "BLWK_fnc_handleSuicideWave" - -Parameters: - 0: _unitsToWorkWith : - Units to potentially turn into bombers - -Returns: - NOTHING - -Examples: - (begin example) - - [unitsArray] call BLWK_fnc_createSuicideWave; - - (end) - -Author(s): - Hilltop(Willtop) & omNomios, - Modified by: Ansible2 // Cipher ----------------------------------------------------------------------------- */ -#define VEST_CHARGE "DemoCharge_Remote_Ammo" - -params ["_unitsToWorkWith"]; - -private _numberOfBombers = round (count _unitsToWorkWith / 4); -private _bombersArray = _unitsToWorkWith select [0,_numberOfBombers]; - -private "_unitGroupTemp"; -_bombersArray apply { - _unitGroupTemp = group _x; - _unitGroupTemp setBehaviour "CARELESS"; - [_unitGroupTemp,(getPosATL BLWK_mainCrate)] remoteExec ["move", groupOwner _unitGroupTemp]; - [_unitGroupTemp,"full"] remoteExec ["setSpeedMode",groupOwner _unitGroupTemp]; - - removeAllWeapons _x; - - // added suicide uniform by KillZoneKid - removeHeadgear _x; - removeVest _x; - _x addVest "V_HarnessOGL_brn"; - _x addHeadgear "H_ShemagOpen_khk"; - - private _unitPosition = position _x; - - private _expl1 = VEST_CHARGE createVehicle _unitPosition; - _expl1 attachTo [_x, [-0.1, 0.1, 0.15], "Pelvis"]; - _expl1 setVectorDirAndUp [ [0.5, 0.5, 0], [-0.5, 0.5, 0] ]; - - private _expl2 = VEST_CHARGE createVehicle _unitPosition; - _expl2 attachTo [_x, [0, 0.15, 0.15], "Pelvis"]; - _expl2 setVectorDirAndUp [ [1, 0, 0], [0, 1, 0] ]; - - private _expl3 = VEST_CHARGE createVehicle _unitPosition; - _expl3 attachTo [_x, [0.1, 0.1, 0.15], "Pelvis"]; - _expl3 setVectorDirAndUp [ [0.5, -0.5, 0], [0.5, 0.5, 0] ]; - // end suicide uniform - - _x addEventHandler ["KILLED",{ - [_this select 0] call BLWK_fnc_explodeSuicideBomberEvent; - }]; - - _x setVariable ["BLWK_suicideBombs",[_expl1,_expl2,_expl3]]; - _x addEventHandler ["Deleted", { - ((_this select 0) getVariable ["BLWK_suicideBombs",[]]) apply { - deleteVehicle _x; - }; - }]; - - [_x] spawn BLWK_fnc_suicideBomberLoop; -}; diff --git a/Functions/Wave Type Libraries/Suicide Wave Library/fn_explodeSuicideBomberEvent.sqf b/Functions/Wave Type Libraries/Suicide Wave Library/fn_explodeSuicideBomberEvent.sqf deleted file mode 100644 index 6ebc1791..00000000 --- a/Functions/Wave Type Libraries/Suicide Wave Library/fn_explodeSuicideBomberEvent.sqf +++ /dev/null @@ -1,41 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_explodeSuicideBomberEvent - -Description: - Creates the explosion at a suicide bomber's position - - Executed from the event added in "BLWK_fnc_createSuicideWave" & "BLWK_fnc_suicideBomberLoop" - -Parameters: - 0: _bomber : - The suicide bomber - -Returns: - NOTHING - -Examples: - (begin example) - - [mySuicideBomber,0] call BLWK_fnc_explodeSuicideBomberEvent; - - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -params ["_bomber"]; - -if (isNull _bomber) exitWith {}; - -private _explosiveType = selectRandom [ - "DemoCharge_Remote_Ammo_Scripted", - "SatchelCharge_Remote_Ammo_Scripted", - "ClaymoreDirectionalMine_Remote_Ammo_Scripted" -]; - -private _explosive = _explosiveType createVehicle (getPosATLVisual _bomber); - -_explosive setDamage 1; -[_bomber] spawn { - sleep 0.5; // give time for BLWK_fnc_handleKillEventPlayer to execute - deleteVehicle (_this select 0); -}; diff --git a/Functions/Wave Type Libraries/Suicide Wave Library/fn_handleSuicideWave.sqf b/Functions/Wave Type Libraries/Suicide Wave Library/fn_handleSuicideWave.sqf deleted file mode 100644 index a35f7896..00000000 --- a/Functions/Wave Type Libraries/Suicide Wave Library/fn_handleSuicideWave.sqf +++ /dev/null @@ -1,27 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_handleSuicideWave - -Description: - This is simply an alias for the below functions. It is used to exec - both on whomever the AI handler is without using multiple remoteExecs - - Executed from "BLWK_fnc_spawnWaveEnemies" - -Parameters: - NONE - -Returns: - NOTHING - -Examples: - (begin example) - - call BLWK_fnc_handleSuicideWave; - - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -private _startingWaveUnits = call BLWK_fnc_createStdWaveInfantry; -[_startingWaveUnits] call BLWK_fnc_createSuicideWave; \ No newline at end of file diff --git a/Functions/Wave Type Libraries/Suicide Wave Library/fn_suicideBomberLoop.sqf b/Functions/Wave Type Libraries/Suicide Wave Library/fn_suicideBomberLoop.sqf deleted file mode 100644 index e1362900..00000000 --- a/Functions/Wave Type Libraries/Suicide Wave Library/fn_suicideBomberLoop.sqf +++ /dev/null @@ -1,44 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_suicideBomberLoop - -Description: - Starts the loop that checks a bombers surroundings to see if they should explode. - Also plays their weird audio. - - Executed from "BLWK_fnc_createSuicideWave" - -Parameters: - NONE - -Returns: - NOTHING - -Examples: - (begin example) - - [myBomber] spawn BLWK_fnc_suicideBomberLoop; - - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -if (!canSuspend) exitWith {}; - -params ["_bomber"]; - -private ["_players","_nearPlayer"]; -private _bomberDistanceToBlow = random [10,15,20]; -while {alive _bomber} do { - _players = call CBAP_fnc_players; - - [_bomber] remoteExec ["BLWK_fnc_playBomberAudio",_players]; - - _nearPlayer = _players findIf {(_bomber distance2D _x) <= _bomberDistanceToBlow}; - - if (_nearPlayer isNotEqualTo -1 OR {_bomber distance2D BLWK_mainCrate <= 10}) exitWith { - [_bomber] call BLWK_fnc_explodeSuicideBomberEvent; - }; - - sleep 3; -}; diff --git a/Headers/descriptionEXT/Wave Types.hpp b/Headers/descriptionEXT/Wave Types.hpp index b03e09cd..8302e7e6 100644 --- a/Headers/descriptionEXT/Wave Types.hpp +++ b/Headers/descriptionEXT/Wave Types.hpp @@ -69,7 +69,7 @@ class BLWK_waveTypes { class suicideWave { - onSelected = "remoteExecCall ['BLWK_fnc_handleSuicideWave',BLWK_theAIHandlerOwnerID]"; + onWaveInit = "BLWK_fnc_suicideWave_onWaveInit"; creationNotificationTemplate = SPECIAL_WARNING_TEMPLATE; notificationText = "Enemy Suicide Bombers Are Incoming!"; // The "toggleVariable" is a name of a missionNamespace variable (on the server) diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 0e54c75d..4bcf7388 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -461,6 +461,19 @@ class BLWK {}; }; + class SuicideWaveLib + { + file = "Functions\Wave Type Libraries\Suicide Wave Lib"; + class suicideWave_bomberLoop + {}; + class suicideWave_explodeBomber + {}; + class suicideWave_playBomberAudio + {}; + class suicideWave_onWaveInit + {}; + }; + class ParatrooperWaveLib { file = "Functions\Wave Type Libraries\Paratrooper Wave Lib"; @@ -501,21 +514,6 @@ class BLWK {}; }; - class SuicideWaveLibrary - { - file = "Functions\Wave Type Libraries\Suicide Wave Library"; - class createSuicideWave - {}; - class explodeSuicideBomberEvent - {}; - class handleSuicideWave - {}; - class playBomberAudio - {}; - class suicideBomberLoop - {}; - }; - class Waves { file = "Functions\Waves"; From 92803b9b1dcc92af7d05be6ec79c249876bd9f13 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Mon, 10 Jul 2023 20:15:40 -0600 Subject: [PATCH 043/133] (#642): replaced BLWK_fnc_endWave --- Functions/Waves/fn_endWave.sqf | 124 ----------------------- Functions/Waves/fn_waves_end.sqf | 141 +++++++++++++++++++++++++++ Headers/descriptionEXT/functions.hpp | 4 +- 3 files changed, 143 insertions(+), 126 deletions(-) delete mode 100644 Functions/Waves/fn_endWave.sqf create mode 100644 Functions/Waves/fn_waves_end.sqf diff --git a/Functions/Waves/fn_endWave.sqf b/Functions/Waves/fn_endWave.sqf deleted file mode 100644 index b0a9d5f1..00000000 --- a/Functions/Waves/fn_endWave.sqf +++ /dev/null @@ -1,124 +0,0 @@ -#include "..\..\Headers\String Constants.hpp" -#include "..\..\Headers\Stalker Global Strings.hpp" -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_endWave - -Description: - Notifies players of wave end and completes mission if final wave done. - Also revives downed players and startst the countdown to the next wave. - - Executed from "BLWK_fnc_startWave" - -Parameters: - NONE - -Returns: - NOTHING - -Examples: - (begin example) - [] spawn BLWK_fnc_endWave; - (end) - -Author(s): - Hilltop(Willtop) & omNomios, - Modified by: Ansible2 // Cipher ----------------------------------------------------------------------------- */ -scriptName "BLWK_fnc_endWave"; - -if (!isServer OR {!canSuspend}) exitWith {}; - -private _currentWaveTypeConfig = localNamespace getVariable ["BLWK_currentWaveConfig",configNull]; -private _waveEndEvent = getText(_currentWaveTypeConfig >> "onWaveEnd"); -if (_waveEndEvent isNotEqualTo "") then { - call compileFinal _waveEndEvent; -}; - - -// check for mission complete -private _endMission = false; -if (BLWK_currentWaveNumber isEqualTo BLWK_maxNumWaves) then { - if (BLWK_extractionEnabled) then { - call BLWK_fnc_callingForExtraction; - - } else { - _endMission = true; - - }; -}; - -if (_endMission) exitWith { - "End2" call BIS_fnc_endMissionServer; -}; - - - -missionNamespace setVariable ["BLWK_inBetweenWaves",true,true]; -private _players = call CBAP_fnc_players; -[TASK_COMPLETE_TEMPLATE,["",COMPLETED_WAVE_NOTIFICATION(str BLWK_currentWaveNumber)]] remoteExec ["BIS_fnc_showNotification",_players]; - - -// handle changing of factions during a mission -private _factionQueue = localNamespace getVariable ["BLWK_factionChangeQueue",[]]; -if (_factionQueue isNotEqualTo []) then { - [true,_factionQueue] call BLWK_fnc_setupFactionMaps; - localNamespace setVariable ["BLWK_factionChangeQueue",[]]; - [true,_factionQueue] remoteExec ["BLWK_fnc_setupFactionMaps",-2]; -}; - - -/* ---------------------------------------------------------------------------- - Revive downed players ----------------------------------------------------------------------------- */ -private "_playerTemp"; -_players apply { - _playerTemp = _x; - - // clear all stalkers counts - _playerTemp setVariable [STALKER_COUNT_VAR,0,BLWK_theAIHandlerOwnerID]; - - - if (!alive _playerTemp) then { - // add a single respawn ticket for each dead unit - private _respawns = [BLUFOR,1] call BIS_fnc_respawnTickets; - missionNamespace setVariable ["BLWK_numRespawnTickets",_respawns,true]; - [0] remoteExecCall ["setPlayerRespawnTime",_playerTemp]; - [_playerTemp] remoteExecCall ["forceRespawn",_playerTemp]; - - } else { - - if (lifeState _playerTemp == "INCAPACITATED") then { - if (BLWK_dontUseRevive) then { - if (BLWK_ACELoaded) then { - [_playerTemp] remoteExecCall ["ace_medical_treatment_fnc_fullHealLocal",_playerTemp]; - }; - } else { - ["BLWK_reviveOnStateVar", 1, _playerTemp] remoteExecCall ["BIS_fnc_reviveOnState",_playerTemp]; - }; - }; - - }; -}; - - -/* ---------------------------------------------------------------------------- - Clear dropped items ----------------------------------------------------------------------------- */ -private _clearDroppedItems = false; -if (((BLWK_currentWaveNumber + 1) mod BLWK_deleteDroppedItemsEvery) isEqualTo 0) then { - _clearDroppedItems = true; - - // don't send the notification every wave if items are cleared every time. Would be annoying. - if (BLWK_deleteDroppedItemsEvery > 1) then { - remoteExecCall ["BLWK_fnc_hintDroppedDelete",BLWK_allClientsTargetID]; - }; -}; - - -// invoke wave end event -[missionNamespace,"BLWK_onWaveEnd"] remoteExecCall ["BIS_fnc_callScriptedEventHandler",0]; - -call BLWK_fnc_startWaveCountdown; - - -[_clearDroppedItems] spawn BLWK_fnc_startWave; diff --git a/Functions/Waves/fn_waves_end.sqf b/Functions/Waves/fn_waves_end.sqf new file mode 100644 index 00000000..38cf9544 --- /dev/null +++ b/Functions/Waves/fn_waves_end.sqf @@ -0,0 +1,141 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_waves_end + +Description: + Notifies players of wave end and completes mission if final wave done. + Also revives downed players and startst the countdown to the next wave. + +Parameters: + NONE + +Returns: + NOTHING + +Examples: + (begin example) + call BLWK_fnc_waves_end; + (end) + +Author(s): + Hilltop(Willtop) & omNomios, + Modified by: Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_waves_end"; + +#define COMPLETED_WAVE_NOTIFICATION(WAVE_NUM_STRING) ("Wave " + WAVE_NUM_STRING + " Complete") +#define TASK_COMPLETE_TEMPLATE "TaskSucceeded" + +if (!isServer) exitWith {}; + +private _waveConfig = localNamespace getVariable ["BLWK_currentWaveConfig",configNull]; +private _waveEndEvent = [ + _waveConfig, + "onWaveEnd" +] call BLWK_fnc_waves_getFunctionFromConfig + + +if (_waveEndEvent isNotEqualTo {}) then { + call _waveEndEvent; +}; + +/* ---------------------------------------------------------------------------- + Check mission end +---------------------------------------------------------------------------- */ +private _endMission = false; +if (BLWK_currentWaveNumber isEqualTo BLWK_maxNumWaves) then { + if (BLWK_extractionEnabled) then { + call BLWK_fnc_callingForExtraction; + } else { + _endMission = true; + }; +}; + +if (_endMission) exitWith { + "End2" call BIS_fnc_endMissionServer; +}; + + +/* ---------------------------------------------------------------------------- + Notify Players +---------------------------------------------------------------------------- */ +missionNamespace setVariable ["BLWK_inBetweenWaves",true,true]; +private _players = call CBAP_fnc_players; +[ + TASK_COMPLETE_TEMPLATE, + ["",COMPLETED_WAVE_NOTIFICATION(str BLWK_currentWaveNumber)] +] remoteExec ["BIS_fnc_showNotification",_players]; + + +/* ---------------------------------------------------------------------------- + Handle faction changes +---------------------------------------------------------------------------- */ +private _factionQueue = localNamespace getVariable ["BLWK_factionChangeQueue",[]]; +if (_factionQueue isNotEqualTo []) then { + [true,_factionQueue] call BLWK_fnc_setupFactionMaps; + localNamespace setVariable ["BLWK_factionChangeQueue",[]]; + [true,_factionQueue] remoteExec ["BLWK_fnc_setupFactionMaps",-2]; +}; + + +/* ---------------------------------------------------------------------------- + Revive downed players +---------------------------------------------------------------------------- */ +_players apply { + // clear all stalkers counts + _x setVariable [STALKER_COUNT_VAR,0,BLWK_theAIHandlerOwnerID]; + + if (!alive _x) then { + // add a single respawn ticket for each dead unit + private _respawns = [BLUFOR,1] call BIS_fnc_respawnTickets; + missionNamespace setVariable ["BLWK_numRespawnTickets",_respawns,true]; + [0] remoteExecCall ["setPlayerRespawnTime",_x]; + [_x] remoteExecCall ["forceRespawn",_x]; + + } else { + + if (lifeState _x == "INCAPACITATED") then { + if (BLWK_dontUseRevive) then { + if (BLWK_ACELoaded) then { + [_x] remoteExecCall ["ace_medical_treatment_fnc_fullHealLocal",_x]; + }; + } else { + ["BLWK_reviveOnStateVar", 1, _x] remoteExecCall ["BIS_fnc_reviveOnState",_x]; + }; + }; + + }; +}; + + +/* ---------------------------------------------------------------------------- + Clear dropped items +---------------------------------------------------------------------------- */ +private _clearDroppedItems = false; +if (((BLWK_currentWaveNumber + 1) mod BLWK_deleteDroppedItemsEvery) isEqualTo 0) then { + _clearDroppedItems = true; + + // don't send the notification every wave if items are cleared every time. Would be annoying. + if (BLWK_deleteDroppedItemsEvery > 1) then { + remoteExecCall ["BLWK_fnc_hintDroppedDelete",BLWK_allClientsTargetID]; + }; +}; + + +// invoke wave end event +[missionNamespace,"BLWK_onWaveEnd"] remoteExecCall ["BIS_fnc_callScriptedEventHandler",0]; + + +/* ---------------------------------------------------------------------------- + Wait for next wave +---------------------------------------------------------------------------- */ +[_clearDroppedItems] spawn { + call BLWK_fnc_startWaveCountdown; + + [ + BLWK_fnc_waves_start, + _this + ] call CBAP_fnc_directCall; +}; + + +nil \ No newline at end of file diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 4bcf7388..9e595f50 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -523,6 +523,8 @@ class BLWK {}; class waves_create {}; + class waves_end + {}; class waves_isCleared {}; @@ -534,8 +536,6 @@ class BLWK {}; class clearMustKillList {}; - class endWave - {}; class getConfigForWave {}; class getMustKillList From 5df7e30db98d88700576a7631037153935ac0f2e Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Mon, 10 Jul 2023 20:16:10 -0600 Subject: [PATCH 044/133] (#642): added wave condition check to BLWK_fnc_getConfigForWave --- Functions/Waves/fn_getConfigForWave.sqf | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/Functions/Waves/fn_getConfigForWave.sqf b/Functions/Waves/fn_getConfigForWave.sqf index 131f3d54..3e88dd24 100644 --- a/Functions/Waves/fn_getConfigForWave.sqf +++ b/Functions/Waves/fn_getConfigForWave.sqf @@ -24,6 +24,8 @@ Author(s): ---------------------------------------------------------------------------- */ scriptName "BLWK_fnc_getConfigForWave"; +#define DEFAULT_WAVE_CONFIG missionConfigFile >> "BLWK_waveTypes" >> "normalWaves" >> "standardWave" + if (!isServer) exitWith {}; /* ---------------------------------------------------------------------------- @@ -58,7 +60,7 @@ private _fn_getNormalWave = { BLWK_normalWaveConfigs selectRandomWeighted _weights }; - missionConfigFile >> "BLWK_waveTypes" >> "normalWaves" >> "standardWave" + DEFAULT_WAVE_CONFIG }; @@ -94,4 +96,22 @@ if (_selectSpecialWave) then { }; +private _waveConditionFunctionName = getText(_waveConfigPath >> "condition"); +if (_waveConditionFunctionName isNotEqualTo "") then { + private _waveConditionFunction = missionNamespace getVariable [_waveConditionFunctionName,{true}]; + if !(call _waveConditionFunction) then { + [ + [ + "Wave condition check failed for: ", + _waveConfigPath, + " with the function: ", + _waveConditionFunctionName, + ". Rerolling for a wave..." + ] + ] call KISKA_fnc_log; + _waveConfigPath = call BLWK_fnc_getConfigForWave; + }; +}; + + _waveConfigPath From a5e9909ac42802bfe7b47abc8176b32644583024 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Mon, 10 Jul 2023 20:17:44 -0600 Subject: [PATCH 045/133] (#642): updated overrun wave to newer system --- .../fn_overrunWave_condition.sqf | 55 ++++++++ ...n_overrunWave_generateManSpawnPosition.sqf | 48 +++++++ .../fn_overrunWave_onWaveEnd.sqf | 17 +++ .../fn_overrunWave_onWaveInit.sqf | 76 +++++++++++ .../fn_handleOverrunWave.sqf | 54 -------- .../fn_overrunTheCrateWave.sqf | 122 ------------------ Headers/String Constants.hpp | 6 +- Headers/descriptionEXT/Wave Types.hpp | 5 +- Headers/descriptionEXT/functions.hpp | 12 +- 9 files changed, 209 insertions(+), 186 deletions(-) create mode 100644 Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_condition.sqf create mode 100644 Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_generateManSpawnPosition.sqf create mode 100644 Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_onWaveEnd.sqf create mode 100644 Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_onWaveInit.sqf delete mode 100644 Functions/Wave Type Libraries/Overrun Wave Library/fn_handleOverrunWave.sqf delete mode 100644 Functions/Wave Type Libraries/Overrun Wave Library/fn_overrunTheCrateWave.sqf diff --git a/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_condition.sqf b/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_condition.sqf new file mode 100644 index 00000000..9aee9f84 --- /dev/null +++ b/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_condition.sqf @@ -0,0 +1,55 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_overrunWave_condition + +Description: + Checks that the play area is has a viable set of opposite ends that both players + and enemies will spawn on either side respectively. + +Parameters: + NONE + +Returns: + - Whether or not the overrun wave can proceed. + +Examples: + (begin example) + private _canBeUsed = call BLWK_fnc_overrunWave_condition; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_overrunWave_condition"; + +#define DIST_BUFFER 50 + +private _distanceToCenter = BLWK_playAreaRadius + DIST_BUFFER; +private _potentialEnemySpawnCenterPosition = []; +private _potentialPlayerSpawnPosition = []; +private _playAreaIsViable = false; +for "_i" from 1 to 18 do { + private _bearing = _i * 10; + _potentialPlayerSpawnPosition = BLWK_playAreaCenter getPos [_distanceToCenter,_bearing]; + if (surfaceIsWater _potentialPlayerSpawnPosition) then { + _potentialPlayerSpawnPosition = []; + + } else { + _potentialEnemySpawnCenterPosition = BLWK_playAreaCenter getPos [_distanceToCenter,_bearing + 180]; + if (surfaceIsWater _potentialEnemySpawnCenterPosition) then { + _potentialPlayerSpawnPosition = []; + _potentialEnemySpawnCenterPosition = []; + } else { + _playAreaIsViable = true; + break; + }; + + }; +}; + +if (_playAreaIsViable) then { + localNamespace setVariable ["BLWK_overrunWave_playerSpawn",_potentialPlayerSpawnPosition]; + localNamespace setVariable ["BLWK_overrunWave_enemySpawnCenter",_potentialEnemySpawnCenterPosition]; +}; + + +_playAreaIsViable diff --git a/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_generateManSpawnPosition.sqf b/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_generateManSpawnPosition.sqf new file mode 100644 index 00000000..050e1621 --- /dev/null +++ b/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_generateManSpawnPosition.sqf @@ -0,0 +1,48 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_overrunWave_generateManSpawnPosition + +Description: + Sets up spawns for overrun wave units to be opposite of the players + +Parameters: + NONE + +Returns: + - A position for a man unit to spawn. + +Examples: + (begin example) + private _position = call BLWK_fnc_overrunWave_generateManSpawnPosition; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_overrunWave_generateManSpawnPosition"; + +#define NUMBER_ENEMY_POSITIONS 5 +#define MAX_ENEMY_DIST 50 +// localNamespace getVariable "BLWK_overrunWave_playerSpawn"; + +private _enemySpawns = localNamespace getVariable ["BLWK_overrunWave_enemySpawns",[]]; + +if (_enemySpawns isEqualTo []) then { + private _enemyCenterPosition = localNamespace getVariable "BLWK_overrunWave_enemySpawnCenter"; + _enemySpawns pushBack _enemyCenterPosition; + while {(count _enemySpawns) < NUMBER_ENEMY_POSITIONS} do { + private _positionToPushBack = [ + _enemyCenterPosition, + 0, + MAX_ENEMY_DIST, + 0, + 0 + ] call BIS_fnc_findSafePos; + + _enemySpawns pushBackUnique _positionToPushBack; + }; + + localNamespace setVariable ["BLWK_overrunWave_enemySpawns",_enemySpawns]; +}; + + +selectRandom _enemySpawns diff --git a/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_onWaveEnd.sqf b/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_onWaveEnd.sqf new file mode 100644 index 00000000..d98721fb --- /dev/null +++ b/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_onWaveEnd.sqf @@ -0,0 +1,17 @@ +localNamespace setVariable ["BLWK_overrunWave_playerSpawn",nil]; +localNamespace setVariable ["BLWK_overrunWave_enemySpawnCenter",nil]; +localNamespace setVariable ["BLWK_overrunWave_enemySpawns",nil]; +localNamespace setVariable ["BLWK_overrunWave_playerBasePosition",nil]; + +missionNamespace setVariable ["BLWK_enforceArea",true,true]; +[true] remoteExecCall ["BLWK_fnc_playAreaEnforcementLoop",BLWK_allClientsTargetId]; + +// make sure crate is in play area +if !(BLWK_mainCrate inArea BLWK_playAreaMarker) then { + BLWK_mainCrate setPos ( + [BLWK_playAreaCenter, 0, 100, 0, 0] call BIS_fnc_findSafePos + ); +}; + + +nil diff --git a/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_onWaveInit.sqf new file mode 100644 index 00000000..3bd81aab --- /dev/null +++ b/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_onWaveInit.sqf @@ -0,0 +1,76 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_overrunWave_onWaveInit + +Description: + The on wave init for overrun waves. + +Parameters: + NONE + +Returns: + NOTHING + +Examples: + (begin example) + call BLWK_fnc_overrunWave_onWaveInit; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_overrunWave_onWaveInit"; + +// store crate position fro moving AI to surround its former place +localNamespace setVariable [ + "BLWK_overrunWave_playerBasePosition", + (getPosATL BLWK_mainCrate) +]; + + +// allow players outside the play area +missionNamespace setVariable ["BLWK_enforceArea",false,true]; + +[ + { + private _playerSpawnPosition = localNamespace getVariable "BLWK_overrunWave_playerSpawn"; + BLWK_mainCrate setPosATL _playerPosition; + + (call CBAP_fnc_players) apply { + // don't teleport players in vehicles + if (isNull (objectParent _x)) then { + _x setPosATL ( + [_playerPosition,15,random 360] call CBAP_fnc_randPos + ); + }; + }; + }, + [], + 2 +] call CBAP_fnc_waitAndExecute; + +private _startingWaveUnits = call BLWK_fnc_getMustKillList; +[ + { + params ["_startingWaveUnits"]; + + private _playerBasePosition = localNamespace getVariable "BLWK_overrunWave_playerBasePosition"; + _startingWaveUnits apply { + private _teleportPosition = [ + _playerBasePosition, + 50, + random 360 + ] call CBAP_fnc_randPos; + + _x setVehiclePosition [_teleportPosition, [], 1, "NONE"]; + }; + + _startingWaveUnits apply { + [group _x,BLWK_playerBasePosition] call BLWK_fnc_stopStalking + }; + }, + [_startingWaveUnits], + 5 +] call CBAP_fnc_waitAndExecute; + + +nil diff --git a/Functions/Wave Type Libraries/Overrun Wave Library/fn_handleOverrunWave.sqf b/Functions/Wave Type Libraries/Overrun Wave Library/fn_handleOverrunWave.sqf deleted file mode 100644 index ad15c2cb..00000000 --- a/Functions/Wave Type Libraries/Overrun Wave Library/fn_handleOverrunWave.sqf +++ /dev/null @@ -1,54 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_handleOverrunWave - -Description: - This is simply an alias for the below functions. It is used to exec - both on whomever the AI handler is without using multiple remoteExecs - - Executed from "BLWK_fnc_spawnWaveEnemies" - -Parameters: - NONE - -Returns: - NOTHING - -Examples: - (begin example) - call BLWK_fnc_handleOverrunWave; - (end) - -Author(s): - Ansible2 // Cipher - - - - units are spawned in at crate position before players are teleported - - Stalker system for enemies has not initialized before the are told to stop stalking ----------------------------------------------------------------------------- */ -private _canDoWave = call BLWK_fnc_overrunTheCrateWave; -private _startingWaveUnits = call BLWK_fnc_createStdWaveInfantry; - -if !(_canDoWave) exitWith {}; - - -[_startingWaveUnits] spawn { - params ["_startingWaveUnits"]; - - waitUntil {missionNamespace getVariable ["BLWK_baseIsClear",false]}; - - private "_positionTemp"; - _startingWaveUnits apply { - _positionTemp = [BLWK_playerBasePosition,50,random 360] call CBAP_fnc_randPos; - _x setVehiclePosition [_positionTemp, [], 1, "NONE"]; - }; - - _startingWaveUnits apply { - waitUntil { - sleep 0.05; - [group _x,BLWK_playerBasePosition] call BLWK_fnc_stopStalking - }; - }; -}; - - -nil \ No newline at end of file diff --git a/Functions/Wave Type Libraries/Overrun Wave Library/fn_overrunTheCrateWave.sqf b/Functions/Wave Type Libraries/Overrun Wave Library/fn_overrunTheCrateWave.sqf deleted file mode 100644 index 17068ed7..00000000 --- a/Functions/Wave Type Libraries/Overrun Wave Library/fn_overrunTheCrateWave.sqf +++ /dev/null @@ -1,122 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_overrunTheCrateWave - -Description: - Adjusts the positions of players and enemies. - - Executed from "BLWK_fnc_handleOverrunWave" - -Parameters: - NONE - -Returns: - - Does play area meet the standards to have an overrun wave - -Examples: - (begin example) - private _canDoWave = call BLWK_fnc_overrunTheCrateWave; - (end) - -Author(s): - Hilltop(Willtop) & omNomios, - Modified by: Ansible2 // Cipher ----------------------------------------------------------------------------- */ -scriptName "BLWK_fnc_overrunTheCrateWave"; - - -#define DIST_BUFFER 50 -#define NUMBER_ENEMY_POSITIONS 5 -#define MAX_ENEMY_DIST 50 -#define ENFORCEMENT_ID "overrunWave_JIP" - -// get opposite sides for players and enemies -private _distanceToCenter = BLWK_playAreaRadius + DIST_BUFFER; -private "_bearing"; -private _enemyCenterPosition = []; -private _playerPosition = []; -private _canExit = false; -for "_i" from 1 to 18 do { - if (_canExit) exitWith {}; - - _bearing = _i * 10; - _playerPosition = BLWK_playAreaCenter getPos [_distanceToCenter,_bearing]; - _playerPosition set [2,0]; - if (surfaceIsWater _playerPosition) then { - _playerPosition = []; - } else { - _enemyCenterPosition = BLWK_playAreaCenter getPos [_distanceToCenter,_bearing + 180]; - _enemyCenterPosition set [2,0]; - if (surfaceIsWater _enemyCenterPosition) then { - _playerPosition = []; - _enemyCenterPosition = []; - } else { - _canExit = true; - }; - }; -}; - -// if the area is not suitable, exit -if (_enemyCenterPosition isEqualTo [] AND {_playerPosition isEqualTo []}) exitWith { - ["Your play area did not meet the requirements for the Overrun Wave type (too much water)"] remoteExecCall ["KISKA_fnc_errorNotification",BLWK_allClientsTargetId]; - false -}; - -// store crate position fro moving AI to surround its former place -BLWK_playerBasePosition = getPosATL BLWK_mainCrate; - - -// Give enemies new spawn positions opposite of players -BLWK_cachedEnemySpawns = +BLWK_infantrySpawnPositions; -private _enemySpawnPositions = []; -_enemySpawnPositions pushBack _enemyCenterPosition; -private "_positionToPushBack"; -while {count _enemySpawnPositions < NUMBER_ENEMY_POSITIONS} do { - _positionToPushBack = [_enemyCenterPosition, 0, MAX_ENEMY_DIST, 0, 0] call BIS_fnc_findSafePos; - _enemySpawnPositions pushBackUnique _positionToPushBack; -}; - -BLWK_infantrySpawnPositions = _enemySpawnPositions; - - -// add scripted event handler to set things back to as they were on wave end -[missionNamespace,"BLWK_onWaveEnd",{ - [missionNamespace,"BLWK_onWaveEnd",_thisScriptedEventHandler] call BIS_fnc_removeScriptedEventHandler; - - BLWK_infantrySpawnPositions = +BLWK_cachedEnemySpawns; - BLWK_cachedEnemySpawns = nil; - BLWK_playerBasePosition = nil; - - missionNamespace setVariable ["BLWK_enforceArea",true,true]; - [true] remoteExecCall ["BLWK_fnc_playAreaEnforcementLoop",BLWK_allClientsTargetId]; - - // make sure crate is in play area - if !(BLWK_mainCrate inArea BLWK_playAreaMarker) then { - BLWK_mainCrate setPos ([BLWK_playAreaCenter, 0, 100, 0, 0] call BIS_fnc_findSafePos); - }; -}] call BIS_fnc_addScriptedEventHandler; - - -[_playerPosition] spawn { - params ["_playerPosition"]; - - // allow players outside the play area - missionNamespace setVariable ["BLWK_enforceArea",false,true]; - - sleep 2; - - // move players and crate to side - BLWK_mainCrate setPosATL _playerPosition; - - (call CBAP_fnc_players) apply { - // don't teleport players in vehicles - if (isNull (objectParent _x)) then { - _x setPosATL ([_playerPosition,15,random 360] call CBAP_fnc_randPos); - }; - }; - - // to keep AI from being spawned on top of players - missionNamespace setVariable ["BLWK_baseIsClear",true]; -}; - - -true diff --git a/Headers/String Constants.hpp b/Headers/String Constants.hpp index 307e5cee..c6973264 100644 --- a/Headers/String Constants.hpp +++ b/Headers/String Constants.hpp @@ -1,9 +1,5 @@ -// queue Strings -#define STANDARD_ENEMY_INFANTRY_QUEUE "BLWK_standardEnemyInfantryqueue" - // Notifications #define SPECIAL_WARNING_TEMPLATE "SpecialWarning" #define TASK_ASSIGNED_TEMPLATE "TaskAssigned" -#define TASK_COMPLETE_TEMPLATE "TaskSucceeded" -#define COMPLETED_WAVE_NOTIFICATION(WAVE_NUM_STRING) ("Wave " + WAVE_NUM_STRING + " Complete") + diff --git a/Headers/descriptionEXT/Wave Types.hpp b/Headers/descriptionEXT/Wave Types.hpp index 8302e7e6..bb129d43 100644 --- a/Headers/descriptionEXT/Wave Types.hpp +++ b/Headers/descriptionEXT/Wave Types.hpp @@ -93,7 +93,10 @@ class BLWK_waveTypes }; class overrunWave : suicideWave { - onSelected = "remoteExecCall ['BLWK_fnc_handleOverrunWave',BLWK_theAIHandlerOwnerID]"; + onWaveInit = "BLWK_fnc_overrunWave_onWaveInit"; + onWaveEnd = "BLWK_fnc_overrunWave_onWaveEnd"; + generateManSpawnPosition = "BLWK_fnc_overrunWave_generateManSpawnPosition"; + condition = "BLWK_fnc_overrunWave_condition"; notificationText = "The Area Was Overrun!"; toggleVariable = "BLWK_allowOverrunWave"; }; diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 9e595f50..f83a6e7b 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -452,12 +452,16 @@ class BLWK {}; }; - class OverrunWaveLibrary + class OverrunWaveLib { - file = "Functions\Wave Type Libraries\Overrun Wave Library"; - class handleOverrunWave + file = "Functions\Wave Type Libraries\Overrun Wave Lib"; + class overrunWave_onWaveInit {}; - class overrunTheCrateWave + class overrunWave_onWaveEnd + {}; + class overrunWave_generateManSpawnPosition + {}; + class overrunWave_condition {}; }; From f94ad2d8403f293a2c2be7d10e6752ea27264301 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Mon, 10 Jul 2023 20:18:02 -0600 Subject: [PATCH 046/133] (#642): implemented BLWK_fnc_waves_end --- Functions/Queue/fn_spawnQueue_unitKilled.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Functions/Queue/fn_spawnQueue_unitKilled.sqf b/Functions/Queue/fn_spawnQueue_unitKilled.sqf index 942261a0..a26fe1a1 100644 --- a/Functions/Queue/fn_spawnQueue_unitKilled.sqf +++ b/Functions/Queue/fn_spawnQueue_unitKilled.sqf @@ -28,7 +28,7 @@ private _queueIsEmpty = _queueItem isEqualTo []; if (_queueIsEmpty AND {call BLWK_fnc_waves_isCleared}) then { [ { - // TODO: call end wave + call BLWK_fnc_waves_end; } ] call CBAP_fnc_directCall; }; From a29879eb5c9ab8a4f631ee66a25b2e5885888191 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Mon, 10 Jul 2023 22:13:07 -0600 Subject: [PATCH 047/133] (#642): fixed network oversite on overrun wave --- .../Overrun Wave Lib/fn_overrunWave_onWaveInit.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_onWaveInit.sqf index 3bd81aab..dfda32dd 100644 --- a/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_onWaveInit.sqf +++ b/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_onWaveInit.sqf @@ -65,7 +65,7 @@ private _startingWaveUnits = call BLWK_fnc_getMustKillList; }; _startingWaveUnits apply { - [group _x,BLWK_playerBasePosition] call BLWK_fnc_stopStalking + [group _x,BLWK_playerBasePosition] remoteExecCall ["BLWK_fnc_stopStalking",BLWK_theAIHandlerOwnerID]; }; }, [_startingWaveUnits], From c8c70b20987a1a0c7f071641fb37e1e83fa557a5 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Mon, 10 Jul 2023 22:53:51 -0600 Subject: [PATCH 048/133] (#642): updated civilian wave to new system --- .../fn_civilianWave_onCivilianKilled.sqf} | 18 +++--- .../fn_civilianWave_onWaveEnd.sqf | 28 ++++++++ .../fn_civilianWave_onWaveInit.sqf | 64 +++++++++++++++++++ .../fn_civilianWave_randomGear.sqf} | 54 +++++----------- .../fn_civiliansWave.sqf | 61 ------------------ .../fn_killedCivilianEvent.sqf | 35 ---------- .../Civilian Wave Library/fn_onCivWaveEnd.sqf | 32 ---------- Headers/civilianGearTables.hpp | 3 +- Headers/descriptionEXT/Wave Types.hpp | 10 +-- Headers/descriptionEXT/functions.hpp | 15 ++--- 10 files changed, 130 insertions(+), 190 deletions(-) rename Functions/Wave Type Libraries/{Civilian Wave Library/fn_handleCivilianKilledEventPlayer.sqf => CIvilian Wave Lib/fn_civilianWave_onCivilianKilled.sqf} (58%) create mode 100644 Functions/Wave Type Libraries/CIvilian Wave Lib/fn_civilianWave_onWaveEnd.sqf create mode 100644 Functions/Wave Type Libraries/CIvilian Wave Lib/fn_civilianWave_onWaveInit.sqf rename Functions/Wave Type Libraries/{Civilian Wave Library/fn_civRandomGear.sqf => CIvilian Wave Lib/fn_civilianWave_randomGear.sqf} (61%) delete mode 100644 Functions/Wave Type Libraries/Civilian Wave Library/fn_civiliansWave.sqf delete mode 100644 Functions/Wave Type Libraries/Civilian Wave Library/fn_killedCivilianEvent.sqf delete mode 100644 Functions/Wave Type Libraries/Civilian Wave Library/fn_onCivWaveEnd.sqf diff --git a/Functions/Wave Type Libraries/Civilian Wave Library/fn_handleCivilianKilledEventPlayer.sqf b/Functions/Wave Type Libraries/CIvilian Wave Lib/fn_civilianWave_onCivilianKilled.sqf similarity index 58% rename from Functions/Wave Type Libraries/Civilian Wave Library/fn_handleCivilianKilledEventPlayer.sqf rename to Functions/Wave Type Libraries/CIvilian Wave Lib/fn_civilianWave_onCivilianKilled.sqf index 30ce4052..1a5e25cd 100644 --- a/Functions/Wave Type Libraries/Civilian Wave Library/fn_handleCivilianKilledEventPlayer.sqf +++ b/Functions/Wave Type Libraries/CIvilian Wave Lib/fn_civilianWave_onCivilianKilled.sqf @@ -1,27 +1,25 @@ /* ---------------------------------------------------------------------------- -Function: BLWK_fnc_handleCivilianKilledEventPlayer +Function: BLWK_fnc_civilianWave_onCivilianKilled Description: - Docks players points and plays a sound informing them of a killed civilian. - - Executed from "BLWK_fnc_killedCivilianEvent". + Docks players points and plays a sound informing them of a killed civilian. Parameters: - 0: _killedUnit : - The unit killed by the player + 0: _killedUnit : - The unit killed by the player Returns: - NOTHING + NOTHING Examples: (begin example) - - [_killedUnit] remoteExecCall ["BLWK_fnc_handleCivilianKilledEventPlayer",_instigator]; - + [_killedUnit] remoteExecCall ["BLWK_fnc_civilianWave_onCivilianKilled",_instigator]; (end) Author(s): - Ansible2 // Cipher + Ansible2 ---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_civilianWave_onCivilianKilled"; + if !(hasInterface) exitWith {}; params ["_killedUnit"]; diff --git a/Functions/Wave Type Libraries/CIvilian Wave Lib/fn_civilianWave_onWaveEnd.sqf b/Functions/Wave Type Libraries/CIvilian Wave Lib/fn_civilianWave_onWaveEnd.sqf new file mode 100644 index 00000000..988fede5 --- /dev/null +++ b/Functions/Wave Type Libraries/CIvilian Wave Lib/fn_civilianWave_onWaveEnd.sqf @@ -0,0 +1,28 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_civilianWave_onWaveEnd + +Description: + Deletes any civilians created for the wave. + +Parameters: + NONE + +Returns: + NOTHING + +Examples: + (begin example) + call BLWK_fnc_civilianWave_onWaveEnd; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_civilianWave_onWaveEnd"; + +// delete any alive civilians from special wave + +private _civilians = localNamespace getVariable ["BLWK_civilianWave_civilians",[]]; +_civilians apply { deleteVehicle _x }; + +localNamespace setVariable ["BLWK_civilianWave_civilians",nil]; diff --git a/Functions/Wave Type Libraries/CIvilian Wave Lib/fn_civilianWave_onWaveInit.sqf b/Functions/Wave Type Libraries/CIvilian Wave Lib/fn_civilianWave_onWaveInit.sqf new file mode 100644 index 00000000..af253851 --- /dev/null +++ b/Functions/Wave Type Libraries/CIvilian Wave Lib/fn_civilianWave_onWaveInit.sqf @@ -0,0 +1,64 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_civilianWave_onWaveInit + +Description: + The on wave init for a civilian wave. + +Parameters: + NONE + +Returns: + NOTHING + +Examples: + (begin example) + call BLWK_fnc_civilianWave_onWaveInit; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_civilianWave_onWaveInit"; + +if (!isServer) exitWith {}; + +#define NUM_CIVILIANS 12 +#define CIVILIAN_CLASS "C_man_1" + +private _civilians = []; +for "_i" from 1 to NUM_CIVILIANS do { + private _randomBuilding = selectRandom BLWK_playAreaBuildings; + private _spawnPosition = selectRandom (_randomBuilding buildingPos -1); + + private _group = createGroup [civilian,true]; + private _unit = _group createUnit [CIVILIAN_CLASS, _spawnPosition, [], 0.5, "NONE"]; + + [_unit] call BLWK_fnc_civilianWave_randomGear; + + + _unit addEventHandler ["KILLED",{ + params ["_killedUnit", "", "_instigator"]; + + if (!(isNull _instigator) AND {isPlayer _instigator}) then { + // show a player hit points and add them to there score + [_killedUnit] remoteExecCall ["BLWK_fnc_civilianWave_onCivilianKilled",_instigator]; + }; + }]; + + + // make civilians run around + [_group,BLWK_playAreaCenter,BLWK_playAreaRadius,3] call CBAP_fnc_taskPatrol; + + _unit allowFleeing 0; + _unit setBehaviour "CARELESS"; + + _civilians pushBack _unit; +}; + +// for deleteing cvilians at wave end +localNamespace setVariable ["BLWK_civilianWave_civilians",_civilians]; + +[BLWK_zeus,[_civilians, true]] remoteExecCall ["addCuratorEditableObjects",2]; + + +nil diff --git a/Functions/Wave Type Libraries/Civilian Wave Library/fn_civRandomGear.sqf b/Functions/Wave Type Libraries/CIvilian Wave Lib/fn_civilianWave_randomGear.sqf similarity index 61% rename from Functions/Wave Type Libraries/Civilian Wave Library/fn_civRandomGear.sqf rename to Functions/Wave Type Libraries/CIvilian Wave Lib/fn_civilianWave_randomGear.sqf index 2c0eaba3..468badc3 100644 --- a/Functions/Wave Type Libraries/Civilian Wave Library/fn_civRandomGear.sqf +++ b/Functions/Wave Type Libraries/CIvilian Wave Lib/fn_civilianWave_randomGear.sqf @@ -1,6 +1,6 @@ #include "..\..\..\Headers\civilianGearTables.hpp" /* ---------------------------------------------------------------------------- -Function: BLWK_fnc_civRandomGear +Function: BLWK_fnc_civilianWave_randomGear Description: Randomizes gear based upon global arrays. Designed with civilians in mind. @@ -9,19 +9,17 @@ Parameters: 0: _unit : - The unit to randomize gear Returns: - BOOL + NOTHING Examples: (begin example) - - [_unit] call BLWK_fnc_civRandomGear; - + [_unit] call BLWK_fnc_civilianWave_randomGear; (end) Author(s): - Ansible2 // Cipher + Ansible2 ---------------------------------------------------------------------------- */ -scriptName "BLWK_fnc_civRandomGear"; +scriptName "BLWK_fnc_civilianWave_randomGear"; params [ ["_unit",objNull,[objNull]] @@ -29,12 +27,12 @@ params [ if (isNull _unit) exitWith { ["_unit is a null object, exiting...",true] call KISKA_fnc_log; - false + nil }; if (!local _unit) exitWith { [[_unit," is not local to your machine, exiting..."],true] call KISKA_fnc_log; - false + nil }; // remove all existing stuff @@ -47,28 +45,9 @@ removeBackpack _unit; removeHeadgear _unit; removeGoggles _unit; - -private _fn_chooseGear = { - params ["_gearArray"]; - - private "_selectedGear"; - - // if is weighted array - if (_gearArray isEqualTypeParams ["",123]) then { - _selectedGear = selectRandomWeighted _gearArray; - } else { - _selectedGear = selectRandom _gearArray; - }; - - _selectedGear -}; - - -// assign stuff - // uniform -if !(CIV_UNIFORMS isEqualTo []) then { - private _chosen_uniform = [CIV_UNIFORMS] call _fn_chooseGear; +if (CIV_UNIFORMS isNotEqualTo []) then { + private _chosen_uniform = [CIV_UNIFORMS,""] call KISKA_fnc_selectRandom; // adding "none" to the selection array will add the possibility of nothing at all being added if !(_chosen_uniform == "NONE") then { @@ -76,28 +55,29 @@ if !(CIV_UNIFORMS isEqualTo []) then { }; }; // headgear -if !(CIV_HEADGEAR isEqualTo []) then { - private _chosen_headgear = [CIV_HEADGEAR] call _fn_chooseGear; +if (CIV_HEADGEAR isNotEqualTo []) then { + private _chosen_headgear = [CIV_HEADGEAR,""] call KISKA_fnc_selectRandom; if !(_chosen_headgear == "NONE") then { _unit addHeadgear _chosen_headgear; }; }; // facewear -if !(CIV_FACEWEAR isEqualTo []) then { - private _chosen_facewear = [CIV_FACEWEAR] call _fn_chooseGear; +if (CIV_FACEWEAR isNotEqualTo []) then { + private _chosen_facewear = [CIV_FACEWEAR,""] call KISKA_fnc_selectRandom; if !(_chosen_facewear == "NONE") then { _unit addGoggles _chosen_facewear; }; }; // vest -if !(CIV_VESTS isEqualTo []) then { - private _chosen_vest = [CIV_VESTS] call _fn_chooseGear; +if (CIV_VESTS isNotEqualTo []) then { + private _chosen_vest = [CIV_VESTS,""] call KISKA_fnc_selectRandom; if !(_chosen_vest == "NONE") then { _unit addVest _chosen_vest; }; }; -true \ No newline at end of file + +nil diff --git a/Functions/Wave Type Libraries/Civilian Wave Library/fn_civiliansWave.sqf b/Functions/Wave Type Libraries/Civilian Wave Library/fn_civiliansWave.sqf deleted file mode 100644 index a8db71de..00000000 --- a/Functions/Wave Type Libraries/Civilian Wave Library/fn_civiliansWave.sqf +++ /dev/null @@ -1,61 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_civiliansWave - -Description: - Creates the civilians during a special wave. - - It is executed from the "BLWK_fnc_spawnWaveEnemies". - -Parameters: - NONE - -Returns: - NOTHING - -Examples: - (begin example) - - call BLWK_fnc_civiliansWave; - - (end) -Author(s): - Hilltop(Willtop) & omNomios, - Modified by: Ansible2 // Cipher ----------------------------------------------------------------------------- */ -if (!isServer) exitWith {}; - -#define NUM_CIVILIANS 12 -#define CIVILIAN_CLASS "C_man_1" -// CIPHER COMMENT: Consider adjusting the amount of ai for dedicated and hosted server -// CIPHER COMMENT: might be worth trying this with agents too -// CIPHER COMMENT: could just do an allunits select {side _x isEqualTo civilian} instead of deletion pile... -private _civilians = []; -for "_i" from 1 to NUM_CIVILIANS do { - private _randomBuilding = selectRandom BLWK_playAreaBuildings; - private _spawnPosition = selectRandom (_randomBuilding buildingPos -1); - - private _group = createGroup [civilian,true]; - private _unit = _group createUnit [CIVILIAN_CLASS, _spawnPosition, [], 0.5, "NONE"]; - - // give them a random look - [_unit] call BLWK_fnc_civRandomGear; - - // if a player kills the civilian, remove points - // CIPHER COMMENT: make sure you need MP event instead of local one - _unit addEventHandler ["KILLED",{ - _this call BLWK_fnc_killedCivilianEvent; - }]; - - // create cycle waypoints for them - [_group,BLWK_playAreaCenter,BLWK_playAreaRadius,3] call CBAP_fnc_taskPatrol; - - _unit allowFleeing 0; - _unit setBehaviour "CARELESS"; - - _civilians pushBack _unit; -}; - -// for deleteing cvilians at wave end -missionNamespace setVariable ["BLWK_civiliansFromWave",_civilians]; - -[BLWK_zeus,[_civilians, true]] remoteExecCall ["addCuratorEditableObjects",2]; \ No newline at end of file diff --git a/Functions/Wave Type Libraries/Civilian Wave Library/fn_killedCivilianEvent.sqf b/Functions/Wave Type Libraries/Civilian Wave Library/fn_killedCivilianEvent.sqf deleted file mode 100644 index e35bb2f6..00000000 --- a/Functions/Wave Type Libraries/Civilian Wave Library/fn_killedCivilianEvent.sqf +++ /dev/null @@ -1,35 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_killedCivilianEvent - -Description: - Initiates a check to see if a civilian was killed by a player and sends - a dock of points to the player if found. - - Executed from the eventhandeler added in "BLWK_fnc_civiliansWave" - -Parameters: - 0: _killedUnit : - Object the event handler is assigned to - 1: _killer : - Object that killed _killedUnit – contains unit itself in case of collisions (not used) - 2: _instigator : - Person who pulled the trigger - 3: _useEffects : - same as useEffects in setDamage alt syntax (not used) - -Returns: - NOTHING - -Examples: - (begin example) - - [_this,_thisEventhandler] call BLWK_fnc_killedCivilianEvent; - - (end) - -Author(s): - Hilltop(Willtop) & omNomios, - Modified by: Ansible2 // Cipher ----------------------------------------------------------------------------- */ -params ["_killedUnit", "_killer", "_instigator", "_useEffects"]; - -if (!(isNull _instigator) AND {isPlayer _instigator}) then { - // show a player hit points and add them to there score - [_killedUnit] remoteExecCall ["BLWK_fnc_handleCivilianKilledEventPlayer",_instigator]; -}; \ No newline at end of file diff --git a/Functions/Wave Type Libraries/Civilian Wave Library/fn_onCivWaveEnd.sqf b/Functions/Wave Type Libraries/Civilian Wave Library/fn_onCivWaveEnd.sqf deleted file mode 100644 index 7aa0df0b..00000000 --- a/Functions/Wave Type Libraries/Civilian Wave Library/fn_onCivWaveEnd.sqf +++ /dev/null @@ -1,32 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_onCivWaveEnd - -Description: - Deletes any alive civilians after wave end. - -Parameters: - NONE - -Returns: - NOTHING - -Examples: - (begin example) - call BLWK_fnc_onCivWaveEnd; - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -scriptName "BLWK_fnc_onCivWaveEnd"; - -// delete any alive civilians from special wave -if ((missionNamespace getVariable ["BLWK_civiliansFromWave",[]]) isNotEqualTo []) then { - BLWK_civiliansFromWave apply { - if (alive _x) then { - deleteVehicle _x; - }; - }; - - missionNamespace setVariable ["BLWK_civiliansFromWave",[]]; -}; diff --git a/Headers/civilianGearTables.hpp b/Headers/civilianGearTables.hpp index c8ef5d24..22d4db86 100644 --- a/Headers/civilianGearTables.hpp +++ b/Headers/civilianGearTables.hpp @@ -24,8 +24,7 @@ "H_Hat_Safari_sand_F",\ "H_Hat_Safari_olive_F",\ "H_StrawHat",\ - "H_StrawHat_dark",\ - ""\ + "H_StrawHat_dark"\ ] #define CIV_VESTS [] diff --git a/Headers/descriptionEXT/Wave Types.hpp b/Headers/descriptionEXT/Wave Types.hpp index bb129d43..6a063308 100644 --- a/Headers/descriptionEXT/Wave Types.hpp +++ b/Headers/descriptionEXT/Wave Types.hpp @@ -77,11 +77,12 @@ class BLWK_waveTypes // (likely paired with a KISKA parameter menu mission param) toggleVariable = "BLWK_allowSuicideWave"; }; - class civilianWave : suicideWave + class civilianWave { - onSelected = "remoteExecCall ['BLWK_fnc_handleStandardWave',BLWK_theAIHandlerOwnerID]; call BLWK_fnc_civiliansWave"; + creationNotificationTemplate = SPECIAL_WARNING_TEMPLATE; + onWaveInit = "BLWK_fnc_civilianWave_onWaveInit"; + onWaveEnd = "BLWK_fnc_civilianWave_onWaveEnd"; notificationText = "Civilians Are Fleeing, Watch Your Fire!"; - onWaveEnd = "call BLWK_fnc_onCivWaveEnd"; toggleVariable = "BLWK_allowCivWave"; }; class droneWave : suicideWave @@ -91,8 +92,9 @@ class BLWK_waveTypes onWaveEnd = "call BLWK_fnc_onDroneWaveEnd"; toggleVariable = "BLWK_allowDroneWave"; }; - class overrunWave : suicideWave + class overrunWave { + creationNotificationTemplate = SPECIAL_WARNING_TEMPLATE; onWaveInit = "BLWK_fnc_overrunWave_onWaveInit"; onWaveEnd = "BLWK_fnc_overrunWave_onWaveEnd"; generateManSpawnPosition = "BLWK_fnc_overrunWave_generateManSpawnPosition"; diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index f83a6e7b..bdc77b50 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -407,19 +407,16 @@ class BLWK {}; }; - // Wave Type Libraries - class CivilianWaveLibrary + class CivilianWaveLib { - file = "Functions\Wave Type Libraries\Civilian Wave Library"; - class civiliansWave + file = "Functions\Wave Type Libraries\Civilian Wave Lib"; + class civilianWave_onCivilianKilled {}; - class civRandomGear + class civilianWave_onWaveInit {}; - class handleCivilianKilledEventPlayer + class civilianWave_onWaveEnd {}; - class killedCivilianEvent - {}; - class onCivWaveEnd + class civilianWave_randomGear {}; }; From ce26b9977a3ba892074e69905313dea1db65d9da Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Mon, 10 Jul 2023 23:27:17 -0600 Subject: [PATCH 049/133] (#642): reimplemented drone wave for new system --- Functions/Queue/fn_spawnQueue_unitKilled.sqf | 14 +-- .../fn_droneWave_attackLoop.sqf | 88 ++++++++++++++++++ .../fn_droneWave_onDroneKilled.sqf | 31 +++++++ .../Drone Wave Lib/fn_droneWave_onWaveEnd.sqf | 23 +++++ .../fn_droneWave_onWaveInit.sqf | 91 +++++++++++++++++++ .../Drone Wave Library/fn_droneAttackLoop.sqf | 50 ---------- .../Drone Wave Library/fn_handleDroneWave.sqf | 27 ------ Functions/Waves/fn_waves_isCleared.sqf | 2 +- Headers/descriptionEXT/Wave Types.hpp | 7 +- Headers/descriptionEXT/functions.hpp | 12 +-- 10 files changed, 251 insertions(+), 94 deletions(-) create mode 100644 Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_attackLoop.sqf create mode 100644 Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onDroneKilled.sqf create mode 100644 Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveEnd.sqf create mode 100644 Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf delete mode 100644 Functions/Wave Type Libraries/Drone Wave Library/fn_droneAttackLoop.sqf delete mode 100644 Functions/Wave Type Libraries/Drone Wave Library/fn_handleDroneWave.sqf diff --git a/Functions/Queue/fn_spawnQueue_unitKilled.sqf b/Functions/Queue/fn_spawnQueue_unitKilled.sqf index a26fe1a1..c44a647b 100644 --- a/Functions/Queue/fn_spawnQueue_unitKilled.sqf +++ b/Functions/Queue/fn_spawnQueue_unitKilled.sqf @@ -3,10 +3,10 @@ Function: BLWK_fnc_spawnQueue_unitKilled Description: Informs the server that a unit from the queue has died. This will either - trigger another unit to be popped and created or to end the wave. + trigger another unit to be popped and created or to end the wave. Parameters: - NONE + NONE Returns: NOTHING @@ -26,11 +26,11 @@ if (!isServer) exitWith {}; private _queueItem = call BLWK_fnc_popAndCreate; private _queueIsEmpty = _queueItem isEqualTo []; if (_queueIsEmpty AND {call BLWK_fnc_waves_isCleared}) then { - [ - { - call BLWK_fnc_waves_end; - } - ] call CBAP_fnc_directCall; + [ + { + call BLWK_fnc_waves_end; + } + ] call CBAP_fnc_directCall; }; diff --git a/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_attackLoop.sqf b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_attackLoop.sqf new file mode 100644 index 00000000..bd19af22 --- /dev/null +++ b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_attackLoop.sqf @@ -0,0 +1,88 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_droneWave_attackLoop + +Description: + Handles the flying of drones and their attacking of targets. + +Parameters: + 0: _drone : - The drone that attacks + 1: _droneGroup : - The drone's group + 2: _spawnPosition : - The position the drone spawned at + +Returns: + NOTHING + +Examples: + (begin example) + [ + myDrone, + group myDrone, + [0,0,0] + ] spawn BLWK_fnc_droneWave_attackLoop; + (end) + +Author(s): + Hilltop(Willtop) & omNomios, + Modified by: Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_droneWave_attackLoop"; + +#define FIRE_DISTANCE_BUFFER 37 +#define FLY_HEIGHT 10 + +if (!canSuspend) exitWith { + ["Must be run in scheduled environment, exiting to scheduled",true] call KISKA_fnc_log; + _this spawn BLWK_fnc_droneWave_attackLoop; +}; + +params [ + "_drone", + "_droneGroup", + "_spawnPosition" +]; + +private _distanceToFire = FLY_HEIGHT + FIRE_DISTANCE_BUFFER; +while {alive _drone} do { + _drone move (position BLWK_mainCrate); + + // wait to be in position to fire + waitUntil { + if ( + !(alive _drone) OR + {(_drone distance BLWK_mainCrate) <= _distanceToFire} OR + // sometimes units can just slightly out of the ideal 3d range + {(_drone distance2D BLWK_mainCrate) <= 10} + ) exitWith {true}; + + sleep 2; + false + }; + + // do fire + waitUntil { + if ( + !(alive _drone) OR + {_drone fireAtTarget [BLWK_mainCrate]} + ) exitWith {true}; + + sleep 2; + false + }; + + // move back to spawn + _drone move _spawnPosition; + waitUntil { + if exitWith {true}; + if ( + !(alive _drone) OR + {(_drone distance2d _spawnPosition) <= 10} + ) exitWith {true}; + + sleep 2; + false + }; + +}; + + +nil diff --git a/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onDroneKilled.sqf b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onDroneKilled.sqf new file mode 100644 index 00000000..6c26e853 --- /dev/null +++ b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onDroneKilled.sqf @@ -0,0 +1,31 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_droneWave_onDroneKilled + +Description: + The on wave init for drone waves. Spawns the drones and adds them to the + must kill list + +Parameters: + NONE + +Returns: + NOTHING + +Examples: + (begin example) + [someDrone,200] remoteExec ["BLWK_fnc_droneWave_onDroneKilled",_instigator]; + (end) + +Author(s): + Hilltop(Willtop) & omNomios, + Modified by: Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_droneWave_onDroneKilled"; + +params ["_drone","_points"]; + +[_points] call BLWK_fnc_addPoints; +[_drone,_points,true] call BLWK_fnc_createHitMarker; + + +nil diff --git a/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveEnd.sqf b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveEnd.sqf new file mode 100644 index 00000000..2980abf4 --- /dev/null +++ b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveEnd.sqf @@ -0,0 +1,23 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_droneWave_onWaveEnd + +Description: + Resets the local "BLWK_droneWave_allDronesCreated" var + +Parameters: + NONE + +Returns: + NOTHING + +Examples: + (begin example) + call BLWK_fnc_droneWave_onWaveEnd; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_droneWave_onWaveEnd"; + +localNamespace setVariable ["BLWK_droneWave_allDronesCreated",nil]; diff --git a/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf new file mode 100644 index 00000000..a9d4a6da --- /dev/null +++ b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf @@ -0,0 +1,91 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_droneWave_onWaveInit + +Description: + The on wave init for drone waves. Spawns the drones and adds them to the + must kill list + +Parameters: + NONE + +Returns: + NOTHING + +Examples: + (begin example) + call BLWK_fnc_droneWave_onWaveInit; + (end) + +Author(s): + Hilltop(Willtop) & omNomios, + Modified by: Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_droneWave_onWaveInit"; + +#define DRONE_CLASS "C_IDAP_UAV_06_antimine_F" +#define DRONE_NUMBER 12 +#define FLY_HEIGHT 10 +#define DRONE_SPAWN_OFFSET 10 + +if (!canSuspend) exitWith { + ["Must be run in scheduled environment, exiting to scheduled",true] call KISKA_fnc_log; + [] spawn BLWK_fnc_createDroneWave; +}; + +localNamespace setVariable ["BLWK_droneWave_allDronesCreated",false]; + +for "_i" from 1 to DRONE_NUMBER do { + // Spawn position + private _droneGroup = createGroup OPFOR; + private _flyDirection = round (random 360); + private _flyFromDirection = [_flyDirection + 180] call CBAP_fnc_simplifyAngle; + private _spawnPosition = BLWK_mainCrate getPos [ + BLWK_playAreaRadius + (random [100,125,150]), + _flyFromDirection + ]; + _spawnPosition set [2,FLY_HEIGHT]; + + // Create + private _droneSpawnInfo = [ + _spawnPosition, + _flyDirection, + DRONE_CLASS, + _droneGroup + ] call BIS_fnc_spawnVehicle; + + private _drone = _droneSpawnInfo select 0; + _drone flyInHeight FLY_HEIGHT; + _drone setSkill 1; + + + [_drone,_droneGroup,_spawnPosition] spawn BLWK_fnc_droneWave_attackLoop; + + + _drone addEventHandler ["HIT", { + params ["_drone", "", "", "_instigator"]; + + if (isPlayer _instigator) then { + private _points = [_drone] call BLWK_fnc_getPointsForKill; + [_drone,_points] remoteExec ["BLWK_fnc_droneWave_onDroneKilled",_instigator]; + }; + + private _explosion = "DemoCharge_Remote_Ammo_Scripted" createVehicle (getPosATLVisual _drone); + _explosion setdamage 1; + deleteVehicle _unit; + + if (call BLWK_fnc_waves_isCleared) then { + call BLWK_fnc_waves_end + }; + }]; + + + [_drone] call BLWK_fnc_addToMustKillList; + BLWK_zeus addCuratorEditableObjects [[_drone], true]; + + // space out spawns so that you don't get spammed + sleep DRONE_SPAWN_OFFSET; +}; + +localNamespace setVariable ["BLWK_droneWave_allDronesCreated",true]; + +nil diff --git a/Functions/Wave Type Libraries/Drone Wave Library/fn_droneAttackLoop.sqf b/Functions/Wave Type Libraries/Drone Wave Library/fn_droneAttackLoop.sqf deleted file mode 100644 index 8db9ee95..00000000 --- a/Functions/Wave Type Libraries/Drone Wave Library/fn_droneAttackLoop.sqf +++ /dev/null @@ -1,50 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_droneAttackLoop - -Description: - Loops to simulate the drones attacking The Crate by dropping bombs ever so often - - Executed from "BLWK_fnc_createDroneWave" - -Parameters: - 0: _droneGroup : - The group of drones to do the attacking - -Returns: - NOTHING - -Examples: - (begin example) - - [_droneGroup] spawn BLWK_fnc_droneAttackLoop; - - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -if (!canSuspend) exitWith {}; - -params ["_droneGroup"]; - -waitUntil { - if ((leader _droneGroup) distance2D BLWK_mainCrate <= 25) exitWith {true}; - sleep 3; - false -}; - -private ["_didFire","_droneTofire"]; -private _droneGroupUnits = units _droneGroup; -while {!(_droneGroupUnits isEqualTo [])} do { - _droneTofire = selectRandom _droneGroupUnits; - - _didFire = _droneTofire fireAtTarget [BLWK_mainCrate]; - if (_didFire) then { - sleep 10; - } else { - sleep 5; - }; - - _droneGroupUnits = units _droneGroup; -}; - -deleteGroup _droneGroup; \ No newline at end of file diff --git a/Functions/Wave Type Libraries/Drone Wave Library/fn_handleDroneWave.sqf b/Functions/Wave Type Libraries/Drone Wave Library/fn_handleDroneWave.sqf deleted file mode 100644 index dcaf86e6..00000000 --- a/Functions/Wave Type Libraries/Drone Wave Library/fn_handleDroneWave.sqf +++ /dev/null @@ -1,27 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_handleDroneWave - -Description: - This is simply an alias for the below functions. It is used to exec - both on whomever the AI handler is without using multiple remoteExecs - - Executed from "BLWK_fnc_spawnWaveEnemies" - -Parameters: - NONE - -Returns: - NOTHING - -Examples: - (begin example) - - call BLWK_fnc_handleDroneWave; - - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -call BLWK_fnc_createStdWaveInfantry; -[] spawn BLWK_fnc_createDroneWave; \ No newline at end of file diff --git a/Functions/Waves/fn_waves_isCleared.sqf b/Functions/Waves/fn_waves_isCleared.sqf index 8737821c..94adcf44 100644 --- a/Functions/Waves/fn_waves_isCleared.sqf +++ b/Functions/Waves/fn_waves_isCleared.sqf @@ -29,7 +29,7 @@ if (_aUnitIsStillAlive) exitWith { false }; // not all special wave drones spawn right away, so checking that they have // (and that they are therefore in the kill list) // before checking if all enemies are dead -private _allDronesCreated = missionNamespace getVariable ["BLWK_allDronesCreated",true]; +private _allDronesCreated = localNamespace getVariable ["BLWK_droneWave_allDronesCreated",true]; if (!_allDronesCreated) exitWith { false }; true diff --git a/Headers/descriptionEXT/Wave Types.hpp b/Headers/descriptionEXT/Wave Types.hpp index 6a063308..87a0d476 100644 --- a/Headers/descriptionEXT/Wave Types.hpp +++ b/Headers/descriptionEXT/Wave Types.hpp @@ -85,11 +85,12 @@ class BLWK_waveTypes notificationText = "Civilians Are Fleeing, Watch Your Fire!"; toggleVariable = "BLWK_allowCivWave"; }; - class droneWave : suicideWave + class droneWave { - onSelected = "remoteExecCall ['BLWK_fnc_handleDroneWave',BLWK_theAIHandlerOwnerID]"; + creationNotificationTemplate = SPECIAL_WARNING_TEMPLATE; + onWaveInit = "BLWK_fnc_droneWave_onWaveInit"; + onWaveEnd = "BLWK_fnc_droneWave_onWaveEnd"; notificationText = "Enemy Drones Inbound!"; - onWaveEnd = "call BLWK_fnc_onDroneWaveEnd"; toggleVariable = "BLWK_allowDroneWave"; }; class overrunWave diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index bdc77b50..5be3aa73 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -420,16 +420,16 @@ class BLWK {}; }; - class DroneWaveLibrary + class DroneWaveLib { - file = "Functions\Wave Type Libraries\Drone Wave Library"; - class createDroneWave + file = "Functions\Wave Type Libraries\Drone Wave Lib"; + class droneWave_attackLoop {}; - class droneAttackLoop + class droneWave_onWaveInit {}; - class handleDroneWave + class droneWave_onWaveEnd {}; - class onDroneWaveEnd + class droneWave_onDroneKilled {}; }; From cd531dfcc7471feb7e7afa9f3d04c3b36176197f Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Tue, 11 Jul 2023 20:11:02 -0600 Subject: [PATCH 050/133] (#642): updated helicopter wave to new standard --- Functions/Other/fn_addVehicleKilledEvent.sqf | 40 ++++++++++++++ .../fn_spawnQueue_addManEventhandlers.sqf | 54 +++++++++++++++++++ Functions/Queue/fn_spawnQueue_create.sqf | 23 +------- .../Supports/fn_passiveHelicopterGunner.sqf | 4 +- .../fn_helicopterWave_onWaveInit.sqf} | 34 ++++++------ .../fn_standardWave_vehicles.sqf | 9 +--- Headers/descriptionEXT/Wave Types.hpp | 5 +- Headers/descriptionEXT/functions.hpp | 12 +++++ 8 files changed, 130 insertions(+), 51 deletions(-) create mode 100644 Functions/Other/fn_addVehicleKilledEvent.sqf create mode 100644 Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf rename Functions/Wave Type Libraries/{Helicopter Wave Library/fn_handleHelicopterWave.sqf => Helicopter Wave Lib/fn_helicopterWave_onWaveInit.sqf} (71%) diff --git a/Functions/Other/fn_addVehicleKilledEvent.sqf b/Functions/Other/fn_addVehicleKilledEvent.sqf new file mode 100644 index 00000000..41baa7a7 --- /dev/null +++ b/Functions/Other/fn_addVehicleKilledEvent.sqf @@ -0,0 +1,40 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_addVehicleKilledEvent + +Description: + Adds a killed event a vehicle that will provide points to a player when it + is killed. + +Parameters: + 0: _vehicle : - The vehicle to add the event to + +Returns: + - The killed event ID + +Examples: + (begin example) + [myVehicle] call BLWK_fnc_addVehicleKilledEvent; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_addVehicleKilledEvent"; + +params [ + ["_vehicle",objNull,[objNull]] +]; + +if (isNull _vehicle) exitWith { + ["Null vehicle passed",true] call KISKA_fnc_log; + -1 +}; + +_vehicle addEventHandler ["KILLED", { + params ["_killedUnit", "", "_instigator"]; + + if (!(isNull _instigator) AND (isPlayer _instigator)) then { + // show a player hit points and add them to there score + [_killedUnit,true] remoteExecCall ["BLWK_fnc_event_killedEnemy",_instigator]; + }; +}]; diff --git a/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf b/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf new file mode 100644 index 00000000..ec0bafcb --- /dev/null +++ b/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_spawnQueue_addManEventhandlers + +Description: + Adds the `HIT`, `KILLED`, and `DELETED` eventhandlers that govern how units + spawn from the queue and provide points to players. + +Parameters: + 0: _unit : - The unit to add the eventhandlers to + +Returns: + NOTHING + +Examples: + (begin example) + [myUnit] call BLWK_fnc_spawnQueue_addManEventhandlers; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_spawnQueue_addManEventhandlers"; + +params [ + ["_unit",objNull,[objNull]] +]; + +if (isNull _unit) exitWith { + ["Null unit passed!"] call KISKA_fnc_log; + nil +}; + + +_unit addEventHandler ["Hit", { + params ["_unit", "", "_damage", "_instigator"]; + [_unit,_damage] remoteExec ["BLWK_fnc_event_hitEnemy",_instigator]; +}]; + +_unit addEventHandler ["Killed", { + params ["_killedUnit", "", "_instigator"]; + if (!(isNull _instigator) AND (isPlayer _instigator)) then { + // show a player hit points and add them to there score + [_killedUnit] remoteExec ["BLWK_fnc_event_killedEnemy",_instigator]; + }; + + [] remoteExec ["BLWK_fnc_spawnQueue_unitKilled",2]; +}]; + +_unit addEventHandler ["Deleted", { + [] remoteExec ["BLWK_fnc_spawnQueue_unitKilled",2]; +}]; + + +nil diff --git a/Functions/Queue/fn_spawnQueue_create.sqf b/Functions/Queue/fn_spawnQueue_create.sqf index 7324cd5c..f4e83df2 100644 --- a/Functions/Queue/fn_spawnQueue_create.sqf +++ b/Functions/Queue/fn_spawnQueue_create.sqf @@ -58,28 +58,7 @@ if !(BLWK_doDetectMines) then { }; -/* ---------------------------------------------------------------------------- - Eventhandlers ----------------------------------------------------------------------------- */ -_unit addEventHandler ["Hit", { - params ["_unit", "", "_damage", "_instigator"]; - [_unit,_damage] remoteExec ["BLWK_fnc_event_hitEnemy",_instigator]; -}]; - -_unit addEventHandler ["Killed", { - params ["_killedUnit", "", "_instigator"]; - if (!(isNull _instigator) AND (isPlayer _instigator)) then { - // show a player hit points and add them to there score - [_killedUnit] remoteExec ["BLWK_fnc_event_killedEnemy",_instigator]; - }; - - [] remoteExec ["BLWK_fnc_spawnQueue_unitKilled",2]; -}]; - -_unit addEventHandler ["Deleted", { - [] remoteExec ["BLWK_fnc_spawnQueue_unitKilled",2]; -}]; - +[_unit] call BLWK_fnc_spawnQueue_addManEventhandlers; /* ---------------------------------------------------------------------------- Update server diff --git a/Functions/Supports/fn_passiveHelicopterGunner.sqf b/Functions/Supports/fn_passiveHelicopterGunner.sqf index 4d761be7..66523351 100644 --- a/Functions/Supports/fn_passiveHelicopterGunner.sqf +++ b/Functions/Supports/fn_passiveHelicopterGunner.sqf @@ -52,7 +52,7 @@ scriptName "BLWK_fnc_passiveHelicopterGunner"; #define DETECT_ENEMY_RADIUS 700 #define MIN_RADIUS 200 #define STAR_BEARINGS [0,144,288,72,216] -#define VEHICLE_DOWNED(vehicle) ((!alive vehicle) OR {(crew vehicle) isEqualTo []} OR {((getPosATL vehicle) select 2) < 3}) +#define VEHICLE_DOWNED(theVehicle) ((!alive theVehicle) OR {(crew theVehicle) isEqualTo []} OR {((getPosATL theVehicle) select 2) < 3}) params [ "_centerPosition", @@ -106,7 +106,7 @@ private _vehicleArray = [_spawnPosition,0,_aircraftType,_side] call BIS_fnc_spaw private _vehicle = _vehicleArray select 0; _vehicle flyInHeight _flyInHeight; -BLWK_zeus addCuratorEditableObjects [[_vehicle],true]; +[BLWK_zeus,[[_vehicle],true]] remoteExec ["addCuratorEditableObjects",2]; diff --git a/Functions/Wave Type Libraries/Helicopter Wave Library/fn_handleHelicopterWave.sqf b/Functions/Wave Type Libraries/Helicopter Wave Lib/fn_helicopterWave_onWaveInit.sqf similarity index 71% rename from Functions/Wave Type Libraries/Helicopter Wave Library/fn_handleHelicopterWave.sqf rename to Functions/Wave Type Libraries/Helicopter Wave Lib/fn_helicopterWave_onWaveInit.sqf index 75e10874..bf96b372 100644 --- a/Functions/Wave Type Libraries/Helicopter Wave Library/fn_handleHelicopterWave.sqf +++ b/Functions/Wave Type Libraries/Helicopter Wave Lib/fn_helicopterWave_onWaveInit.sqf @@ -1,27 +1,24 @@ /* ---------------------------------------------------------------------------- -Function: BLWK_fnc_handleHelicopterWave +Function: BLWK_fnc_helicopterWave_onWaveInit Description: - This is simply an alias for the below functions. It is used to exec - both on whomever the AI handler is without using multiple remoteExecs - - Executed from "BLWK_fnc_spawnWaveEnemies" + Spawns helicopters for a helicopter wave. Parameters: - NONE + NONE Returns: - NOTHING + NOTHING Examples: (begin example) - call BLWK_fnc_handleHelicopterWave; + call BLWK_fnc_helicopterWave_onWaveInit; (end) Author(s): - Ansible2 // Cipher + Ansible2 ---------------------------------------------------------------------------- */ -scriptName "BLWK_fnc_handleHelicopterWave"; +scriptName "BLWK_fnc_helicopterWave_onWaveInit"; #define DEFAULT_TRANSPORT_HELI "B_Heli_Transport_01_F" #define DEFAULT_ATTACK_HELI "O_Heli_Attack_02_dynamicLoadout_F" @@ -29,8 +26,6 @@ scriptName "BLWK_fnc_handleHelicopterWave"; #define TYPE_ATTACK 7 #define MIN_WAVE_FOR_ATTACK_HELI 12 -call BLWK_fnc_createStdWaveInfantry; - private _fn_spawnHeli = { params ["_typeId","_defaultAircraft"]; @@ -42,7 +37,8 @@ private _fn_spawnHeli = { }; private _vehicleClass = _defaultAircraft; - if (_index isNotEqualTo -1) then { + private _validAircraftFound = _index isNotEqualTo -1; + if (_validAircraftFound) then { _vehicleClass = _typeArray select _index; }; @@ -59,18 +55,22 @@ private _fn_spawnHeli = { OPFOR ] call BLWK_fnc_passiveHelicopterGunner; - // loop through crew - (_vehicleArray select 1) apply { + private _crew = _vehicleArray select 1; + _crew apply { [_x] remoteExecCall ["BLWK_fnc_addToMustKillList",2]; - [_x] call BLWK_fnc_addStdEnemyManEHs; + [_x] call BLWK_fnc_spawnQueue_addManEventhandlers; + _x allowDamage true; _x setSkill 0.05; }; + + private _heli = _vehicleArray select 0; + [_heli] call BLWK_fnc_addVehicleKilledEvent; }; [[TYPE_TRANSPORT,DEFAULT_TRANSPORT_HELI],[TYPE_ATTACK,DEFAULT_ATTACK_HELI]] apply { _x call _fn_spawnHeli; // only spawn an attack helicopter after its been 12 waves - if (BLWK_currentWaveNumber < MIN_WAVE_FOR_ATTACK_HELI) exitWith {}; + if (BLWK_currentWaveNumber < MIN_WAVE_FOR_ATTACK_HELI) then { break }; }; diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_vehicles.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_vehicles.sqf index d72384a4..776b3a66 100644 --- a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_vehicles.sqf +++ b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_vehicles.sqf @@ -159,14 +159,7 @@ private _fn_spawnAVehicle = { _returnedVehicles pushBack _vehicle; - _vehicle addEventHandler ["KILLED", { - params ["_killedUnit", "", "_instigator"]; - - if (!(isNull _instigator) AND (isPlayer _instigator)) then { - // show a player hit points and add them to there score - [_killedUnit,true] remoteExecCall ["BLWK_fnc_event_killedEnemy",_instigator]; - }; - }]; + [_vehicle] call BLWK_fnc_addVehicleKilledEvent; _nextAvailableIndex }; diff --git a/Headers/descriptionEXT/Wave Types.hpp b/Headers/descriptionEXT/Wave Types.hpp index 87a0d476..dd264170 100644 --- a/Headers/descriptionEXT/Wave Types.hpp +++ b/Headers/descriptionEXT/Wave Types.hpp @@ -103,9 +103,10 @@ class BLWK_waveTypes notificationText = "The Area Was Overrun!"; toggleVariable = "BLWK_allowOverrunWave"; }; - class heliWave : suicideWave + class heliWave { - onSelected = "remoteExecCall ['BLWK_fnc_handleHelicopterWave',BLWK_theAIHandlerOwnerID]"; + creationNotificationTemplate = SPECIAL_WARNING_TEMPLATE; + onWaveInit = "BLWK_fnc_helicopterWave_onWaveInit"; notificationText = "Enemy Helicopters Inbound!"; toggleVariable = "BLWK_allowHeliWave"; }; diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 5be3aa73..cc698e39 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -218,6 +218,8 @@ class BLWK class Other { file = "Functions\Other"; + class addVehicleKilledEvent; + {}; class addACESupportMenuAction {}; class addPlayerItems @@ -305,6 +307,8 @@ class BLWK {}; class spawnQueue_popAndCreate {}; + class spawnQueue_addManEventHandlers + {}; class spawnQueue_unitKilled {}; }; @@ -433,6 +437,14 @@ class BLWK {}; }; + + class HelicoperWaveLib + { + file = "Functions\Wave Type Libraries\Helicopter Wave Lib"; + class helicoperWave_onWaveInit + {}; + }; + class HelicoperWaveLibrary { file = "Functions\Wave Type Libraries\Helicopter Wave Library"; From f5339cc89817cc21017084ee97c06ca26c5e76eb Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Tue, 11 Jul 2023 20:18:57 -0600 Subject: [PATCH 051/133] (#642): removed old helicopter wave lib --- Headers/descriptionEXT/functions.hpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index cc698e39..4aa35057 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -445,13 +445,6 @@ class BLWK {}; }; - class HelicoperWaveLibrary - { - file = "Functions\Wave Type Libraries\Helicopter Wave Library"; - class handleHelicopterWave - {}; - }; - class MortarWaveLibrary { file = "Functions\Wave Type Libraries\Mortar Wave Library"; From b4006138f9416d965f6592ed14dfa52eb3a00934 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Tue, 11 Jul 2023 20:23:59 -0600 Subject: [PATCH 052/133] (#642): updated mortar wave to new standard --- .../fn_helicopterWave_onWaveInit.sqf | 3 + .../fn_mortarWave_onWaveInit.sqf | 63 +++++++++++++++++++ .../fn_createMortarWave.sqf | 55 ---------------- .../fn_handleMortarWave.sqf | 27 -------- Headers/descriptionEXT/Wave Types.hpp | 5 +- Headers/descriptionEXT/functions.hpp | 10 ++- 6 files changed, 73 insertions(+), 90 deletions(-) create mode 100644 Functions/Wave Type Libraries/Mortar Wave Lib/fn_mortarWave_onWaveInit.sqf delete mode 100644 Functions/Wave Type Libraries/Mortar Wave Library/fn_createMortarWave.sqf delete mode 100644 Functions/Wave Type Libraries/Mortar Wave Library/fn_handleMortarWave.sqf diff --git a/Functions/Wave Type Libraries/Helicopter Wave Lib/fn_helicopterWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Helicopter Wave Lib/fn_helicopterWave_onWaveInit.sqf index bf96b372..33798dac 100644 --- a/Functions/Wave Type Libraries/Helicopter Wave Lib/fn_helicopterWave_onWaveInit.sqf +++ b/Functions/Wave Type Libraries/Helicopter Wave Lib/fn_helicopterWave_onWaveInit.sqf @@ -74,3 +74,6 @@ private _fn_spawnHeli = { // only spawn an attack helicopter after its been 12 waves if (BLWK_currentWaveNumber < MIN_WAVE_FOR_ATTACK_HELI) then { break }; }; + + +nil diff --git a/Functions/Wave Type Libraries/Mortar Wave Lib/fn_mortarWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Mortar Wave Lib/fn_mortarWave_onWaveInit.sqf new file mode 100644 index 00000000..4e46388c --- /dev/null +++ b/Functions/Wave Type Libraries/Mortar Wave Lib/fn_mortarWave_onWaveInit.sqf @@ -0,0 +1,63 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_mortarWave_onWaveInit + +Description: + + +Parameters: + NONE + +Returns: + NOTHING + +Examples: + (begin example) + call BLWK_fnc_mortarWave_onWaveInit; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_mortarWave_onWaveInit"; + +private _startingWaveUnits = call BLWK_fnc_getMustKillList; +#define MORTAR_CLASS "O_Mortar_01_F" + +[_startingWaveUnits select 0] spawn { + params ["_mortarMan"]; + + private _spawnPosition = [ + BLWK_playAreaCenter, + BLWK_playAreaRadius - 15, + BLWK_playAreaRadius - 5, + 3, + 0, + 10 + ] call BIS_fnc_findSafePos; + private _mortarTube = MORTAR_CLASS createVehicle _spawnPosition; + + [group _mortarMan] call BLWK_fnc_stopStalking; + + _mortarMan moveInGunner _mortarTube; + [BLWK_zeus,[[_mortarTube],true]] remoteExec ["addCuratorEditableObjects",2]; + + // give players a bit of time before starting + sleep 20; + + private _ammo = getArtilleryAmmo [_mortarTube] select 0; + private "_fireAtPosition"; + private _doFire = true; + while {_doFire} do { + _fireAtPosition = [BLWK_mainCrate,random 45,random 360] call CBAP_fnc_randPos; + _mortarTube doArtilleryFire [_fireAtPosition,_ammo,1]; + + sleep (random [15,20,25]); + if (!alive _mortarMan) exitWith { + deleteVehicle _mortarTube; + _doFire = false; + }; + }; +}; + + +nil diff --git a/Functions/Wave Type Libraries/Mortar Wave Library/fn_createMortarWave.sqf b/Functions/Wave Type Libraries/Mortar Wave Library/fn_createMortarWave.sqf deleted file mode 100644 index 53bff9b8..00000000 --- a/Functions/Wave Type Libraries/Mortar Wave Library/fn_createMortarWave.sqf +++ /dev/null @@ -1,55 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_createMortarWave - -Description: - Creates the mortar and starts firing at The Crate - - Executed from "BLWK_fnc_handleMortarWave" - -Parameters: - 0: _mortarMan : - The person to operate the mortar - -Returns: - NOTHING - -Examples: - (begin example) - - [aUnit] spawn BLWK_fnc_createMortarWave; - - (end) - -Author(s): - Hilltop(Willtop) & omNomios, - Modified by: Ansible2 // Cipher ----------------------------------------------------------------------------- */ -#define MORTAR_CLASS "O_Mortar_01_F" - -if (!canSuspend) exitWith {}; - -params ["_mortarMan"]; - -private _spawnPosition = [BLWK_playAreaCenter, BLWK_playAreaRadius - 15, BLWK_playAreaRadius - 5, 3, 0, 10] call BIS_fnc_findSafePos; -private _mortarTube = MORTAR_CLASS createVehicle _spawnPosition; - -[group _mortarMan] call BLWK_fnc_stopStalking; - -_mortarMan moveInGunner _mortarTube; -[BLWK_zeus,[[_mortarTube],true]] remoteExecCall ["addCuratorEditableObjects",2]; - -// give players a bit of time before starting -sleep 20; - -private _ammo = getArtilleryAmmo [_mortarTube] select 0; -private "_fireAtPosition"; -private _doFire = true; -while {_doFire} do { - _fireAtPosition = [BLWK_mainCrate,random 45,random 360] call CBAP_fnc_randPos; - _mortarTube doArtilleryFire [_fireAtPosition,_ammo,1]; - - sleep (random [15,20,25]); - if (!alive _mortarMan) exitWith { - deleteVehicle _mortarTube; - _doFire = false; - }; -}; \ No newline at end of file diff --git a/Functions/Wave Type Libraries/Mortar Wave Library/fn_handleMortarWave.sqf b/Functions/Wave Type Libraries/Mortar Wave Library/fn_handleMortarWave.sqf deleted file mode 100644 index 62fa93b1..00000000 --- a/Functions/Wave Type Libraries/Mortar Wave Library/fn_handleMortarWave.sqf +++ /dev/null @@ -1,27 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_handleMortarWave - -Description: - This is simply an alias for the below functions. It is used to exec - both on whomever the AI handler is without using multiple remoteExecs - - Executed from "BLWK_fnc_spawnWaveEnemies" - -Parameters: - NONE - -Returns: - NOTHING - -Examples: - (begin example) - - call BLWK_fnc_handleMortarWave; - - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -private _startingWaveUnits = call BLWK_fnc_createStdWaveInfantry; -[_startingWaveUnits select 0] spawn BLWK_fnc_createMortarWave; \ No newline at end of file diff --git a/Headers/descriptionEXT/Wave Types.hpp b/Headers/descriptionEXT/Wave Types.hpp index dd264170..05fc321c 100644 --- a/Headers/descriptionEXT/Wave Types.hpp +++ b/Headers/descriptionEXT/Wave Types.hpp @@ -110,9 +110,10 @@ class BLWK_waveTypes notificationText = "Enemy Helicopters Inbound!"; toggleVariable = "BLWK_allowHeliWave"; }; - class mortarWave : suicideWave + class mortarWave { - onSelected = "remoteExecCall ['BLWK_fnc_handleMortarWave',BLWK_theAIHandlerOwnerID]"; + creationNotificationTemplate = SPECIAL_WARNING_TEMPLATE; + onWaveInit = "BLWK_fnc_mortarWave_onWaveInit"; notificationText = "Incoming Mortar Fire!"; toggleVariable = "BLWK_allowMortarWave"; }; diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 4aa35057..42d03af0 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -445,15 +445,13 @@ class BLWK {}; }; - class MortarWaveLibrary + class MortarWaveLib { - file = "Functions\Wave Type Libraries\Mortar Wave Library"; - class createMortarWave - {}; - class handleMortarWave + file = "Functions\Wave Type Libraries\Mortar Wave Lib"; + class mortarWave_onWaveInit {}; }; - + class OverrunWaveLib { file = "Functions\Wave Type Libraries\Overrun Wave Lib"; From 3b0d66213a1a8eff8f37a7835c05b7bd49f65192 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Tue, 11 Jul 2023 20:26:51 -0600 Subject: [PATCH 053/133] (#642): renamed blwk_fnc_startWave to blwk_fnc_waves_start --- Functions/Waves/fn_cleanUpTheDead.sqf | 2 -- Functions/Waves/fn_getConfigForWave.sqf | 2 -- Functions/Waves/{fn_startWave.sqf => fn_waves_start.sqf} | 8 +++----- Headers/descriptionEXT/functions.hpp | 4 ++-- initServer.sqf | 2 +- 5 files changed, 6 insertions(+), 12 deletions(-) rename Functions/Waves/{fn_startWave.sqf => fn_waves_start.sqf} (92%) diff --git a/Functions/Waves/fn_cleanUpTheDead.sqf b/Functions/Waves/fn_cleanUpTheDead.sqf index 33fab679..d4b5db66 100644 --- a/Functions/Waves/fn_cleanUpTheDead.sqf +++ b/Functions/Waves/fn_cleanUpTheDead.sqf @@ -4,8 +4,6 @@ Function: BLWK_fnc_cleanUpTheDead Description: Cleans up dead bodies according to the mission param BLWK_roundsBeforeBodyDeletion. - Executed from "BLWK_fnc_startWave" - Parameters: NONE diff --git a/Functions/Waves/fn_getConfigForWave.sqf b/Functions/Waves/fn_getConfigForWave.sqf index 3e88dd24..9564754d 100644 --- a/Functions/Waves/fn_getConfigForWave.sqf +++ b/Functions/Waves/fn_getConfigForWave.sqf @@ -5,8 +5,6 @@ Description: Determines what type of wave should happen next and returns the selected wave's config. - Executed from "BLWK_fnc_startWave" - Parameters: NONE diff --git a/Functions/Waves/fn_startWave.sqf b/Functions/Waves/fn_waves_start.sqf similarity index 92% rename from Functions/Waves/fn_startWave.sqf rename to Functions/Waves/fn_waves_start.sqf index 2bc6110b..01b30838 100644 --- a/Functions/Waves/fn_startWave.sqf +++ b/Functions/Waves/fn_waves_start.sqf @@ -1,11 +1,9 @@ /* ---------------------------------------------------------------------------- -Function: BLWK_fnc_startWave +Function: BLWK_fnc_waves_start Description: Heals the player when they select the action on The Crate - Executed from "initServer.sqf" & "BLWK_fnc_endWave" - Parameters: 0: _clearDroppedItems - Will dropped items on the ground be deleted this round? @@ -14,14 +12,14 @@ Returns: Examples: (begin example) - [true] call BLWK_fnc_startWave; + [true] call BLWK_fnc_waves_start; (end) Author(s): Hilltop(Willtop) & omNomios, Modified by: Ansible2 ---------------------------------------------------------------------------- */ -scriptName "BLWK_fnc_startWave"; +scriptName "BLWK_fnc_waves_start"; if (!isServer) exitWith {}; diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 42d03af0..ff76efd1 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -531,6 +531,8 @@ class BLWK {}; class waves_isCleared {}; + class waves_start + {}; class addToMustKillList {}; @@ -549,8 +551,6 @@ class BLWK {}; class spawnLoot {}; - class startWave - {}; class startWaveCountdown {}; }; diff --git a/initServer.sqf b/initServer.sqf index 7e1dc0ae..6cc9e81c 100644 --- a/initServer.sqf +++ b/initServer.sqf @@ -29,6 +29,6 @@ if (BLWK_buildingsNearTheCrateAreIndestructable_radius > 0) then { call BLWK_fnc_startWaveCountdown; -[] spawn BLWK_fnc_startWave; +[{ [false] call BLWK_fnc_waves_start; }] call CBAP_fnc_directCall; [] spawn BLWK_fnc_arePlayersAliveLoop; From efc8302cbaea4b5e93cbae8e2be6dfcbbc469188 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Wed, 12 Jul 2023 17:05:05 -0600 Subject: [PATCH 054/133] (#642): fixed some invalid file paths for funcitons --- ...OrHostsOfError.sqf => fn_notifyAdminsOrHostOfError.sqf} | 0 Headers/descriptionEXT/functions.hpp | 7 +++---- 2 files changed, 3 insertions(+), 4 deletions(-) rename Functions/Other/{fn_notifyAdminsOrHostsOfError.sqf => fn_notifyAdminsOrHostOfError.sqf} (100%) diff --git a/Functions/Other/fn_notifyAdminsOrHostsOfError.sqf b/Functions/Other/fn_notifyAdminsOrHostOfError.sqf similarity index 100% rename from Functions/Other/fn_notifyAdminsOrHostsOfError.sqf rename to Functions/Other/fn_notifyAdminsOrHostOfError.sqf diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index ff76efd1..7c278610 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -1,5 +1,4 @@ -class BLWK -{ +class BLWK{ class AiPathing { file = "functions\AI Pathing"; @@ -218,7 +217,7 @@ class BLWK class Other { file = "Functions\Other"; - class addVehicleKilledEvent; + class addVehicleKilledEvent {}; class addACESupportMenuAction {}; @@ -441,7 +440,7 @@ class BLWK class HelicoperWaveLib { file = "Functions\Wave Type Libraries\Helicopter Wave Lib"; - class helicoperWave_onWaveInit + class helicopterWave_onWaveInit {}; }; From db725396305307b776c62f89958cb4aa5b37e1e6 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Wed, 12 Jul 2023 17:05:24 -0600 Subject: [PATCH 055/133] (#642): adjusted location of addVehicleKilledHandler --- .../fn_event_addVehicleKilledHandler.sqf} | 6 +++--- .../Helicopter Wave Lib/fn_helicopterWave_onWaveInit.sqf | 2 +- .../Standard Wave Lib/fn_standardWave_vehicles.sqf | 2 +- Headers/descriptionEXT/functions.hpp | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) rename Functions/{Other/fn_addVehicleKilledEvent.sqf => Events/fn_event_addVehicleKilledHandler.sqf} (84%) diff --git a/Functions/Other/fn_addVehicleKilledEvent.sqf b/Functions/Events/fn_event_addVehicleKilledHandler.sqf similarity index 84% rename from Functions/Other/fn_addVehicleKilledEvent.sqf rename to Functions/Events/fn_event_addVehicleKilledHandler.sqf index 41baa7a7..8cbe3953 100644 --- a/Functions/Other/fn_addVehicleKilledEvent.sqf +++ b/Functions/Events/fn_event_addVehicleKilledHandler.sqf @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- -Function: BLWK_fnc_addVehicleKilledEvent +Function: BLWK_fnc_event_addVehicleKilledHandler Description: Adds a killed event a vehicle that will provide points to a player when it @@ -13,13 +13,13 @@ Returns: Examples: (begin example) - [myVehicle] call BLWK_fnc_addVehicleKilledEvent; + [myVehicle] call BLWK_fnc_event_addVehicleKilledHandler; (end) Author(s): Ansible2 ---------------------------------------------------------------------------- */ -scriptName "BLWK_fnc_addVehicleKilledEvent"; +scriptName "BLWK_fnc_event_addVehicleKilledHandler"; params [ ["_vehicle",objNull,[objNull]] diff --git a/Functions/Wave Type Libraries/Helicopter Wave Lib/fn_helicopterWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Helicopter Wave Lib/fn_helicopterWave_onWaveInit.sqf index 33798dac..d99fbf29 100644 --- a/Functions/Wave Type Libraries/Helicopter Wave Lib/fn_helicopterWave_onWaveInit.sqf +++ b/Functions/Wave Type Libraries/Helicopter Wave Lib/fn_helicopterWave_onWaveInit.sqf @@ -65,7 +65,7 @@ private _fn_spawnHeli = { }; private _heli = _vehicleArray select 0; - [_heli] call BLWK_fnc_addVehicleKilledEvent; + [_heli] call BLWK_fnc_event_addVehicleKilledHandler; }; diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_vehicles.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_vehicles.sqf index 776b3a66..b5db87df 100644 --- a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_vehicles.sqf +++ b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_vehicles.sqf @@ -159,7 +159,7 @@ private _fn_spawnAVehicle = { _returnedVehicles pushBack _vehicle; - [_vehicle] call BLWK_fnc_addVehicleKilledEvent; + [_vehicle] call BLWK_fnc_event_addVehicleKilledHandler; _nextAvailableIndex }; diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 7c278610..797e7c6a 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -217,8 +217,6 @@ class BLWK{ class Other { file = "Functions\Other"; - class addVehicleKilledEvent - {}; class addACESupportMenuAction {}; class addPlayerItems @@ -515,6 +513,8 @@ class BLWK{ {}; class event_hitEnemy {}; + class event_addVehicleKilledHandler + {}; }; class Waves From ad1b0f980df380ca3acfb196fad8b36ea871bc54 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Wed, 12 Jul 2023 17:06:37 -0600 Subject: [PATCH 056/133] (#642): fixed incorrect file path in functions.hpp and header comment --- Functions/Events/fn_event_killedEnemy.sqf | 2 +- Headers/descriptionEXT/functions.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Functions/Events/fn_event_killedEnemy.sqf b/Functions/Events/fn_event_killedEnemy.sqf index 45a22e00..e597158e 100644 --- a/Functions/Events/fn_event_killedEnemy.sqf +++ b/Functions/Events/fn_event_killedEnemy.sqf @@ -1,5 +1,5 @@ /* ---------------------------------------------------------------------------- -Function: BLWK_fnc_stdEnemyHitEventPlayer +Function: BLWK_fnc_event_killedEnemy Description: Executes from an enemy's killed eventhandler. The message is sent from whomever diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 797e7c6a..67df2233 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -508,7 +508,7 @@ class BLWK{ class Events { - file = "Functions\Wave Type Libraries\Events"; + file = "Functions\Events"; class event_killedEnemy {}; class event_hitEnemy From 30ddab1bae7c7622adbe94b133f4de2e07519943 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Wed, 12 Jul 2023 17:08:36 -0600 Subject: [PATCH 057/133] (#642): fixed all compilation issues --- Functions/Queue/fn_spawnQueue_add.sqf | 4 ++-- .../Drone Wave Lib/fn_droneWave_attackLoop.sqf | 1 - .../Suicide Wave Lib/fn_suicideWave_onWaveInit.sqf | 2 +- Functions/Waves/fn_waves_end.sqf | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Functions/Queue/fn_spawnQueue_add.sqf b/Functions/Queue/fn_spawnQueue_add.sqf index 692b9205..114ea9b9 100644 --- a/Functions/Queue/fn_spawnQueue_add.sqf +++ b/Functions/Queue/fn_spawnQueue_add.sqf @@ -29,8 +29,8 @@ scriptName "BLWK_fnc_spawnQueue_add"; params [ ["_class","",[""]], - ["_position",[],[objNull,[]]] - ["_onManCreatedFunctionName","BLWK_fnc_standardWave_onManCreated",[""]], + ["_position",[],[objNull,[]]], + ["_onManCreatedFunctionName","BLWK_fnc_standardWave_onManCreated",[""]] ]; diff --git a/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_attackLoop.sqf b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_attackLoop.sqf index bd19af22..39b91661 100644 --- a/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_attackLoop.sqf +++ b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_attackLoop.sqf @@ -72,7 +72,6 @@ while {alive _drone} do { // move back to spawn _drone move _spawnPosition; waitUntil { - if exitWith {true}; if ( !(alive _drone) OR {(_drone distance2d _spawnPosition) <= 10} diff --git a/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_onWaveInit.sqf index 3a400e3d..8e83e7b1 100644 --- a/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_onWaveInit.sqf +++ b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_onWaveInit.sqf @@ -50,7 +50,7 @@ _bombers apply { [ [0.5, 0.5, 0], [-0.5, 0.5, 0] ] ], [ - [0.1, 0.1, 0.15],, + [0.1, 0.1, 0.15], [ [0.5, -0.5, 0], [0.5, 0.5, 0] ] ], [ diff --git a/Functions/Waves/fn_waves_end.sqf b/Functions/Waves/fn_waves_end.sqf index 38cf9544..6da9479b 100644 --- a/Functions/Waves/fn_waves_end.sqf +++ b/Functions/Waves/fn_waves_end.sqf @@ -31,7 +31,7 @@ private _waveConfig = localNamespace getVariable ["BLWK_currentWaveConfig",confi private _waveEndEvent = [ _waveConfig, "onWaveEnd" -] call BLWK_fnc_waves_getFunctionFromConfig +] call BLWK_fnc_waves_getFunctionFromConfig; if (_waveEndEvent isNotEqualTo {}) then { From 5d138272d837b4c32289d332b7aa3c19992f9f2c Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Thu, 13 Jul 2023 23:51:44 -0600 Subject: [PATCH 058/133] (#642): Fixed syntax error --- Functions/Waves/fn_waves_getFunctionFromConfig.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Functions/Waves/fn_waves_getFunctionFromConfig.sqf b/Functions/Waves/fn_waves_getFunctionFromConfig.sqf index 00c4dc14..f6c862ac 100644 --- a/Functions/Waves/fn_waves_getFunctionFromConfig.sqf +++ b/Functions/Waves/fn_waves_getFunctionFromConfig.sqf @@ -39,7 +39,7 @@ scriptName "BLWK_fnc_waves_getFunctionFromConfig"; params [ ["_waveConfig",configNull,[configNull]], - ["_configProperty","",""], + ["_configProperty","",[""]], ["_justName",false,[true]], ["_allowDefault",true,[true]] ]; From 62746455d319730a5349bc5760af73192274439e Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Thu, 13 Jul 2023 23:52:40 -0600 Subject: [PATCH 059/133] (#642): Fixed logic error with standardWave man class generation and added new selectRandom syntax --- .../fn_standardWave_generateMenClassnames.sqf | 31 ++++++++++--------- Functions/Waves/fn_waves_create.sqf | 2 +- .../fn_selectRandom.sqf | 31 ++++++++++++++++--- 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_generateMenClassnames.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_generateMenClassnames.sqf index ad423494..f3afada3 100644 --- a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_generateMenClassnames.sqf +++ b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_generateMenClassnames.sqf @@ -22,28 +22,31 @@ Author(s): scriptName "BLWK_fnc_standardWave_generateMenClassnames"; -private _availableClasses = []; -// classes -_availableClasses pushback BLWK_level1Faction_menClasses; -// weight of class -_availableClasses pushBack BLWK_level1Faction_weight; +private _classes = []; +private _weights = []; + +_classes append BLWK_level1Faction_menClasses; +BLWK_level1Faction_menClasses apply { _weights pushBack BLWK_level1Faction_weight }; if (BLWK_currentWaveNumber >= BLWK_level2Faction_startWave) then { - _availableClasses pushback BLWK_level2Faction_menClasses; - _availableClasses pushBack BLWK_level2Faction_weight; + _classes append BLWK_level2Faction_menClasses; + BLWK_level2Faction_menClasses apply { _weights pushBack BLWK_level2Faction_weight }; }; if (BLWK_currentWaveNumber > BLWK_level3Faction_startWave) then { - _availableClasses pushback BLWK_level3Faction_menClasses; - _availableClasses pushBack BLWK_level3Faction_weight; + _classes append BLWK_level3Faction_menClasses; + BLWK_level3Faction_menClasses apply { _weights pushBack BLWK_level3Faction_weight }; }; if (BLWK_currentWaveNumber > BLWK_level4Faction_startWave) then { - _availableClasses pushback BLWK_level4Faction_menClasses; - _availableClasses pushBack BLWK_level4Faction_weight; + _classes append BLWK_level4Faction_menClasses; + BLWK_level4Faction_menClasses apply { _weights pushBack BLWK_level4Faction_weight }; }; if (BLWK_currentWaveNumber > BLWK_level5Faction_startWave) then { - _availableClasses pushback BLWK_level5Faction_menClasses; - _availableClasses pushBack BLWK_level5Faction_weight; + _classes append BLWK_level5Faction_menClasses; + BLWK_level5Faction_menClasses apply { _weights pushBack BLWK_level5Faction_weight }; }; -_availableClasses +[ + _classes, + _weights +] diff --git a/Functions/Waves/fn_waves_create.sqf b/Functions/Waves/fn_waves_create.sqf index be8399f6..443c0843 100644 --- a/Functions/Waves/fn_waves_create.sqf +++ b/Functions/Waves/fn_waves_create.sqf @@ -58,7 +58,7 @@ for "_i" from 1 to _totalNumEnemiesToSpawnDuringWave do { _spawnPosition_temp = call _generateSpawnPositionFunction; }; - private _class = [_availableClassnames] call KISKA_fnc_selectRandom; + private _class = [_availableClassnames,""] call KISKA_fnc_selectRandom; [ _class, _spawnPosition_temp, diff --git a/KISKA Systems/KISKA Utility Functions/fn_selectRandom.sqf b/KISKA Systems/KISKA Utility Functions/fn_selectRandom.sqf index e8c6d3a2..956f306c 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_selectRandom.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_selectRandom.sqf @@ -27,8 +27,23 @@ Examples: private _weight2 = 0.5; private _randomWeightedValue = [ - ["thing1", _weight1, - "thing2", _weight2], + [ + "thing1", _weight1, + "thing2", _weight2 + ], + "" + ] call KISKA_fnc_selectRandom; + (end) + + (begin example) + private _weight1 = 0.5; + private _weight2 = 0.5; + + private _randomWeightedValue = [ + [ + ["thing1", "thing2"], + [_weight1, _weight2] + ], "" ] call KISKA_fnc_selectRandom; (end) @@ -38,6 +53,9 @@ Author(s): ---------------------------------------------------------------------------- */ scriptName "KISKA_fnc_selectRandom"; +#define VALUES_TO_SELECT (_array select 0) +#define WEIGHTS (_array select 1) + params [ ["_array",[],[[]]], "_valueType" @@ -47,8 +65,13 @@ if (isNil "_valueType") exitWith { selectRandom _array; }; -private _weightedArray = _array isEqualTypeParams [_valueType,1]; -if (_weightedArray) exitWith { +private _isWeightedArray_syntaxOne = (_array isEqualTypeParams [[],[]]) AND ((count _array) isEqualTo 2); +if (_isWeightedArray_syntaxOne) exitWith { + VALUES_TO_SELECT selectRandomWeighted WEIGHTS; +}; + +private _isWeightedArray_syntaxTwo = _array isEqualTypeParams [_valueType,1]; +if (_isWeightedArray_syntaxTwo) exitWith { selectRandomWeighted _array; }; From 245038466acaa9d02f9314d5c432b89e0025ed9b Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Thu, 13 Jul 2023 23:58:00 -0600 Subject: [PATCH 060/133] (#642): fixed onManCreated not being called --- Functions/Waves/fn_waves_create.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Functions/Waves/fn_waves_create.sqf b/Functions/Waves/fn_waves_create.sqf index 443c0843..ce04505c 100644 --- a/Functions/Waves/fn_waves_create.sqf +++ b/Functions/Waves/fn_waves_create.sqf @@ -51,7 +51,7 @@ if (!BLWK_multipleEnemyPositions) then { private _generatManClassesFunction = [_waveConfig,"generateMenClassnames"] call BLWK_fnc_waves_getFunctionFromConfig; private _availableClassnames = call _generatManClassesFunction; private _generateSpawnPositionFunction = [_waveConfig,"generateManSpawnPosition"] call BLWK_fnc_waves_getFunctionFromConfig; -private _onManCreatedFunctionName = [_waveConfig,"generateManSpawnPosition",true] call BLWK_fnc_waves_getFunctionFromConfig; +private _onManCreatedFunctionName = [_waveConfig,"onManCreated",true] call BLWK_fnc_waves_getFunctionFromConfig; for "_i" from 1 to _totalNumEnemiesToSpawnDuringWave do { if (BLWK_multipleEnemyPositions) then { From 67295238f115e7f98e775167d6d289f4676df554 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Fri, 14 Jul 2023 00:01:01 -0600 Subject: [PATCH 061/133] (#642): fixed incorrect function call when unit is killed --- Functions/Queue/fn_spawnQueue_unitKilled.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Functions/Queue/fn_spawnQueue_unitKilled.sqf b/Functions/Queue/fn_spawnQueue_unitKilled.sqf index c44a647b..11b81250 100644 --- a/Functions/Queue/fn_spawnQueue_unitKilled.sqf +++ b/Functions/Queue/fn_spawnQueue_unitKilled.sqf @@ -23,7 +23,7 @@ scriptName "BLWK_fnc_spawnQueue_unitKilled"; if (!isServer) exitWith {}; -private _queueItem = call BLWK_fnc_popAndCreate; +private _queueItem = call BLWK_fnc_spawnQueue_popAndCreate; private _queueIsEmpty = _queueItem isEqualTo []; if (_queueIsEmpty AND {call BLWK_fnc_waves_isCleared}) then { [ From f58e974ab8386e5abfaec5b8eb290a7e64267fed Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Fri, 14 Jul 2023 00:12:08 -0600 Subject: [PATCH 062/133] (#642): fixed error for default config in getFunctionFromConfig --- Functions/Waves/fn_waves_getFunctionFromConfig.sqf | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Functions/Waves/fn_waves_getFunctionFromConfig.sqf b/Functions/Waves/fn_waves_getFunctionFromConfig.sqf index f6c862ac..84898f9e 100644 --- a/Functions/Waves/fn_waves_getFunctionFromConfig.sqf +++ b/Functions/Waves/fn_waves_getFunctionFromConfig.sqf @@ -35,13 +35,12 @@ Author(s): ---------------------------------------------------------------------------- */ scriptName "BLWK_fnc_waves_getFunctionFromConfig"; -#define DEFAULT_WAVE_CONFIG_PATH missionConfigFile >> "BLWK_waveTypes" >> "normalWaves" >> "standardWave" +#define DEFAULT_WAVE_CONFIG_PATH (missionConfigFile >> "BLWK_waveTypes" >> "normalWaves" >> "standardWave") params [ ["_waveConfig",configNull,[configNull]], ["_configProperty","",[""]], - ["_justName",false,[true]], - ["_allowDefault",true,[true]] + ["_justName",false,[true]] ]; @@ -77,7 +76,10 @@ private _requestedFunction = missionNamespace getVariable [ _requestedFunctionName, {} ]; -if (_requestedFunction isEqualTo {}) then { +if ( + (_requestedFunction isEqualTo {}) AND + (_waveConfig isNotEqualTo DEFAULT_WAVE_CONFIG_PATH) +) then { private _message = [ "Could not find function for property: ", _configProperty, From 5d681fafa0e0f8b39cd2ec99fc57b3be953ac1bf Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Fri, 14 Jul 2023 00:15:09 -0600 Subject: [PATCH 063/133] (#642): fixed undefined stalker macro on wave end --- Functions/Waves/fn_waves_end.sqf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Functions/Waves/fn_waves_end.sqf b/Functions/Waves/fn_waves_end.sqf index 6da9479b..ce546b46 100644 --- a/Functions/Waves/fn_waves_end.sqf +++ b/Functions/Waves/fn_waves_end.sqf @@ -1,3 +1,4 @@ +#include "..\..\Headers\Stalker Global Strings.hpp" /* ---------------------------------------------------------------------------- Function: BLWK_fnc_waves_end @@ -78,7 +79,7 @@ if (_factionQueue isNotEqualTo []) then { /* ---------------------------------------------------------------------------- - Revive downed players + Revive downed players ---------------------------------------------------------------------------- */ _players apply { // clear all stalkers counts From 277480a933c4d7d724fcc139170c0f8588ad4155 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Fri, 14 Jul 2023 00:24:35 -0600 Subject: [PATCH 064/133] (#642): added todo --- Functions/Waves/fn_waves_isCleared.sqf | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Functions/Waves/fn_waves_isCleared.sqf b/Functions/Waves/fn_waves_isCleared.sqf index 94adcf44..327a7dde 100644 --- a/Functions/Waves/fn_waves_isCleared.sqf +++ b/Functions/Waves/fn_waves_isCleared.sqf @@ -33,3 +33,15 @@ private _allDronesCreated = localNamespace getVariable ["BLWK_droneWave_allDrone if (!_allDronesCreated) exitWith { false }; true + + +// TODO: +// The delay between the headless client sending to the must kill array +// and the server checking that BLWK_fnc_getMustKillList has alive units +// is too large of a delay because that kill list might not be updated + +// Might be able to replace this with a total count that can be expected to have needed to +// die on the server and once it receives notice that the number it's expecting have +// perished, it will end the wave, though this might run into the same issue + +// You can duplicate this error if you kill all spawned units at once. \ No newline at end of file From c5ed0c43b0ee80ab1a5fb598939cc2750645a068 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Fri, 14 Jul 2023 21:16:56 -0600 Subject: [PATCH 065/133] (#642): fixed premature wave end when deleting units from old wave --- Functions/Queue/fn_spawnQueue_add.sqf | 5 +++ .../fn_spawnQueue_addManEventhandlers.sqf | 22 +++++++---- .../fn_spawnQueue_removeManEventhandlers.sqf | 39 +++++++++++++++++++ Functions/Queue/fn_spawnQueue_unitKilled.sqf | 3 ++ Functions/Waves/fn_waves_create.sqf | 10 ++++- Functions/Waves/fn_waves_isCleared.sqf | 21 +++++----- Headers/descriptionEXT/functions.hpp | 2 + 7 files changed, 81 insertions(+), 21 deletions(-) create mode 100644 Functions/Queue/fn_spawnQueue_removeManEventhandlers.sqf diff --git a/Functions/Queue/fn_spawnQueue_add.sqf b/Functions/Queue/fn_spawnQueue_add.sqf index 114ea9b9..83244acc 100644 --- a/Functions/Queue/fn_spawnQueue_add.sqf +++ b/Functions/Queue/fn_spawnQueue_add.sqf @@ -27,6 +27,8 @@ Author(s): ---------------------------------------------------------------------------- */ scriptName "BLWK_fnc_spawnQueue_add"; +if (!isServer) exitWith {}; + params [ ["_class","",[""]], ["_position",[],[objNull,[]]], @@ -37,5 +39,8 @@ params [ private _queue = call BLWK_fnc_spawnQueue_get; _queue pushBack _this; +private _currentRequiredKillCount = localNamespace getVariable ["BLWK_spawnQueue_requiredKillCount",0]; +localNamespace setVariable ["BLWK_spawnQueue_requiredKillCount",_currentRequiredKillCount + 1]; + nil diff --git a/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf b/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf index ec0bafcb..db70d782 100644 --- a/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf +++ b/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf @@ -3,7 +3,7 @@ Function: BLWK_fnc_spawnQueue_addManEventhandlers Description: Adds the `HIT`, `KILLED`, and `DELETED` eventhandlers that govern how units - spawn from the queue and provide points to players. + spawn from the queue and provide points to players. Parameters: 0: _unit : - The unit to add the eventhandlers to @@ -22,33 +22,41 @@ Author(s): scriptName "BLWK_fnc_spawnQueue_addManEventhandlers"; params [ - ["_unit",objNull,[objNull]] + ["_unit",objNull,[objNull]] ]; if (isNull _unit) exitWith { - ["Null unit passed!"] call KISKA_fnc_log; - nil + ["Null unit passed!"] call KISKA_fnc_log; + nil }; -_unit addEventHandler ["Hit", { +private _hitEventId = _unit addEventHandler ["Hit", { params ["_unit", "", "_damage", "_instigator"]; [_unit,_damage] remoteExec ["BLWK_fnc_event_hitEnemy",_instigator]; }]; +_unit setVariable ["BLWK_spawnQueue_hitEventId",_hitEventId]; -_unit addEventHandler ["Killed", { + +private _killedEventId = _unit addEventHandler ["Killed", { params ["_killedUnit", "", "_instigator"]; if (!(isNull _instigator) AND (isPlayer _instigator)) then { // show a player hit points and add them to there score [_killedUnit] remoteExec ["BLWK_fnc_event_killedEnemy",_instigator]; }; + [_killedUnit] call BLWK_fnc_spawnQueue_removeManEventhandlers; [] remoteExec ["BLWK_fnc_spawnQueue_unitKilled",2]; }]; +_unit setVariable ["BLWK_spawnQueue_killedEventId",_killedEventId]; + + +private _deletedEventId = _unit addEventHandler ["Deleted", { + params ["_deletedUnit"]; -_unit addEventHandler ["Deleted", { [] remoteExec ["BLWK_fnc_spawnQueue_unitKilled",2]; }]; +_unit setVariable ["BLWK_spawnQueue_deletedEventId",_deletedEventId]; nil diff --git a/Functions/Queue/fn_spawnQueue_removeManEventhandlers.sqf b/Functions/Queue/fn_spawnQueue_removeManEventhandlers.sqf new file mode 100644 index 00000000..7db1b187 --- /dev/null +++ b/Functions/Queue/fn_spawnQueue_removeManEventhandlers.sqf @@ -0,0 +1,39 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_spawnQueue_removeManEventhandlers + +Description: + Removes the `HIT`, `KILLED`, and `DELETED` eventhandlers that govern how units + spawn from the queue and provide points to players. + +Parameters: + 0: _unit : - The unit to add the eventhandlers to + +Returns: + NOTHING + +Examples: + (begin example) + [myUnit] call BLWK_fnc_spawnQueue_removeManEventhandlers; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_spawnQueue_removeManEventhandlers"; + +params [ + ["_unit",objNull,[objNull]] +]; + + +private _deletedEventId = _unit getVariable ["BLWK_spawnQueue_deletedEventId",-1]; +_unit removeEventHandler ["DELETED",_deletedEventId]; + +private _killedEventId = _unit getVariable ["BLWK_spawnQueue_killedEventId",-1]; +_unit removeEventHandler ["KILLED",_killedEventId]; + +private _hitEventId = _unit getVariable ["BLWK_spawnQueue_hitEventId",-1]; +_unit removeEventHandler ["HIT",_hitEventId]; + + +nil diff --git a/Functions/Queue/fn_spawnQueue_unitKilled.sqf b/Functions/Queue/fn_spawnQueue_unitKilled.sqf index 11b81250..b6b60e1e 100644 --- a/Functions/Queue/fn_spawnQueue_unitKilled.sqf +++ b/Functions/Queue/fn_spawnQueue_unitKilled.sqf @@ -23,6 +23,9 @@ scriptName "BLWK_fnc_spawnQueue_unitKilled"; if (!isServer) exitWith {}; +private _currentWaveKilledCount = localNamespace getVariable ["BLWK_spawnQueue_killedCount",0]; +localNamespace setVariable ["BLWK_spawnQueue_killedCount",_currentWaveKilledCount + 1]; + private _queueItem = call BLWK_fnc_spawnQueue_popAndCreate; private _queueIsEmpty = _queueItem isEqualTo []; if (_queueIsEmpty AND {call BLWK_fnc_waves_isCleared}) then { diff --git a/Functions/Waves/fn_waves_create.sqf b/Functions/Waves/fn_waves_create.sqf index ce04505c..2d7ea480 100644 --- a/Functions/Waves/fn_waves_create.sqf +++ b/Functions/Waves/fn_waves_create.sqf @@ -33,12 +33,18 @@ params [ ]; +localNamespace setVariable ["BLWK_spawnQueue_requiredKillCount",0]; +localNamespace setVariable ["BLWK_spawnQueue_killedCount",0]; /* ---------------------------------------------------------------------------- Create Queue ---------------------------------------------------------------------------- */ if (_totalNumEnemiesToSpawnDuringWave < BASE_ENEMY_NUMBER) then { - _totalNumEnemiesToSpawnDuringWave = BASE_ENEMY_NUMBER * ((BLWK_enemiesPerWaveMultiplier * BLWK_currentWaveNumber) + 1); - _totalNumEnemiesToSpawnDuringWave = _totalNumEnemiesToSpawnDuringWave + (BLWK_enemiesPerPlayerMultiplier * (count (call CBAP_fnc_players))); + _totalNumEnemiesToSpawnDuringWave = BASE_ENEMY_NUMBER * ( + (BLWK_enemiesPerWaveMultiplier * BLWK_currentWaveNumber) + 1 + ); + _totalNumEnemiesToSpawnDuringWave = _totalNumEnemiesToSpawnDuringWave + ( + BLWK_enemiesPerPlayerMultiplier * (count (call CBAP_fnc_players)) + ); _totalNumEnemiesToSpawnDuringWave = round _totalNumEnemiesToSpawnDuringWave; }; diff --git a/Functions/Waves/fn_waves_isCleared.sqf b/Functions/Waves/fn_waves_isCleared.sqf index 327a7dde..5e1c6021 100644 --- a/Functions/Waves/fn_waves_isCleared.sqf +++ b/Functions/Waves/fn_waves_isCleared.sqf @@ -20,8 +20,16 @@ Author(s): ---------------------------------------------------------------------------- */ if (!isServer) exitWith { false }; +// Given that the ai handler may have a slight delay between it and the server +/// the server will know about how many units it expects to have died during the wave +// The server will receive death notifications from the AI handler +private _numberOfUnitsKilledDuringWave = localNamespace getVariable ["BLWK_spawnQueue_killedCount",0]; +private _numberOfUnitsNeededToKillForWaveToClear = localNamespace getVariable ["BLWK_spawnQueue_requiredKillCount",0]; +if (_numberOfUnitsKilledDuringWave < _numberOfUnitsNeededToKillForWaveToClear) exitWith { false }; + if ((call BLWK_fnc_spawnQueue_get) isNotEqualTo []) exitWith { false }; + private _index = (call BLWK_fnc_getMustKillList) findIf { alive _x }; private _aUnitIsStillAlive = _index isNotEqualTo -1; if (_aUnitIsStillAlive) exitWith { false }; @@ -32,16 +40,5 @@ if (_aUnitIsStillAlive) exitWith { false }; private _allDronesCreated = localNamespace getVariable ["BLWK_droneWave_allDronesCreated",true]; if (!_allDronesCreated) exitWith { false }; -true - -// TODO: -// The delay between the headless client sending to the must kill array -// and the server checking that BLWK_fnc_getMustKillList has alive units -// is too large of a delay because that kill list might not be updated - -// Might be able to replace this with a total count that can be expected to have needed to -// die on the server and once it receives notice that the number it's expecting have -// perished, it will end the wave, though this might run into the same issue - -// You can duplicate this error if you kill all spawned units at once. \ No newline at end of file +true diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 67df2233..64f29c38 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -306,6 +306,8 @@ class BLWK{ {}; class spawnQueue_addManEventHandlers {}; + class spawnQueue_removeManEventHandlers + {}; class spawnQueue_unitKilled {}; }; From 7cc772e2e26969c86ba14f1f6501ee6e69e3ae3b Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Fri, 14 Jul 2023 23:18:30 -0600 Subject: [PATCH 066/133] (#642): adjusted formatting and language of comments --- Functions/Queue/fn_spawnQueue_removeManEventhandlers.sqf | 2 +- Functions/Waves/fn_waves_end.sqf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Functions/Queue/fn_spawnQueue_removeManEventhandlers.sqf b/Functions/Queue/fn_spawnQueue_removeManEventhandlers.sqf index 7db1b187..ec2bc889 100644 --- a/Functions/Queue/fn_spawnQueue_removeManEventhandlers.sqf +++ b/Functions/Queue/fn_spawnQueue_removeManEventhandlers.sqf @@ -6,7 +6,7 @@ Description: spawn from the queue and provide points to players. Parameters: - 0: _unit : - The unit to add the eventhandlers to + 0: _unit : - The unit to remove the eventhandlers from Returns: NOTHING diff --git a/Functions/Waves/fn_waves_end.sqf b/Functions/Waves/fn_waves_end.sqf index ce546b46..3fc23383 100644 --- a/Functions/Waves/fn_waves_end.sqf +++ b/Functions/Waves/fn_waves_end.sqf @@ -68,7 +68,7 @@ private _players = call CBAP_fnc_players; /* ---------------------------------------------------------------------------- - Handle faction changes + Handle faction changes ---------------------------------------------------------------------------- */ private _factionQueue = localNamespace getVariable ["BLWK_factionChangeQueue",[]]; if (_factionQueue isNotEqualTo []) then { From e1de87008e9bd3e17d753a48cc41521338503335 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 15 Jul 2023 14:43:44 -0600 Subject: [PATCH 067/133] (#642): format changes --- .../Init Functions/fn_prepareGlobals.sqf | 19 +++++++++++-------- .../fn_spawnQueue_addManEventhandlers.sqf | 6 +++--- Functions/Queue/fn_spawnQueue_get.sqf | 2 +- Functions/Queue/fn_spawnQueue_unitKilled.sqf | 2 +- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/Functions/Init Functions/fn_prepareGlobals.sqf b/Functions/Init Functions/fn_prepareGlobals.sqf index c1ed9b02..cc153120 100644 --- a/Functions/Init Functions/fn_prepareGlobals.sqf +++ b/Functions/Init Functions/fn_prepareGlobals.sqf @@ -5,19 +5,19 @@ Function: BLWK_fnc_prepareGlobals Description: - Does exactly what it says. Most globals in the scenario are initialized here. + Does exactly what it says. Most globals in the scenario are initialized here. - It is executed from the "initPlayerLocal.sqf & initServer.sqf". + It is executed from the "initPlayerLocal.sqf & initServer.sqf". Parameters: - NONE + NONE Returns: - Nothing + Nothing Examples: (begin example) - call BLWK_fnc_prepareGlobals + call BLWK_fnc_prepareGlobals (end) ---------------------------------------------------------------------------- */ // JIP players have wave number synced already @@ -60,7 +60,7 @@ if (isServer) then { // number should never be zero, but it can be for some time until the server has initialized waitUntil { - if (owner BLWK_theAIHandlerEntity isNotEqualTo 0) exitWith {true}; + if ((owner BLWK_theAIHandlerEntity) isNotEqualTo 0) exitWith {true}; sleep 1; false }; @@ -70,8 +70,11 @@ if (isServer) then { [["Found AI Handler with Owner ID of ",BLWK_theAIHandlerOwnerID],false] call KISKA_fnc_log; - // LOCATION LIST OPTIONS - BLWK_locations = nearestlocations [[0,0,0],["nameVillage","nameCity","nameCityCapital","nameMarine","Airport"],worldsize * sqrt 2]; + BLWK_locations = nearestlocations [ + [0,0,0], + ["nameVillage","nameCity","nameCityCapital","nameMarine","Airport"], + worldsize * sqrt 2 + ]; // for revealing loot and deleteing it at the end of the round BLWK_lootMarkers = []; diff --git a/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf b/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf index db70d782..38f125b8 100644 --- a/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf +++ b/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf @@ -33,7 +33,7 @@ if (isNull _unit) exitWith { private _hitEventId = _unit addEventHandler ["Hit", { params ["_unit", "", "_damage", "_instigator"]; - [_unit,_damage] remoteExec ["BLWK_fnc_event_hitEnemy",_instigator]; + [_unit,_damage] remoteExecCall ["BLWK_fnc_event_hitEnemy",_instigator]; }]; _unit setVariable ["BLWK_spawnQueue_hitEventId",_hitEventId]; @@ -42,7 +42,7 @@ private _killedEventId = _unit addEventHandler ["Killed", { params ["_killedUnit", "", "_instigator"]; if (!(isNull _instigator) AND (isPlayer _instigator)) then { // show a player hit points and add them to there score - [_killedUnit] remoteExec ["BLWK_fnc_event_killedEnemy",_instigator]; + [_killedUnit] remoteExecCall ["BLWK_fnc_event_killedEnemy",_instigator]; }; [_killedUnit] call BLWK_fnc_spawnQueue_removeManEventhandlers; @@ -54,7 +54,7 @@ _unit setVariable ["BLWK_spawnQueue_killedEventId",_killedEventId]; private _deletedEventId = _unit addEventHandler ["Deleted", { params ["_deletedUnit"]; - [] remoteExec ["BLWK_fnc_spawnQueue_unitKilled",2]; + [] remoteExecCall ["BLWK_fnc_spawnQueue_unitKilled",2]; }]; _unit setVariable ["BLWK_spawnQueue_deletedEventId",_deletedEventId]; diff --git a/Functions/Queue/fn_spawnQueue_get.sqf b/Functions/Queue/fn_spawnQueue_get.sqf index 3d6798dc..7d666889 100644 --- a/Functions/Queue/fn_spawnQueue_get.sqf +++ b/Functions/Queue/fn_spawnQueue_get.sqf @@ -2,7 +2,7 @@ Function: BLWK_fnc_spawnQueue_get Description: - Returns the currently queued list of entries to spawn; + Returns the currently queued list of entries to spawn. Parameters: NONE diff --git a/Functions/Queue/fn_spawnQueue_unitKilled.sqf b/Functions/Queue/fn_spawnQueue_unitKilled.sqf index b6b60e1e..bdc71e1c 100644 --- a/Functions/Queue/fn_spawnQueue_unitKilled.sqf +++ b/Functions/Queue/fn_spawnQueue_unitKilled.sqf @@ -13,7 +13,7 @@ Returns: Examples: (begin example) - [] remoteExec ["BLWK_fnc_spawnQueue_unitKilled",2]; + [] remoteExecCall ["BLWK_fnc_spawnQueue_unitKilled",2]; (end) Author(s): From d83a58a1c033b4e8086b856eab2c0fb499dc1d50 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 15 Jul 2023 18:30:42 -0600 Subject: [PATCH 068/133] (#642): refactored for limited queue groups and multiple units in group --- .../Init Functions/fn_prepareGlobals.sqf | 1 + Functions/Queue/fn_spawnQueue_add.sqf | 8 +- .../fn_spawnQueue_addManEventhandlers.sqf | 4 +- Functions/Queue/fn_spawnQueue_create.sqf | 112 ++++++++++++------ .../Queue/fn_spawnQueue_getAvailableGroup.sqf | 31 +++++ Functions/Queue/fn_spawnQueue_initGroups.sqf | 55 +++++++++ .../Queue/fn_spawnQueue_popAndCreate.sqf | 22 +++- .../fn_standardWave_onGroupCreated.sqf | 33 ++++++ Functions/Waves/fn_addToMustKillList.sqf | 24 ++-- Functions/Waves/fn_waves_create.sqf | 6 +- Headers/descriptionEXT/Wave Types.hpp | 8 ++ Headers/descriptionEXT/functions.hpp | 6 + .../fn_paramsMenu_createCtrlOfClass.sqf | 13 +- .../Headers/missionParams.hpp | 14 +++ 14 files changed, 278 insertions(+), 59 deletions(-) create mode 100644 Functions/Queue/fn_spawnQueue_getAvailableGroup.sqf create mode 100644 Functions/Queue/fn_spawnQueue_initGroups.sqf create mode 100644 Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onGroupCreated.sqf diff --git a/Functions/Init Functions/fn_prepareGlobals.sqf b/Functions/Init Functions/fn_prepareGlobals.sqf index cc153120..c49fd52f 100644 --- a/Functions/Init Functions/fn_prepareGlobals.sqf +++ b/Functions/Init Functions/fn_prepareGlobals.sqf @@ -68,6 +68,7 @@ if (isServer) then { // having an owner id for the AI handler makes using setVariable remotely possible publicVariable "BLWK_theAIHandlerOwnerID"; [["Found AI Handler with Owner ID of ",BLWK_theAIHandlerOwnerID],false] call KISKA_fnc_log; + [] remoteExecCall ["BLWK_fnc_spawnQuleue_initGroups",BLWK_theAIHandlerOwnerID]; BLWK_locations = nearestlocations [ diff --git a/Functions/Queue/fn_spawnQueue_add.sqf b/Functions/Queue/fn_spawnQueue_add.sqf index 83244acc..386e7e85 100644 --- a/Functions/Queue/fn_spawnQueue_add.sqf +++ b/Functions/Queue/fn_spawnQueue_add.sqf @@ -9,6 +9,8 @@ Parameters: 1: _position : - The position to spawn the unit at 2: _onManCreatedFunctionName : - The global var name for the function to run once the unit is created on the AI handler owner machine. + 2: _onGroupCreatedFunctionName : - The global var name for the function + to run once all the units in a this unit's group have been created Returns: NOTHING @@ -18,7 +20,8 @@ Examples: [ "I_Soldier_A_F", [0,0,0], - "BLWK_fnc_standardWave_onManCreated" + "BLWK_fnc_standardWave_onManCreated", + "BLWK_fnc_standardWave_onGroupCreated" ] call BLWK_fnc_spawnQueue_add; (end) @@ -32,7 +35,8 @@ if (!isServer) exitWith {}; params [ ["_class","",[""]], ["_position",[],[objNull,[]]], - ["_onManCreatedFunctionName","BLWK_fnc_standardWave_onManCreated",[""]] + ["_onManCreatedFunctionName","BLWK_fnc_standardWave_onManCreated",[""]], + ["_onGroupCreatedFunctionName","BLWK_fnc_standardWave_onGroupCreated",[""]] ]; diff --git a/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf b/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf index 38f125b8..9c8eb4f8 100644 --- a/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf +++ b/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf @@ -46,7 +46,9 @@ private _killedEventId = _unit addEventHandler ["Killed", { }; [_killedUnit] call BLWK_fnc_spawnQueue_removeManEventhandlers; - [] remoteExec ["BLWK_fnc_spawnQueue_unitKilled",2]; + if !(isNull _killedUnit) then { + [_unit] join (localNamespace getVariable "BLWK_spawnQueue_cleanUpGroup"); + }; }]; _unit setVariable ["BLWK_spawnQueue_killedEventId",_killedEventId]; diff --git a/Functions/Queue/fn_spawnQueue_create.sqf b/Functions/Queue/fn_spawnQueue_create.sqf index f4e83df2..df89c7f6 100644 --- a/Functions/Queue/fn_spawnQueue_create.sqf +++ b/Functions/Queue/fn_spawnQueue_create.sqf @@ -2,23 +2,51 @@ Function: BLWK_fnc_spawnQueue_create Description: - Creates a unit for the wave based upon the args provided. + Creates a group of units for the wave based upon the args provided. Parameters: - 0: _class : - The classname of the unit you want to add to the queue - 1: _position : - The position to spawn the unit at - 2: _onManCreatedFunctionName : - The global var name for the function - to run once the unit is created on the AI handler owner machine. + 0: _unitCreationArgList : > An array of units + to create. The first unit's spawn position will be used and they will be the leader + of a single group for the units in the list. + + Each Array Element: + - 0: _class : - The classname of the unit you want to add to the queue + - 1: _position : - The position to spawn the unit at + - 2: _onManCreatedFunctionName : - The global var name for the function + to run once the unit is created on the AI handler owner machine. + - 3: _onManCreatedFunctionName : - The global var name for the function + to run once the unit is created on the AI handler owner machine. Returns: NOTHING Examples: (begin example) + // create a group of a single unit [ - "I_Soldier_A_F", - [0,0,0], - "BLWK_fnc_standardWave_onManCreated" + [ + "I_Soldier_A_F", + [0,0,0], + "BLWK_fnc_standardWave_onManCreated", + "BLWK_fnc_standardWave_onGroupCreated" + ] + ] call BLWK_fnc_spawnQueue_create; + (end) + (begin example) + // create a group of a two units + [ + [ + "I_Soldier_A_F", + [0,0,0], + "BLWK_fnc_standardWave_onManCreated", + "BLWK_fnc_standardWave_onGroupCreated" + ], + [ + "I_Soldier_A_F", + [0,0,0], + "BLWK_fnc_standardWave_onManCreated", + "BLWK_fnc_standardWave_onGroupCreated" + ] ] call BLWK_fnc_spawnQueue_create; (end) @@ -28,46 +56,58 @@ Author(s): scriptName "BLWK_fnc_spawnQueue_create"; params [ - ["_class","",[""]], - ["_position",[],[objNull,[]]], - ["_onManCreatedFunctionName","BLWK_fnc_standardWave_onManCreated",[""]] + ["_unitCreationArgList",[],[[]]] ]; -private _group = createGroup OPFOR; -private _unit = _group createUnit [_class, _position, [], 0, "NONE"]; -// even creating a unit for the group with createUnit does not always have them -// in that group -[_unit] joinSilent _group; -_group deleteGroupWhenEmpty true; -[_unit] call BLWK_fnc_setSkill; +if (_unitCreationArgList isEqualTo []) exitWith {}; -// keep items (maps, nvgs, binoculars, etc.) so that they can just be loot drops -removeAllAssignedItems _unit; -// for pistol only waves and randomized weapons -[_unit] call BLWK_fnc_handleEnemyWeapons; -if !(BLWK_autocombatEnabled) then { - _unit disableAI "AUTOCOMBAT"; -}; -if !(BLWK_suppressionEnabled) then { - _unit disableAI "SUPPRESSION"; -}; -if !(BLWK_doDetectMines) then { - _unit disableAI "MINEDETECTION"; -}; +private _group = call BLWK_fnc_spawnQueue_getAvailableGroup; +private _spawnPosition = (_unitCreationArgList select 0) select 1; +private _createdUnits = _unitCreationArgList apply { + _x params [ + ["_class","",[""]], + "", + ["_onManCreatedFunctionName","BLWK_fnc_standardWave_onManCreated",[""]], + ["_onGroupCreatedFunctionName","BLWK_fnc_standardWave_onGroupCreated",[""]] + ]; + private _unit = _group createUnit [_class, _spawnPosition, [], 5, "NONE"]; -[_unit] call BLWK_fnc_spawnQueue_addManEventhandlers; + [_unit] call BLWK_fnc_setSkill; + // keep items (maps, nvgs, binoculars, etc.) so that they can just be loot drops + removeAllAssignedItems _unit; + // for pistol only waves and randomized weapons + [_unit] call BLWK_fnc_handleEnemyWeapons; + + if !(BLWK_autocombatEnabled) then { + _unit disableAI "AUTOCOMBAT"; + }; + if !(BLWK_suppressionEnabled) then { + _unit disableAI "SUPPRESSION"; + }; + if !(BLWK_doDetectMines) then { + _unit disableAI "MINEDETECTION"; + }; + + [_unit] call BLWK_fnc_spawnQueue_addManEventhandlers; + [_unit] call (missionNamespace getVariable [_onManCreatedFunctionName,{}]); + + _unit +}; + +// even creating a unit for the group with createUnit does not always have them +// in that group +_createdUnits joinSilent _group; /* ---------------------------------------------------------------------------- Update server ---------------------------------------------------------------------------- */ -[_unit] remoteExecCall ["BLWK_fnc_addToMustKillList",2]; -[BLWK_zeus, [[_unit],false]] remoteExecCall ["addCuratorEditableObjects",2]; - +[_createdUnits] remoteExecCall ["BLWK_fnc_addToMustKillList",2]; +[BLWK_zeus, [_createdUnits,false]] remoteExecCall ["addCuratorEditableObjects",2]; -[_unit] call (missionNamespace getVariable [_onManCreatedFunctionName,{}]); +[_group] call (missionNamespace getVariable [_onGroupCreatedFunctionName,{}]); nil diff --git a/Functions/Queue/fn_spawnQueue_getAvailableGroup.sqf b/Functions/Queue/fn_spawnQueue_getAvailableGroup.sqf new file mode 100644 index 00000000..e0149384 --- /dev/null +++ b/Functions/Queue/fn_spawnQueue_getAvailableGroup.sqf @@ -0,0 +1,31 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_spawnQueue_getAvailableGroup + +Description: + Returns an empty group from the precreated groups for the spawn queue. + +Parameters: + NONE + +Returns: + - an empty group to use + +Examples: + (begin example) + private _group = call BLWK_fnc_spawnQueue_getAvailableGroup; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_spawnQueue_getAvailableGroup"; + +private _groupsToChooseFrom = localNamespace getVariable "BLWK_spawnQueue_groups"; +private _groupIndex = _groupsToChooseFrom findIf { (count (units _x)) isEqualTo 0 }; + +if (_groupIndex < 0) then { + ["BLWK_fnc_spawnQueue_getAvailableGroup could not find any _groupIndex that had not units!",false] remoteExecCall ["KISKA_fnc_log",2]; +}; + + +_groupsToChooseFrom param [_groupIndex,(_groupIndex select 0)] diff --git a/Functions/Queue/fn_spawnQueue_initGroups.sqf b/Functions/Queue/fn_spawnQueue_initGroups.sqf new file mode 100644 index 00000000..322b6493 --- /dev/null +++ b/Functions/Queue/fn_spawnQueue_initGroups.sqf @@ -0,0 +1,55 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_spawnQueue_initGroups + +Description: + Creates the limited set of groups that the spawn queue will use during the + mission. + +Parameters: + NONE + +Returns: + NOTHING + +Examples: + (begin example) + call BLWK_fnc_spawnQueue_initGroups; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_spawnQueue_initGroups"; + +#define NUMBER_OF_GROUPS 50 + +if !(local BLWK_theAIHandlerEntity) exitWith { + [ + [ + "BLWK_fnc_spawnQueue_initGroups was called on machine where clientOwner is: ", + clientOwner, + " but BLWK_theAIHandlerEntity is not local" + ] + ] remoteExecCall ["KISKA_fnc_log",2]; + + nil +}; + +private _groups = []; +for "_i" from 1 to NUMBER_OF_GROUPS do { + _groups pushBack (createGroup [OPFOR,false]); +}; + +localNamespace setVariable ["BLWK_spawnQueue_groups",_groups]; +localNamespace setVariable ["BLWK_spawnQueue_cleanUpGroup",createGroup [OPFOR,false]]; + + + + + + +// A limited number of groups are used by the AI handler +// dead AI are moved into a group to be used for dead units on the AI handler +// Multiple AI are assigned to a given group +// Players can choose group sizes as a parameter +// stalker system rewritten to handle groups and dynamically change leader \ No newline at end of file diff --git a/Functions/Queue/fn_spawnQueue_popAndCreate.sqf b/Functions/Queue/fn_spawnQueue_popAndCreate.sqf index d2a57dd8..6d071f02 100644 --- a/Functions/Queue/fn_spawnQueue_popAndCreate.sqf +++ b/Functions/Queue/fn_spawnQueue_popAndCreate.sqf @@ -2,7 +2,7 @@ Function: BLWK_fnc_spawnQueue_popAndCreate Description: - Takes the first entry in the enemy man spawn queue, removes the item and then + Takes the first entry in creation args spawn queue, removes the item and then spawns the unit from the arguments. Parameters: @@ -25,13 +25,25 @@ scriptName "BLWK_fnc_spawnQueue_popAndCreate"; if (!isServer) exitWith {}; // check if queue is empty +private _maxGroupSize = localNamespace getVariable ["BLWK_spawnQueue_maxGroupSize",1]; +private _stagedSpawns = localNamespace getVariable ["BLWK_spawnQueue_stagedSpawns",[]]; + private _queue = localNamespace getVariable ["BLWK_spawnQueue",[]]; if (_queue isEqualTo []) exitWith { - [] + if (_stagedSpawns isNotEqualTo []) then { + localNamespace setVariable ["BLWK_spawnQueue_stagedSpawns",[]]; + [_stagedSpawns] remoteExecCall ["BLWK_fnc_spawnQueue_create",BLWK_theAIHandlerOwnerID]; + }; + + _queue }; -private _spawnArgs = _queue deleteAt 0; -_spawnArgs remoteExecCall ["BLWK_fnc_spawnQueue_create",BLWK_theAIHandlerOwnerID]; + +private _insertedIndex = _stagedSpawns pushBack (_queue deleteAt 0); +if ((_insertedIndex + 1) isEqualTo _maxGroupSize) then { + localNamespace setVariable ["BLWK_spawnQueue_stagedSpawns",[]]; + [_stagedSpawns] remoteExecCall ["BLWK_fnc_spawnQueue_create",BLWK_theAIHandlerOwnerID]; +}; -_spawnArgs +_queue diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onGroupCreated.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onGroupCreated.sqf new file mode 100644 index 00000000..36bf2be7 --- /dev/null +++ b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onGroupCreated.sqf @@ -0,0 +1,33 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_standardWave_onGroupCreated + +Description: + Inits code specific to when a group is created for the common standard wave. + +Parameters: + 0: _group : - The created group + +Returns: + NOTHING + +Examples: + (begin example) + [group _unit] call BLWK_fnc_standardWave_onGroupCreated; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_standardWave_onGroupCreated"; + +params [ + ["_group",grpNull,[grpNull]] +]; + +// private _group = group _unit; +// [_group] spawn BLWK_fnc_pathing_mainLoop; +// [_unit] spawn BLWK_fnc_pathing_collisionLoop; +// [_group] spawn BLWK_fnc_startStalkingPlayers; + + +nil diff --git a/Functions/Waves/fn_addToMustKillList.sqf b/Functions/Waves/fn_addToMustKillList.sqf index 12782e56..b6b50d70 100644 --- a/Functions/Waves/fn_addToMustKillList.sqf +++ b/Functions/Waves/fn_addToMustKillList.sqf @@ -2,18 +2,18 @@ Function: BLWK_fnc_addToMustKillList Description: - Adds a unit to the server's global array that keeps track of what units need + Adds a number of units to the server's global array that keeps track of what units need to be killed before the round can be done. Parameters: - 0: _unitToAdd : - The unit to add + 0: _unitsToAdd : - The units to add Returns: NOTHING Examples: (begin example) - [myUnit] call BLWK_fnc_addToMustKillList; + [[myUnit,aSecondUnit]] call BLWK_fnc_addToMustKillList; (end) Author(s): @@ -22,14 +22,18 @@ Author(s): if (!isServer) exitWith {}; params [ - ["_unitToAdd",objNull,[objNull]] + ["_unitsToAdd",[],[[]]] ]; -if (isNull _unitToAdd) exitWith { - ["A null unit was passed..."] call KISKA_fnc_log; - nil + +private _currentList = call BLWK_fnc_getMustKillList; +_unitsToAdd apply { + if (isNull _x) exitWith { + ["A null unit was passed..."] call KISKA_fnc_log; + continue + }; + + _currentList pushBackUnique _x; }; -private _currentArray = call BLWK_fnc_getMustKillList; -_currentArray pushBackUnique _unitToAdd; -localNamespace setVariable ["BLWK_mustKillList",_currentArray]; +localNamespace setVariable ["BLWK_mustKillList",_currentList]; diff --git a/Functions/Waves/fn_waves_create.sqf b/Functions/Waves/fn_waves_create.sqf index 2d7ea480..b36fc694 100644 --- a/Functions/Waves/fn_waves_create.sqf +++ b/Functions/Waves/fn_waves_create.sqf @@ -57,7 +57,8 @@ if (!BLWK_multipleEnemyPositions) then { private _generatManClassesFunction = [_waveConfig,"generateMenClassnames"] call BLWK_fnc_waves_getFunctionFromConfig; private _availableClassnames = call _generatManClassesFunction; private _generateSpawnPositionFunction = [_waveConfig,"generateManSpawnPosition"] call BLWK_fnc_waves_getFunctionFromConfig; -private _onManCreatedFunctionName = [_waveConfig,"onManCreated",true] call BLWK_fnc_waves_getFunctionFromConfig; +private _onManCreatedFunctionName = [_waveConfig,"onManCreated"] call BLWK_fnc_waves_getFunctionFromConfig; +private _onGroupCreatedFunctionName = [_waveConfig,"onGroupCreated"] call BLWK_fnc_waves_getFunctionFromConfig; for "_i" from 1 to _totalNumEnemiesToSpawnDuringWave do { if (BLWK_multipleEnemyPositions) then { @@ -68,7 +69,8 @@ for "_i" from 1 to _totalNumEnemiesToSpawnDuringWave do { [ _class, _spawnPosition_temp, - _onManCreatedFunctionName + _onManCreatedFunctionName, + _onGroupCreatedFunctionName ] call BLWK_fnc_spawnQueue_add; }; diff --git a/Headers/descriptionEXT/Wave Types.hpp b/Headers/descriptionEXT/Wave Types.hpp index 05fc321c..66c4b908 100644 --- a/Headers/descriptionEXT/Wave Types.hpp +++ b/Headers/descriptionEXT/Wave Types.hpp @@ -34,6 +34,14 @@ class BLWK_waveTypes // Parameters: /// 0: - the unit created onManCreated = "BLWK_fnc_standardWave_onManCreated"; + + // The name of a missionNamespace variable that must be code. + // Runs once a group is created from the queue of enemies to spawn (and all its units have been created). + // Executes on the AI Handler (either headless or server) + // (see BLWK_fnc_spawnQueue_create for context) + // Parameters: + /// 0: - the created group + onGroupCreated = "BLWK_fnc_standardWave_onGroupCreated"; // uncompiled code that is run on the server when the wave is ended //onWaveEnd = ""; diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 64f29c38..fd44b2be 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -300,8 +300,12 @@ class BLWK{ {}; class spawnQueue_get {}; + class spawnQueue_getAvailableGroup + {}; class spawnQueue_create {}; + class spawnQueue_initGroups + {}; class spawnQueue_popAndCreate {}; class spawnQueue_addManEventHandlers @@ -500,6 +504,8 @@ class BLWK{ {}; class standardWave_generateMenClassnames {}; + class standardWave_onGroupCreated + {}; class standardWave_onManCreated {}; class standardWave_onWaveInit diff --git a/KISKA Systems/KISKA Parameter Menu/Functions/ParamAdjustments/fn_paramsMenu_createCtrlOfClass.sqf b/KISKA Systems/KISKA Parameter Menu/Functions/ParamAdjustments/fn_paramsMenu_createCtrlOfClass.sqf index fdfe9b27..9cbf2bd4 100644 --- a/KISKA Systems/KISKA Parameter Menu/Functions/ParamAdjustments/fn_paramsMenu_createCtrlOfClass.sqf +++ b/KISKA Systems/KISKA Parameter Menu/Functions/ParamAdjustments/fn_paramsMenu_createCtrlOfClass.sqf @@ -68,9 +68,16 @@ private _paramTitle_ctrl = _paramControlGroup controlsGroupCtrl PARAM_MENU_ROW_T _paramTitle_ctrl ctrlSetText (getText(_paramConfig >> "title")); private _joinStringArray = []; -private _configToolTipText = getText(_paramConfig >> "tooltip"); -if (_configToolTipText isNotEqualTo "") then { - _joinStringArray pushBack _configToolTipText; +private _toolTipConfig = _paramConfig >> "tooltip"; +if !(isNull _toolTipConfig) then { + private _toolTipText = _toolTipConfig call BIS_fnc_getCfgData; + if (_toolTipText isEqualType []) then { + _toolTipText = _toolTipText joinString "\n"; + }; + + if (_toolTipText isNotEqualTo "") then { + _joinStringArray pushBack _toolTipText; + }; }; // OPTIMIZE check if restart bool should be cached and also use when broadcasting to see if it is worth broadcasting a change that won't even take affect diff --git a/KISKA Systems/KISKA Parameter Menu/Headers/missionParams.hpp b/KISKA Systems/KISKA Parameter Menu/Headers/missionParams.hpp index 124f94f9..2ad7b275 100644 --- a/KISKA Systems/KISKA Parameter Menu/Headers/missionParams.hpp +++ b/KISKA Systems/KISKA Parameter Menu/Headers/missionParams.hpp @@ -75,6 +75,20 @@ class KISKA_missionParams { title = "Enemy AI"; + class BLWK_spawnQueue_maxGroupSize : sliderParamBase + { + title = "Max Enemy Group Size"; + tooltip[] = { + "Controls the number of units that will be in each group when spawned.", + "If it is 1, every time a unit is killed and there is another unit in the queue, the queued unit will be spawned.", + "If it is 2, for example, two units must die (or the queue must be empty) before a new group of 2 units spawn." + }; + default = 4; + namespace = 1; + max = 12; + min = 1; + }; + class BLWK_doDetectCollision : yes_no_paramBase { title = "Run Enemy AI Collision Script?"; From ba60b6d22be5ac08f08e075e6f0b636c001c9973 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 15 Jul 2023 18:31:42 -0600 Subject: [PATCH 069/133] (#642): fixed incorrect args passed to function --- Functions/Waves/fn_waves_create.sqf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Functions/Waves/fn_waves_create.sqf b/Functions/Waves/fn_waves_create.sqf index b36fc694..8c5ec578 100644 --- a/Functions/Waves/fn_waves_create.sqf +++ b/Functions/Waves/fn_waves_create.sqf @@ -57,8 +57,8 @@ if (!BLWK_multipleEnemyPositions) then { private _generatManClassesFunction = [_waveConfig,"generateMenClassnames"] call BLWK_fnc_waves_getFunctionFromConfig; private _availableClassnames = call _generatManClassesFunction; private _generateSpawnPositionFunction = [_waveConfig,"generateManSpawnPosition"] call BLWK_fnc_waves_getFunctionFromConfig; -private _onManCreatedFunctionName = [_waveConfig,"onManCreated"] call BLWK_fnc_waves_getFunctionFromConfig; -private _onGroupCreatedFunctionName = [_waveConfig,"onGroupCreated"] call BLWK_fnc_waves_getFunctionFromConfig; +private _onManCreatedFunctionName = [_waveConfig,"onManCreated",true] call BLWK_fnc_waves_getFunctionFromConfig; +private _onGroupCreatedFunctionName = [_waveConfig,"onGroupCreated",true] call BLWK_fnc_waves_getFunctionFromConfig; for "_i" from 1 to _totalNumEnemiesToSpawnDuringWave do { if (BLWK_multipleEnemyPositions) then { From 6a6c47b18d4022608401024bc0c299ccaea73748 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 15 Jul 2023 19:06:32 -0600 Subject: [PATCH 070/133] (#642): fixed syntax errors that causes units not to spawn --- Functions/Init Functions/fn_prepareGlobals.sqf | 2 +- Functions/Queue/fn_spawnQueue_create.sqf | 6 +++--- Functions/Queue/fn_spawnQueue_getAvailableGroup.sqf | 2 +- Functions/Queue/fn_spawnQueue_popAndCreate.sqf | 11 ++++++++--- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Functions/Init Functions/fn_prepareGlobals.sqf b/Functions/Init Functions/fn_prepareGlobals.sqf index c49fd52f..6ecf78d3 100644 --- a/Functions/Init Functions/fn_prepareGlobals.sqf +++ b/Functions/Init Functions/fn_prepareGlobals.sqf @@ -68,7 +68,7 @@ if (isServer) then { // having an owner id for the AI handler makes using setVariable remotely possible publicVariable "BLWK_theAIHandlerOwnerID"; [["Found AI Handler with Owner ID of ",BLWK_theAIHandlerOwnerID],false] call KISKA_fnc_log; - [] remoteExecCall ["BLWK_fnc_spawnQuleue_initGroups",BLWK_theAIHandlerOwnerID]; + [] remoteExecCall ["BLWK_fnc_spawnQueue_initGroups",BLWK_theAIHandlerOwnerID]; BLWK_locations = nearestlocations [ diff --git a/Functions/Queue/fn_spawnQueue_create.sqf b/Functions/Queue/fn_spawnQueue_create.sqf index df89c7f6..f9ce36c0 100644 --- a/Functions/Queue/fn_spawnQueue_create.sqf +++ b/Functions/Queue/fn_spawnQueue_create.sqf @@ -64,13 +64,13 @@ if (_unitCreationArgList isEqualTo []) exitWith {}; private _group = call BLWK_fnc_spawnQueue_getAvailableGroup; -private _spawnPosition = (_unitCreationArgList select 0) select 1; +private _firstArgSet = _unitCreationArgList select 0; +_firstArgSet params ["","_spawnPosition","","_onGroupCreatedFunctionName"]; private _createdUnits = _unitCreationArgList apply { _x params [ ["_class","",[""]], "", - ["_onManCreatedFunctionName","BLWK_fnc_standardWave_onManCreated",[""]], - ["_onGroupCreatedFunctionName","BLWK_fnc_standardWave_onGroupCreated",[""]] + ["_onManCreatedFunctionName","BLWK_fnc_standardWave_onManCreated",[""]] ]; private _unit = _group createUnit [_class, _spawnPosition, [], 5, "NONE"]; diff --git a/Functions/Queue/fn_spawnQueue_getAvailableGroup.sqf b/Functions/Queue/fn_spawnQueue_getAvailableGroup.sqf index e0149384..f306dff5 100644 --- a/Functions/Queue/fn_spawnQueue_getAvailableGroup.sqf +++ b/Functions/Queue/fn_spawnQueue_getAvailableGroup.sqf @@ -28,4 +28,4 @@ if (_groupIndex < 0) then { }; -_groupsToChooseFrom param [_groupIndex,(_groupIndex select 0)] +_groupsToChooseFrom param [_groupIndex,(_groupsToChooseFrom select 0)] diff --git a/Functions/Queue/fn_spawnQueue_popAndCreate.sqf b/Functions/Queue/fn_spawnQueue_popAndCreate.sqf index 6d071f02..6ef20252 100644 --- a/Functions/Queue/fn_spawnQueue_popAndCreate.sqf +++ b/Functions/Queue/fn_spawnQueue_popAndCreate.sqf @@ -24,9 +24,13 @@ scriptName "BLWK_fnc_spawnQueue_popAndCreate"; if (!isServer) exitWith {}; -// check if queue is empty -private _maxGroupSize = localNamespace getVariable ["BLWK_spawnQueue_maxGroupSize",1]; -private _stagedSpawns = localNamespace getVariable ["BLWK_spawnQueue_stagedSpawns",[]]; +private _stagedSpawns = localNamespace getVariable ["BLWK_spawnQueue_stagedSpawns",-1]; +private _stagedIsUninitialized = _stagedSpawns isEqualTo -1; +if (_stagedIsUninitialized) then { + _stagedSpawns = []; + localNamespace setVariable ["BLWK_spawnQueue_stagedSpawns",_stagedSpawns]; +}; + private _queue = localNamespace getVariable ["BLWK_spawnQueue",[]]; if (_queue isEqualTo []) exitWith { @@ -39,6 +43,7 @@ if (_queue isEqualTo []) exitWith { }; +private _maxGroupSize = localNamespace getVariable ["BLWK_spawnQueue_maxGroupSize",1]; private _insertedIndex = _stagedSpawns pushBack (_queue deleteAt 0); if ((_insertedIndex + 1) isEqualTo _maxGroupSize) then { localNamespace setVariable ["BLWK_spawnQueue_stagedSpawns",[]]; From 890c696742d8f2f839a0c93b25d7f91e67032971 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 15 Jul 2023 20:38:05 -0600 Subject: [PATCH 071/133] (#642): fixed groups not being deleted after last unit is deleted --- .../fn_spawnQueue_addManEventhandlers.sqf | 25 +++++++++++- Functions/Queue/fn_spawnQueue_create.sqf | 8 +++- Functions/Queue/fn_spawnQueue_initGroups.sqf | 12 +----- Functions/Queue/fn_spawnQueue_unitKilled.sqf | 4 +- .../fn_standardWave_onManCreated.sqf | 8 ++-- KISKA Systems/KISKA Functions.hpp | 2 + .../fn_isGroupAlive.sqf | 38 +++++++++++++++++++ 7 files changed, 79 insertions(+), 18 deletions(-) create mode 100644 KISKA Systems/KISKA Utility Functions/fn_isGroupAlive.sqf diff --git a/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf b/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf index 9c8eb4f8..6d437ed4 100644 --- a/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf +++ b/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf @@ -47,8 +47,20 @@ private _killedEventId = _unit addEventHandler ["Killed", { [_killedUnit] call BLWK_fnc_spawnQueue_removeManEventhandlers; if !(isNull _killedUnit) then { - [_unit] join (localNamespace getVariable "BLWK_spawnQueue_cleanUpGroup"); + private _cleanUpGroup = localNamespace getVariable ["BLWK_spawnQueue_cleanUpGroup",grpNull]; + if (isNull _cleanUpGroup) then { + call BLWK_fnc_spawnQueue_initGroups; + }; + + private _previousGroup = group _killedUnit; + [_killedUnit] join _cleanUpGroup; + + if !([_previousGroup] call KISKA_fnc_isGroupAlive) then { + deleteGroup _previousGroup; + }; }; + + [] remoteExecCall ["BLWK_fnc_spawnQueue_unitKilled",2]; }]; _unit setVariable ["BLWK_spawnQueue_killedEventId",_killedEventId]; @@ -56,6 +68,17 @@ _unit setVariable ["BLWK_spawnQueue_killedEventId",_killedEventId]; private _deletedEventId = _unit addEventHandler ["Deleted", { params ["_deletedUnit"]; + // units do not have groups at the time of the deleted event handler + private _spawnQueueGroup = _deletedUnit getVariable ["BLWK_spawnQueue_group",grpNull]; + // game will crash if group is deleted too quickly + [_spawnQueueGroup] spawn { + params ["_spawnQueueGroup"]; + sleep 1; + if !([_spawnQueueGroup] call KISKA_fnc_isGroupAlive) then { + deleteGroup _spawnQueueGroup; + }; + }; + [] remoteExecCall ["BLWK_fnc_spawnQueue_unitKilled",2]; }]; _unit setVariable ["BLWK_spawnQueue_deletedEventId",_deletedEventId]; diff --git a/Functions/Queue/fn_spawnQueue_create.sqf b/Functions/Queue/fn_spawnQueue_create.sqf index f9ce36c0..1c1a218a 100644 --- a/Functions/Queue/fn_spawnQueue_create.sqf +++ b/Functions/Queue/fn_spawnQueue_create.sqf @@ -63,7 +63,7 @@ params [ if (_unitCreationArgList isEqualTo []) exitWith {}; -private _group = call BLWK_fnc_spawnQueue_getAvailableGroup; +private _group = createGroup [OPFOR,true]; private _firstArgSet = _unitCreationArgList select 0; _firstArgSet params ["","_spawnPosition","","_onGroupCreatedFunctionName"]; private _createdUnits = _unitCreationArgList apply { @@ -79,6 +79,7 @@ private _createdUnits = _unitCreationArgList apply { // keep items (maps, nvgs, binoculars, etc.) so that they can just be loot drops removeAllAssignedItems _unit; + // for pistol only waves and randomized weapons [_unit] call BLWK_fnc_handleEnemyWeapons; @@ -95,6 +96,11 @@ private _createdUnits = _unitCreationArgList apply { [_unit] call BLWK_fnc_spawnQueue_addManEventhandlers; [_unit] call (missionNamespace getVariable [_onManCreatedFunctionName,{}]); + // Need to keep track of group here because if unit is deleted + // They will not have a group at the time of the deleted eventhandler's + // activation, but we need to know to be able to clean up this group + _unit setVariable ["BLWK_spawnQueue_group",_group]; + _unit }; diff --git a/Functions/Queue/fn_spawnQueue_initGroups.sqf b/Functions/Queue/fn_spawnQueue_initGroups.sqf index 322b6493..0694f1c1 100644 --- a/Functions/Queue/fn_spawnQueue_initGroups.sqf +++ b/Functions/Queue/fn_spawnQueue_initGroups.sqf @@ -2,8 +2,8 @@ Function: BLWK_fnc_spawnQueue_initGroups Description: - Creates the limited set of groups that the spawn queue will use during the - mission. + Creates the clean up group used by the spawn queue units to be able to immediately + delete empty groups. Parameters: NONE @@ -21,8 +21,6 @@ Author(s): ---------------------------------------------------------------------------- */ scriptName "BLWK_fnc_spawnQueue_initGroups"; -#define NUMBER_OF_GROUPS 50 - if !(local BLWK_theAIHandlerEntity) exitWith { [ [ @@ -35,12 +33,6 @@ if !(local BLWK_theAIHandlerEntity) exitWith { nil }; -private _groups = []; -for "_i" from 1 to NUMBER_OF_GROUPS do { - _groups pushBack (createGroup [OPFOR,false]); -}; - -localNamespace setVariable ["BLWK_spawnQueue_groups",_groups]; localNamespace setVariable ["BLWK_spawnQueue_cleanUpGroup",createGroup [OPFOR,false]]; diff --git a/Functions/Queue/fn_spawnQueue_unitKilled.sqf b/Functions/Queue/fn_spawnQueue_unitKilled.sqf index bdc71e1c..754a6500 100644 --- a/Functions/Queue/fn_spawnQueue_unitKilled.sqf +++ b/Functions/Queue/fn_spawnQueue_unitKilled.sqf @@ -26,8 +26,8 @@ if (!isServer) exitWith {}; private _currentWaveKilledCount = localNamespace getVariable ["BLWK_spawnQueue_killedCount",0]; localNamespace setVariable ["BLWK_spawnQueue_killedCount",_currentWaveKilledCount + 1]; -private _queueItem = call BLWK_fnc_spawnQueue_popAndCreate; -private _queueIsEmpty = _queueItem isEqualTo []; +private _currentQueue = call BLWK_fnc_spawnQueue_popAndCreate; +private _queueIsEmpty = _currentQueue isEqualTo []; if (_queueIsEmpty AND {call BLWK_fnc_waves_isCleared}) then { [ { diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onManCreated.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onManCreated.sqf index 4df8af82..10603267 100644 --- a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onManCreated.sqf +++ b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onManCreated.sqf @@ -24,10 +24,10 @@ params [ ["_unit",objNull,[objNull]] ]; -private _group = group _unit; -[_group] spawn BLWK_fnc_pathing_mainLoop; -[_unit] spawn BLWK_fnc_pathing_collisionLoop; -[_group] spawn BLWK_fnc_startStalkingPlayers; +// private _group = group _unit; +// [_group] spawn BLWK_fnc_pathing_mainLoop; +// [_unit] spawn BLWK_fnc_pathing_collisionLoop; +// [_group] spawn BLWK_fnc_startStalkingPlayers; nil diff --git a/KISKA Systems/KISKA Functions.hpp b/KISKA Systems/KISKA Functions.hpp index 2783155f..4df788a8 100644 --- a/KISKA Systems/KISKA Functions.hpp +++ b/KISKA Systems/KISKA Functions.hpp @@ -140,6 +140,8 @@ class KISKA class idCounter {}; class isAdminOrHost + {}; + class isGroupAlive {}; class isMainMenu {}; diff --git a/KISKA Systems/KISKA Utility Functions/fn_isGroupAlive.sqf b/KISKA Systems/KISKA Utility Functions/fn_isGroupAlive.sqf new file mode 100644 index 00000000..e35125d7 --- /dev/null +++ b/KISKA Systems/KISKA Utility Functions/fn_isGroupAlive.sqf @@ -0,0 +1,38 @@ +/* ---------------------------------------------------------------------------- +Function: KISKA_fnc_isGroupAlive + +Description: + Checks if any unit in the group is alive. + +Parameters: + 0: _group - The group or a unit in that group to check the status for + +Returns: + - True if a unit in the group is alive, false otherwise + +Examples: + (begin example) + [group player] call KISKA_fnc_isGroupAlive; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "KISKA_fnc_isGroupAlive"; + +params [ + ["_group",grpNull,[grpNull,objNull]] +]; + + +if (isNull _group) exitWith {false}; + +if (_group isEqualType objNull) then { + _group = group _group; +}; + +private _units = units _group; +private _personInGroupIsAlive = (_units findIf {alive _x}) isNotEqualTo -1; + + +_personInGroupIsAlive From 413408f32556f48c9897ce7ee38bd20d13d888ea Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 16 Jul 2023 03:23:28 -0600 Subject: [PATCH 072/133] (#642): WIP refactoring stalking for new group system --- .../Other/fn_handleUnconsciousAiEvent.sqf | 1 + .../fn_stalking_canPlayerBeStalked.sqf | 31 +++ Functions/Stalking/fn_stalking_getPlayer.sqf | 48 +++++ Functions/Stalking/fn_stalking_start.sqf | 188 ++++++++++++++++++ .../fn_standardWave_onGroupCreated.sqf | 4 +- .../fn_standardWave_onManCreated.sqf | 5 +- 6 files changed, 270 insertions(+), 7 deletions(-) create mode 100644 Functions/Stalking/fn_stalking_canPlayerBeStalked.sqf create mode 100644 Functions/Stalking/fn_stalking_getPlayer.sqf create mode 100644 Functions/Stalking/fn_stalking_start.sqf diff --git a/Functions/Other/fn_handleUnconsciousAiEvent.sqf b/Functions/Other/fn_handleUnconsciousAiEvent.sqf index 015c01dc..ce697c15 100644 --- a/Functions/Other/fn_handleUnconsciousAiEvent.sqf +++ b/Functions/Other/fn_handleUnconsciousAiEvent.sqf @@ -39,6 +39,7 @@ if (clientOwner isNotEqualTo BLWK_theAIHandlerOwnerID) exitWith { nil }; +// TODO: handle stalking [ "ace_unconscious", { diff --git a/Functions/Stalking/fn_stalking_canPlayerBeStalked.sqf b/Functions/Stalking/fn_stalking_canPlayerBeStalked.sqf new file mode 100644 index 00000000..3e712e76 --- /dev/null +++ b/Functions/Stalking/fn_stalking_canPlayerBeStalked.sqf @@ -0,0 +1,31 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_stalking_canPlayerBeStalked + +Description: + Checks whether or not a player can be stalked. + +Parameters: + 0: _player : - The player unit to check + +Returns: + BOOL + +Examples: + (begin example) + private _isStalkable = [player] call BLWK_fnc_stalking_canPlayerBeStalked; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_stalking_canPlayerBeStalked"; + +params [ + ["_player",objNull,[objNull]] +]; + + +(alive _player) AND +// not incapacitated +{(incapacitatedState _player) isEqualTo ""} AND +{_player getVariable ["BLWK_stalking_canBeStalked",true]} diff --git a/Functions/Stalking/fn_stalking_getPlayer.sqf b/Functions/Stalking/fn_stalking_getPlayer.sqf new file mode 100644 index 00000000..85908700 --- /dev/null +++ b/Functions/Stalking/fn_stalking_getPlayer.sqf @@ -0,0 +1,48 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_stalking_getPlayer + +Description: + Finds the player with the least amount of stalkers that can be stalked. + +Parameters: + NONE + +Returns: + - player with least amount of stalkers or null object if none found + +Examples: + (begin example) + private _bestStalkablePlayer = call BLWK_fnc_stalking_getPlayer; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +private _players = call CBAP_fnc_players; +// sort players that can be stalked + +_players = _players select { [_x] call BLWK_fnc_stalking_canPlayerBeStalked }; +if (_players isEqualTo []) exitWith { + objNull +}; + + +private _playerStalkerCounts = []; +private ["_lowestStalkerCount","_playerWithLowestStalkers"]; +{ + private _playersCurrentStalkerCount = _x getVariable [STALKER_COUNT_VAR,0]; + _playerStalkerCounts pushBack _playersCurrentStalkerCount; + if (_forEachIndex isEqualTo 0) then { + _lowestStalkerCount = _playersCurrentStalkerCount; + _playerWithLowestStalkers = _x; + continue; + }; + + if (_playersCurrentStalkerCount < _lowestStalkerCount) then { + _lowestStalkerCount = _playersCurrentStalkerCount; + _playerWithLowestStalkers = _x; + }; +} forEach _players; + + +_playerWithLowestStalkers diff --git a/Functions/Stalking/fn_stalking_start.sqf b/Functions/Stalking/fn_stalking_start.sqf new file mode 100644 index 00000000..88a4d564 --- /dev/null +++ b/Functions/Stalking/fn_stalking_start.sqf @@ -0,0 +1,188 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_stalking_start + +Description: + Starts a group's stalking of players. + +Parameters: + 0: _stalkerGroup : - The group that will be stalking + +Returns: + NOTHING + +Examples: + (begin example) + [aStalkerGroup] call BLWK_fnc_stalking_start; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_stalking_start"; + +#define DEFAULT_POSITION (getPosATL BLWK_mainCrate) +#define UPDATE_RATE 20 +#define SWITCH_TO_MOVE_DISTANCE 50 + + +params [ + ["_stalkerGroup",grpNull,[grpNull]] +]; + + +if (isNull _stalkerGroup) exitWith { + ["_stalkerGroup is null",true] call KISKA_fnc_log; +}; + +private _playerToStalk = call BLWK_fnc_stalking_getPlayer; +if (isNull _playerToStalk) exitWith { + (leader _stalkerGroup) move DEFAULT_POSITION; +}; + + +private _currentStalkerCount = _playerToStalk getVariable ["BLWK_stalking_numberOfStalkers",0]; +_playerToStalk setVariable ["BLWK_stalking_numberOfStalkers",_currentStalkerCount + (count (units _stalkerGroup))]; +_stalkerGroup setVariable ["BLWK_stalking_doStalk",true]; +_stalkerGroup setVariable ["BLWK_stalking_stalkedPlayer",_playerToStalk]; + +private _stalkerGroupUnits = units _stalkerGroup; +_stalkerGroupUnits apply { + private _eventId = _x addEventHandler ["KILLED", { + params ["_unit"]; + + private _group = group _unit; + private _stalkedPlayer = _group getVariable [ + "BLWK_stalking_stalkedPlayer", + objNull + ]; + + if !(isNull _stalkedPlayer) then { + private _numberOfStalkers = _stalkedPlayer getVariable [ + "BLWK_stalking_numberOfStalkers", + 0 + ]; + + _numberOfStalkers = _numberOfStalkers - 1; + _stalkedPlayer setVariable [ + "BLWK_stalking_numberOfStalkers", + _numberOfStalkers max 0 + ]; + }; + }]; + + _x setVariable ["BLWK_stalking_killedEventId", _eventId]; +}; + + +[_stalkerGroup] call KISKA_fnc_clearWaypoints; + +[_stalkerGroup] spawn { + params ["_stalkerGroup"]; + + while { !(isNull _stalkerGroup) AND (_stalkerGroup getVariable ["BLWK_stalking_doStalk",false]) } do { + if !([_stalkerGroup] call KISKA_fnc_isGroupAlive) then { + [_stalkerGroup] call BLWK_fnc_stalking_stop; + break; + }; + + private _playerToStalk = _stalkerGroup getVariable ["BLWK_stalking_stalkedPlayer",objNull]; + if !(isNull _playerToStalk) then { + /* -------------------------------------- + Reset group if needed + -------------------------------------- */ + _stalkerGroupUnits = units _stalkerGroup; + private _stalkerGroupShouldUseMove = ((leader _stalkerGroup) distance2D _playerToStalk) < SWITCH_TO_MOVE_DISTANCE; + private _stalkerGroupIsUnderMoveOrders = _stalkerGroup getVariable ["BLWK_stalking_isUnderMove",false]; + if (_stalkerGroupIsUnderMoveOrders AND (!_stalkerGroupShouldUseMove)) then { + doStop _stalkerGroupUnits; + sleep 1; + _stalkerGroupUnits doFollow _stalkerLeader; + }; + + + /* -------------------------------------- + clear previous waypoints, + Waypoints are not immediately deleted so need to wait + -------------------------------------- */ + private "_waypointCount"; + waitUntil { + _waypointCount = count (waypoints _stalkerGroup); + [ + _stalkerGroup, + (_waypointCount - 1) + ] call KISKA_fnc_clearWaypoints; + + private _stalkerGroupWaypointsDeleted = _waypointCount < 2; + if (_stalkerGroupWaypointsDeleted) exitWith {true}; + + sleep 1; + + (units _stalkerGroup) isEqualTo [] + }; + + + /* -------------------------------------- + Choose between waypoint or `move` command + -------------------------------------- */ + private _hasWaypoint = _waypointCount isEqualTo 1; + if (_stalkerGroupShouldUseMove) then { + _stalkerGroup setVariable ["BLWK_stalking_isUnderMove",true]; + (leader _stalkerGroup) move (getPosATL _playerToStalk); + + if (_hasWaypoint) then { + deleteWaypoint [_stalkerGroup,0]; + }; + + } else { + _stalkerGroup setVariable ["BLWK_stalking_isUnderMove",false]; + + private _hasStalkerWaypoint = waypointName [ + _stalkerGroup, + (currentWaypoint _stalkerGroup) + ] == "BLWK_stalking_waypoint"; + + if (_hasWaypoint AND (!_hasStalkerWaypoint)) then { + [_stalkerGroup] call KISKA_fnc_clearWaypoints; + }; + + if (_hasStalkerWaypoint) then { + private _waypoint = [_stalkerGroup,0]; + _waypoint setWaypointBehaviour "AWARE"; + _waypoint setWaypointPosition [getPos _playerToStalk,5]; + + } else { + private _waypoint = [ + _stalkerGroup, + _playerToStalk, + 0, + "MOVE", + "AWARE", + "FULL" + ] call CBAP_fnc_addWaypoint; + _waypoint setWaypointName "BLWK_stalking_waypoint"; + }; + + }; + }; + + sleep UPDATE_RATE; + + /* -------------------------------------- + stop temporarily if not units to stalk + -------------------------------------- */ + if !([_playerToStalk] call BLWK_fnc_stalking_canPlayerBeStalked) then { + _playerToStalk = call BLWK_fnc_stalking_getPlayer; + }; + + if ((isNull _playerToStalk)) then { + [_stalkerGroup] call KISKA_fnc_clearWaypoints; + (leader _stalkerGroup) move DEFAULT_POSITION; + break; + }; + }; +}; + + +// TODO: be able to rebalance if a player respawns + +nil diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onGroupCreated.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onGroupCreated.sqf index 36bf2be7..29e0db7f 100644 --- a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onGroupCreated.sqf +++ b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onGroupCreated.sqf @@ -24,10 +24,8 @@ params [ ["_group",grpNull,[grpNull]] ]; -// private _group = group _unit; // [_group] spawn BLWK_fnc_pathing_mainLoop; -// [_unit] spawn BLWK_fnc_pathing_collisionLoop; -// [_group] spawn BLWK_fnc_startStalkingPlayers; +[_group] spawn BLWK_fnc_stalking_start; nil diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onManCreated.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onManCreated.sqf index 10603267..3c831fee 100644 --- a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onManCreated.sqf +++ b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onManCreated.sqf @@ -24,10 +24,7 @@ params [ ["_unit",objNull,[objNull]] ]; -// private _group = group _unit; -// [_group] spawn BLWK_fnc_pathing_mainLoop; -// [_unit] spawn BLWK_fnc_pathing_collisionLoop; -// [_group] spawn BLWK_fnc_startStalkingPlayers; +[_unit] spawn BLWK_fnc_pathing_collisionLoop; nil From 45c7307ee0c2d8072cc211907812ee93a74d6c55 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 16 Jul 2023 15:47:22 -0600 Subject: [PATCH 073/133] (#642): refactored stalker system --- Functions/Stalking/fn_stalking_getPlayer.sqf | 7 +- .../fn_stalking_queueRedistribute.sqf | 32 +++ .../fn_stalking_removeStalkedPlayer.sqf | 42 +++ .../fn_stalking_setPlayerStalkable.sqf | 41 +++ .../Stalking/fn_stalking_setStalkedPlayer.sqf | 41 +++ Functions/Stalking/fn_stalking_start.sqf | 243 ++++++++++-------- Functions/Stalking/fn_stalking_stop.sqf | 74 ++++++ Headers/descriptionEXT/functions.hpp | 12 +- 8 files changed, 375 insertions(+), 117 deletions(-) create mode 100644 Functions/Stalking/fn_stalking_queueRedistribute.sqf create mode 100644 Functions/Stalking/fn_stalking_removeStalkedPlayer.sqf create mode 100644 Functions/Stalking/fn_stalking_setPlayerStalkable.sqf create mode 100644 Functions/Stalking/fn_stalking_setStalkedPlayer.sqf create mode 100644 Functions/Stalking/fn_stalking_stop.sqf diff --git a/Functions/Stalking/fn_stalking_getPlayer.sqf b/Functions/Stalking/fn_stalking_getPlayer.sqf index 85908700..a1f4e840 100644 --- a/Functions/Stalking/fn_stalking_getPlayer.sqf +++ b/Functions/Stalking/fn_stalking_getPlayer.sqf @@ -27,11 +27,10 @@ if (_players isEqualTo []) exitWith { }; -private _playerStalkerCounts = []; -private ["_lowestStalkerCount","_playerWithLowestStalkers"]; +private _lowestStalkerCount = 1e7; +private _playerWithLowestStalkers = objNull; { - private _playersCurrentStalkerCount = _x getVariable [STALKER_COUNT_VAR,0]; - _playerStalkerCounts pushBack _playersCurrentStalkerCount; + private _playersCurrentStalkerCount = _x getVariable ["BLWK_stalking_numberOfStalkerGroups",0]; if (_forEachIndex isEqualTo 0) then { _lowestStalkerCount = _playersCurrentStalkerCount; _playerWithLowestStalkers = _x; diff --git a/Functions/Stalking/fn_stalking_queueRedistribute.sqf b/Functions/Stalking/fn_stalking_queueRedistribute.sqf new file mode 100644 index 00000000..172affdc --- /dev/null +++ b/Functions/Stalking/fn_stalking_queueRedistribute.sqf @@ -0,0 +1,32 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_stalking_queueRedistribute + +Description: + Queues a redistribute for groups that are currently stalking players to find + a new player to stalk. + +Parameters: + NONE + +Returns: + NOTHING + +Examples: + (begin example) + [] remoteExec ["BLWK_fnc_stalking_start",BLWK_theAiHandlerOwnerId]; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_stalking_queueRedistribute"; + +(groups OPFOR) apply { + private _isStalkingGroup = _x getVariable ["BLWK_stalking_doStalk",false]; + if !(_isStalkingGroup) then { continue }; + + _x setVariable ["BLWK_stalking_redistribute",true]; +}; + + +nil diff --git a/Functions/Stalking/fn_stalking_removeStalkedPlayer.sqf b/Functions/Stalking/fn_stalking_removeStalkedPlayer.sqf new file mode 100644 index 00000000..d2ed47fa --- /dev/null +++ b/Functions/Stalking/fn_stalking_removeStalkedPlayer.sqf @@ -0,0 +1,42 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_stalking_removeStalkedPlayer + +Description: + Updates a player's stalker number and sets variables on the stalker group. + +Parameters: + 0: _stalkerGroup : - The group to remove stalked player from + +Returns: + NOTHING + +Examples: + (begin example) + [aStalkerGroup] call BLWK_fnc_stalking_removeStalkedPlayer; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_stalking_removeStalkedPlayer"; + +params [ + ["_stalkerGroup",grpNull,[grpNull]] +]; + +if ((isNull _stalkerGroup) OR (isNull _playerToStalk)) exitWith { + [["Null argument passed, params are: "_this]] call KISKA_fnc_log; + nil +}; + +private _playerBeingStalked = _stalkerGroup getVariable ["BLWK_stalking_stalkedPlayer",objNull]; + +if !(isNull _playerBeingStalked) then { + private _numberOfStalkerGroups = _playerToStalk getVariable ["BLWK_stalking_numberOfStalkerGroups",0]; + _playerToStalk setVariable [ + "BLWK_stalking_numberOfStalkerGroups", + (_numberOfStalkerGroups - 1) max 0 + ]; +}; + +_stalkerGroup setVariable ["BLWK_stalking_stalkedPlayer",nil]; diff --git a/Functions/Stalking/fn_stalking_setPlayerStalkable.sqf b/Functions/Stalking/fn_stalking_setPlayerStalkable.sqf new file mode 100644 index 00000000..eb5f16b2 --- /dev/null +++ b/Functions/Stalking/fn_stalking_setPlayerStalkable.sqf @@ -0,0 +1,41 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_stalking_setPlayerStalkable + +Description: + Sets whether or not a player can be stalked. + + Changing this setting from it's previous will trigger a redistribution of AI + stalkers on all players. + +Parameters: + 0: _player : - The player to allow or disallow stalking + 1: _newSetting : - Whether or not to allow stalking + +Returns: + NOTHING + +Examples: + (begin example) + [player,false] remoteExecCall [ + "BLWK_fnc_stalking_setPlayerStalkable", + BLWK_theAiHandlerOwnerId + ]; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_stalking_setPlayerStalkable"; + +params [ + ["_player",objNull,[objNull]], + ["_newSetting",true,[true]] +]; + +// can stalked is true by default +private _previousSetting = _player getVariable ["BLWK_stalking_canBeStalked",true]; +if (_previousSetting isEqualTo _newSetting) exitWith {}; + +_player setVariable ["BLWK_stalking_canBeStalked",_newSetting]; + +call BLWK_fnc_stalking_queueRedistribute; diff --git a/Functions/Stalking/fn_stalking_setStalkedPlayer.sqf b/Functions/Stalking/fn_stalking_setStalkedPlayer.sqf new file mode 100644 index 00000000..cc1612a5 --- /dev/null +++ b/Functions/Stalking/fn_stalking_setStalkedPlayer.sqf @@ -0,0 +1,41 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_stalking_setStalkedPlayer + +Description: + Updates a player's stalker number and sets variables on the stalker group. + +Parameters: + 0: _stalkerGroup : - The group to add as a stalker + 1: _playerToStalk : - The player to set as being stalked by the group + +Returns: + NOTHING + +Examples: + (begin example) + [aStalkerGroup,player] call BLWK_fnc_stalking_setStalkedPlayer; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_stalking_setStalkedPlayer"; + +params [ + ["_stalkerGroup",grpNull,[grpNull]], + ["_playerToStalk",objNull,[objNull]] +]; + +if ((isNull _stalkerGroup) OR (isNull _playerToStalk)) exitWith { + [["Null argument passed, params are: "_this]] call KISKA_fnc_log; + nil +}; + + +[_stalkerGroup] call BLWK_fnc_stalking_removeStalkedPlayer; + + +private _currentStalkingGroupCount = _playerToStalk getVariable ["BLWK_stalking_numberOfStalkerGroups",0]; +_playerToStalk setVariable ["BLWK_stalking_numberOfStalkerGroups",_currentStalkingGroupCount + 1]; + +_stalkerGroup setVariable ["BLWK_stalking_stalkedPlayer",_playerToStalk]; diff --git a/Functions/Stalking/fn_stalking_start.sqf b/Functions/Stalking/fn_stalking_start.sqf index 88a4d564..5b9e1821 100644 --- a/Functions/Stalking/fn_stalking_start.sqf +++ b/Functions/Stalking/fn_stalking_start.sqf @@ -32,153 +32,182 @@ params [ if (isNull _stalkerGroup) exitWith { ["_stalkerGroup is null",true] call KISKA_fnc_log; + nil }; -private _playerToStalk = call BLWK_fnc_stalking_getPlayer; -if (isNull _playerToStalk) exitWith { - (leader _stalkerGroup) move DEFAULT_POSITION; -}; +// private _playerToStalk = call BLWK_fnc_stalking_getPlayer; +// if !(isNull _playerToStalk) then { +// private _currentStalkingGroupCount = _playerToStalk getVariable ["BLWK_stalking_numberOfStalkerGroups",0]; +// _playerToStalk setVariable ["BLWK_stalking_numberOfStalkerGroups",_currentStalkingGroupCount + 1]; +// _stalkerGroup setVariable ["BLWK_stalking_stalkedPlayer",_playerToStalk]; +// }; -private _currentStalkerCount = _playerToStalk getVariable ["BLWK_stalking_numberOfStalkers",0]; -_playerToStalk setVariable ["BLWK_stalking_numberOfStalkers",_currentStalkerCount + (count (units _stalkerGroup))]; _stalkerGroup setVariable ["BLWK_stalking_doStalk",true]; -_stalkerGroup setVariable ["BLWK_stalking_stalkedPlayer",_playerToStalk]; -private _stalkerGroupUnits = units _stalkerGroup; -_stalkerGroupUnits apply { - private _eventId = _x addEventHandler ["KILLED", { - params ["_unit"]; +/* ---------------------------------------------------------------------------- + Add Group Events +---------------------------------------------------------------------------- */ +private _leaderChangedEventId = _stalkerGroup addEventHandler ["LeaderChanged", { + params ["_group", "_newLeader"]; - private _group = group _unit; - private _stalkedPlayer = _group getVariable [ - "BLWK_stalking_stalkedPlayer", - objNull + if (_group getVariable ["BLWK_stalking_isUnderMove",false]) then { + private _currentMovePosition = _stalkerGroup getVariable [ + "BLWK_stalking_currentMovePosition", + DEFAULT_POSITION ]; - if !(isNull _stalkedPlayer) then { - private _numberOfStalkers = _stalkedPlayer getVariable [ - "BLWK_stalking_numberOfStalkers", - 0 - ]; - - _numberOfStalkers = _numberOfStalkers - 1; - _stalkedPlayer setVariable [ - "BLWK_stalking_numberOfStalkers", - _numberOfStalkers max 0 - ]; - }; - }]; + _newLeader move _currentMovePosition; + }; +}]; +_stalkerGroup setVariable ["BLWK_stalking_leaderChangedEventId",_leaderChangedEventId]; - _x setVariable ["BLWK_stalking_killedEventId", _eventId]; -}; +private _deletedEventId = _stalkerGroup addEventHandler ["Deleted", { + params ["_group"]; + _this call BLWK_fnc_stalking_stop; +}]; +_stalkerGroup setVariable ["BLWK_stalking_deletedEventId",_deletedEventId]; + +private _emptyEventId = _stalkerGroup addEventHandler ["Empty", { + params ["_group"]; + _this call BLWK_fnc_stalking_stop; +}]; +_stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; + + +/* ---------------------------------------------------------------------------- + Main loop +---------------------------------------------------------------------------- */ [_stalkerGroup] call KISKA_fnc_clearWaypoints; [_stalkerGroup] spawn { params ["_stalkerGroup"]; while { !(isNull _stalkerGroup) AND (_stalkerGroup getVariable ["BLWK_stalking_doStalk",false]) } do { + if !([_stalkerGroup] call KISKA_fnc_isGroupAlive) then { [_stalkerGroup] call BLWK_fnc_stalking_stop; break; }; - private _playerToStalk = _stalkerGroup getVariable ["BLWK_stalking_stalkedPlayer",objNull]; - if !(isNull _playerToStalk) then { - /* -------------------------------------- - Reset group if needed - -------------------------------------- */ - _stalkerGroupUnits = units _stalkerGroup; - private _stalkerGroupShouldUseMove = ((leader _stalkerGroup) distance2D _playerToStalk) < SWITCH_TO_MOVE_DISTANCE; - private _stalkerGroupIsUnderMoveOrders = _stalkerGroup getVariable ["BLWK_stalking_isUnderMove",false]; - if (_stalkerGroupIsUnderMoveOrders AND (!_stalkerGroupShouldUseMove)) then { - doStop _stalkerGroupUnits; - sleep 1; - _stalkerGroupUnits doFollow _stalkerLeader; - }; + private _currentPlayerBeingStalked = _stalkerGroup getVariable ["BLWK_stalking_stalkedPlayer",objNull]; + /* -------------------------------------- + verify player to stalk + -------------------------------------- */ + private _currentPlayerCanBeStalked = [_currentPlayerBeingStalked] call BLWK_fnc_stalking_canPlayerBeStalked; + private _shouldRedistribute = _stalkerGroup getVariable ["BLWK_stalking_redistribute",false]; + if ((!_currentPlayerCanBeStalked) OR _shouldRedistribute) then { + private _playerToStalk = call BLWK_fnc_stalking_getPlayer; + if (isNull _playerToStalk) then { + + if !(_stalkerGroup setVariable ["BLWK_stalking_isPatrolling",false]) then { + _stalkerGroup setVariable ["BLWK_stalking_isPatrolling",true]; + [_stalkerGroup] call KISKA_fnc_clearWaypoints; + [_stalkerGroup, DEFAULT_POSITION, 100, 3, "MOVE", "AWARE"] call CBAP_fnc_taskPatrol; + }; + + sleep UPDATE_RATE; + continue; - /* -------------------------------------- - clear previous waypoints, - Waypoints are not immediately deleted so need to wait - -------------------------------------- */ - private "_waypointCount"; - waitUntil { - _waypointCount = count (waypoints _stalkerGroup); - [ - _stalkerGroup, - (_waypointCount - 1) - ] call KISKA_fnc_clearWaypoints; - - private _stalkerGroupWaypointsDeleted = _waypointCount < 2; - if (_stalkerGroupWaypointsDeleted) exitWith {true}; - - sleep 1; + } else { + [_stalkerGroup,_playerToStalk] call BLWK_fnc_stalking_setStalkedPlayer; + _currentPlayerBeingStalked = _playerToStalk; - (units _stalkerGroup) isEqualTo [] }; + }; + + /* -------------------------------------- + Reset group if needed from `move` command + -------------------------------------- */ + private _stalkerGroupShouldUseMove = ( + (leader _stalkerGroup) distance2D _currentPlayerBeingStalked + ) < SWITCH_TO_MOVE_DISTANCE; + private _stalkerGroupIsUnderMoveOrders = _stalkerGroup getVariable ["BLWK_stalking_isUnderMove",false]; + if (_stalkerGroupIsUnderMoveOrders AND (!_stalkerGroupShouldUseMove)) then { + private _stalkerGroupUnits = units _stalkerGroup; + doStop _stalkerGroupUnits; + sleep 1; + // regroup units + _stalkerGroupUnits doFollow _stalkerLeader; + }; - /* -------------------------------------- - Choose between waypoint or `move` command - -------------------------------------- */ - private _hasWaypoint = _waypointCount isEqualTo 1; - if (_stalkerGroupShouldUseMove) then { - _stalkerGroup setVariable ["BLWK_stalking_isUnderMove",true]; - (leader _stalkerGroup) move (getPosATL _playerToStalk); - if (_hasWaypoint) then { - deleteWaypoint [_stalkerGroup,0]; - }; + /* -------------------------------------- + clear previous waypoints, + Waypoints are not immediately deleted so need to wait + -------------------------------------- */ + private "_waypointCount"; + waitUntil { + _waypointCount = count (waypoints _stalkerGroup); + [ + _stalkerGroup, + (_waypointCount - 1) + ] call KISKA_fnc_clearWaypoints; + + private _stalkerGroupWaypointsDeleted = _waypointCount < 2; + if (_stalkerGroupWaypointsDeleted) exitWith {true}; + + sleep 1; + + // prevent infinte loop + (units _stalkerGroup) isEqualTo [] + }; - } else { - _stalkerGroup setVariable ["BLWK_stalking_isUnderMove",false]; - private _hasStalkerWaypoint = waypointName [ - _stalkerGroup, - (currentWaypoint _stalkerGroup) - ] == "BLWK_stalking_waypoint"; + /* -------------------------------------- + Choose between waypoint or `move` command + -------------------------------------- */ + private _hasWaypoint = _waypointCount isEqualTo 1; + if (_stalkerGroupShouldUseMove) then { + _stalkerGroup setVariable ["BLWK_stalking_isUnderMove",true]; + + private _playerPosition = getPosATL _currentPlayerBeingStalked; + _stalkerGroup setVariable ["BLWK_stalking_currentMovePosition",_playerPosition]; + + (leader _stalkerGroup) move _playerPosition; + if (_hasWaypoint) then { + deleteWaypoint [_stalkerGroup,0]; + }; - if (_hasWaypoint AND (!_hasStalkerWaypoint)) then { - [_stalkerGroup] call KISKA_fnc_clearWaypoints; - }; + } else { + _stalkerGroup setVariable ["BLWK_stalking_isUnderMove",false]; + _stalkerGroup setVariable ["BLWK_stalking_currentMovePosition",nil]; - if (_hasStalkerWaypoint) then { - private _waypoint = [_stalkerGroup,0]; - _waypoint setWaypointBehaviour "AWARE"; - _waypoint setWaypointPosition [getPos _playerToStalk,5]; - - } else { - private _waypoint = [ - _stalkerGroup, - _playerToStalk, - 0, - "MOVE", - "AWARE", - "FULL" - ] call CBAP_fnc_addWaypoint; - _waypoint setWaypointName "BLWK_stalking_waypoint"; - }; + private _hasStalkerWaypoint = waypointName [ + _stalkerGroup, + (currentWaypoint _stalkerGroup) + ] == "BLWK_stalking_waypoint"; + private _hasWaypointThatIsNotStalkerWaypoint = _hasWaypoint AND (!_hasStalkerWaypoint); + if (_hasWaypointThatIsNotStalkerWaypoint) then { + [_stalkerGroup] call KISKA_fnc_clearWaypoints; }; - }; - sleep UPDATE_RATE; + if (_hasStalkerWaypoint) then { + private _waypoint = [_stalkerGroup,0]; + _waypoint setWaypointBehaviour "AWARE"; + _waypoint setWaypointPosition [getPos _currentPlayerBeingStalked,5]; - /* -------------------------------------- - stop temporarily if not units to stalk - -------------------------------------- */ - if !([_playerToStalk] call BLWK_fnc_stalking_canPlayerBeStalked) then { - _playerToStalk = call BLWK_fnc_stalking_getPlayer; + } else { + private _waypoint = [ + _stalkerGroup, + _currentPlayerBeingStalked, + 0, + "MOVE", + "AWARE", + "FULL" + ] call CBAP_fnc_addWaypoint; + _waypoint setWaypointName "BLWK_stalking_waypoint"; + }; }; - if ((isNull _playerToStalk)) then { - [_stalkerGroup] call KISKA_fnc_clearWaypoints; - (leader _stalkerGroup) move DEFAULT_POSITION; - break; - }; + _stalkerGroup setVariable ["BLWK_stalking_isPatrolling",false]; + + sleep UPDATE_RATE; }; }; diff --git a/Functions/Stalking/fn_stalking_stop.sqf b/Functions/Stalking/fn_stalking_stop.sqf new file mode 100644 index 00000000..59a5f19c --- /dev/null +++ b/Functions/Stalking/fn_stalking_stop.sqf @@ -0,0 +1,74 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_stalking_stop + +Description: + Stops a unit from stalking and readjusts the stalker counts for the unit + they were stalking. + +Parameters: + 0: _stalkerGroup : - The group that should stop stalking + +Returns: + NOTHING + +Examples: + (begin example) + [aStalkerGroup] call BLWK_fnc_stalking_stop; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_stalking_stop"; + +params [ + ["_stalkerGroup",grpNull,[grpNull]] +]; + + +if (isNull _stalkerGroup) exitWith { + ["_stalkerGroup is null",true] call KISKA_fnc_log; + nil +}; + +/* ---------------------------------------------------------------------------- + Clear misc variables +---------------------------------------------------------------------------- */ +_stalkerGroup setVariable ["BLWK_stalking_doStalk",nil]; +_stalkerGroup setVariable ["BLWK_stalking_currentMovePosition",nil]; +_stalkerGroup setVariable ["BLWK_stalking_isUnderMove",nil]; +_stalkerGroup setVariable ["BLWK_stalking_redistribute",nil]; +_stalkerGroup setVariable ["BLWK_stalking_isPatrolling",nil]; + + +private _hasStalkerWaypoint = waypointName [ + _stalkerGroup, + (currentWaypoint _stalkerGroup) +] == "BLWK_stalking_waypoint"; +if (_hasStalkerWaypoint) then { + [_stalkerGroup] call KISKA_fnc_clearWaypoints; +}; + + +[_stalkerGroup] call BLWK_fnc_stalking_removeStalkedPlayer; + + +/* ---------------------------------------------------------------------------- + Group events +---------------------------------------------------------------------------- */ +[ + ["BLWK_stalking_leaderChangedEventId","LeaderChanged"], + ["BLWK_stalking_deletedEventId","Deleted"], + ["BLWK_stalking_emptyEventId","Empty"] +] apply { + _x params ["_eventSaveId","_eventName"]; + + private _eventId = _stalkerGroup getVariable [ + _eventSaveId, + -1 + ]; + _stalkerGroup removeEventHandler [_eventName,_eventId]; +}; + + +nil diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index fd44b2be..e42902c1 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -400,17 +400,17 @@ class BLWK{ class Stalking { file = "Functions\Stalking"; - class adjustStalkable + class stalking_getPlayer {}; - class canUnitBeStalked + class stalking_queueRedistribute {}; - class getAPlayerToStalk + class stalking_removeStalkedPlayer {}; - class registerStalkers + class stalking_setPlayerStalkable {}; - class startStalkingPlayers + class stalking_start {}; - class stopStalking + class stalking_stop {}; }; From 5e0d99aac0080ad7b629c1455af0cc47873c0ffa Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 16 Jul 2023 16:59:07 -0600 Subject: [PATCH 074/133] (#642): updated stalker systems interaction with other systems --- Functions/AI Pathing/fn_pathing_mainLoop.sqf | 4 - .../Other/fn_handleUnconsciousAiEvent.sqf | 7 +- Functions/Queue/fn_spawnQueue_initGroups.sqf | 11 - Functions/Stalking/fn_adjustStalkable.sqf | 30 --- Functions/Stalking/fn_canUnitBeStalked.sqf | 30 --- Functions/Stalking/fn_getAPlayerToStalk.sqf | 51 ---- Functions/Stalking/fn_registerStalkers.sqf | 35 --- .../fn_stalking_queueRedistribute.sqf | 5 +- Functions/Stalking/fn_stalking_start.sqf | 18 +- .../Stalking/fn_startStalkingPlayers.sqf | 221 ------------------ Functions/Stalking/fn_stopStalking.sqf | 79 ------- Functions/Supports/fn_endAircraftGunner.sqf | 55 ++--- Functions/Supports/fn_startAircraftGunner.sqf | 5 +- .../fn_mortarWave_onWaveInit.sqf | 41 ++-- .../fn_overrunWave_onWaveInit.sqf | 8 +- Functions/Waves/fn_waves_end.sqf | 6 +- Headers/Stalker Global Strings.hpp | 5 - onPlayerRespawn.sqf | 2 +- 18 files changed, 78 insertions(+), 535 deletions(-) delete mode 100644 Functions/Stalking/fn_adjustStalkable.sqf delete mode 100644 Functions/Stalking/fn_canUnitBeStalked.sqf delete mode 100644 Functions/Stalking/fn_getAPlayerToStalk.sqf delete mode 100644 Functions/Stalking/fn_registerStalkers.sqf delete mode 100644 Functions/Stalking/fn_startStalkingPlayers.sqf delete mode 100644 Functions/Stalking/fn_stopStalking.sqf delete mode 100644 Headers/Stalker Global Strings.hpp diff --git a/Functions/AI Pathing/fn_pathing_mainLoop.sqf b/Functions/AI Pathing/fn_pathing_mainLoop.sqf index 7ad0e27f..3df884cc 100644 --- a/Functions/AI Pathing/fn_pathing_mainLoop.sqf +++ b/Functions/AI Pathing/fn_pathing_mainLoop.sqf @@ -1,4 +1,3 @@ -#include "..\..\Headers\Stalker Global Strings.hpp" /* ---------------------------------------------------------------------------- Function: BLWK_fnc_pathing_mainLoop @@ -27,9 +26,6 @@ Examples: Author(s): Ansible2 // Cipher ---------------------------------------------------------------------------- */ -// telling the unit to go to their stalked player seems to cause -// the issue of AI getting stuck too, hence why they go to the crate - #define RESET_POSITION \ [["Reset ", _groupLeader],false] call KISKA_fnc_log; \ [_groupLeader,[BLWK_mainCrate, 5] call CBAP_fnc_randPos] remoteExecCall ["move",_groupLeader]; \ diff --git a/Functions/Other/fn_handleUnconsciousAiEvent.sqf b/Functions/Other/fn_handleUnconsciousAiEvent.sqf index ce697c15..34a92076 100644 --- a/Functions/Other/fn_handleUnconsciousAiEvent.sqf +++ b/Functions/Other/fn_handleUnconsciousAiEvent.sqf @@ -2,7 +2,7 @@ Function: BLWK_fnc_handleUnconsciousAiEvent Description: - Suspends or restarts the AI pathing and stalking system depending on AI's + Suspends or restarts the AI pathing depending on AI's ACE unconscious state. Parameters: @@ -39,22 +39,19 @@ if (clientOwner isNotEqualTo BLWK_theAIHandlerOwnerID) exitWith { nil }; -// TODO: handle stalking [ "ace_unconscious", { params ["_unit","_unconscious"]; + if !(isPlayer _unit) then { _unit setVariable ["BLWK_isACEUnconscious",true]; private _group = group _unit; if (_unconscious) then { _group setVariable ["BLWK_runPathingLoop",false]; - [_group] call BLWK_fnc_stopStalking; - } else { // if waking up [_group] spawn BLWK_fnc_pathing_mainLoop; - [_group] spawn BLWK_fnc_startStalkingPlayers; }; }; diff --git a/Functions/Queue/fn_spawnQueue_initGroups.sqf b/Functions/Queue/fn_spawnQueue_initGroups.sqf index 0694f1c1..69dbf071 100644 --- a/Functions/Queue/fn_spawnQueue_initGroups.sqf +++ b/Functions/Queue/fn_spawnQueue_initGroups.sqf @@ -34,14 +34,3 @@ if !(local BLWK_theAIHandlerEntity) exitWith { }; localNamespace setVariable ["BLWK_spawnQueue_cleanUpGroup",createGroup [OPFOR,false]]; - - - - - - -// A limited number of groups are used by the AI handler -// dead AI are moved into a group to be used for dead units on the AI handler -// Multiple AI are assigned to a given group -// Players can choose group sizes as a parameter -// stalker system rewritten to handle groups and dynamically change leader \ No newline at end of file diff --git a/Functions/Stalking/fn_adjustStalkable.sqf b/Functions/Stalking/fn_adjustStalkable.sqf deleted file mode 100644 index 760482b4..00000000 --- a/Functions/Stalking/fn_adjustStalkable.sqf +++ /dev/null @@ -1,30 +0,0 @@ -#include "..\..\Headers\Stalker Global Strings.hpp" -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_adjustStalkable - -Description: - Changes whether or not a unit/player is stalkable by the AI. - -Parameters: - 0: _unit : - The unit to adjust the state - 1: _state : - State to set, true means stalkable, false means not - -Returns: - NOTHING - -Examples: - (begin example) - - [myUnit,false] call BLWK_fnc_adjustStalkable; - - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -params [ - "_unit", - ["_state",false,[true]] -]; - -_unit setVariable [IS_UNIT_AVAILABLE_VAR,_state,BLWK_theAIHandlerOwnerID]; \ No newline at end of file diff --git a/Functions/Stalking/fn_canUnitBeStalked.sqf b/Functions/Stalking/fn_canUnitBeStalked.sqf deleted file mode 100644 index a6b13bac..00000000 --- a/Functions/Stalking/fn_canUnitBeStalked.sqf +++ /dev/null @@ -1,30 +0,0 @@ -#include "..\..\Headers\Stalker Global Strings.hpp" -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_canUnitBeStalked - -Description: - Checks whether or not a unit is able to be stalked by the AI. - -Parameters: - 0: _unitToAdd : - The unit or group to add to the array - -Returns: - BOOL - -Examples: - (begin example) - _isStalkable = [aUnit] call BLWK_fnc_canUnitBeStalked; - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -params [ - ["_unit",objNull,[objNull]] -]; - -if ((alive _unit) AND {incapacitatedState _unit isEqualTo ""} AND {_unit getVariable [IS_UNIT_AVAILABLE_VAR,true]}) then { - true -} else { - false -}; \ No newline at end of file diff --git a/Functions/Stalking/fn_getAPlayerToStalk.sqf b/Functions/Stalking/fn_getAPlayerToStalk.sqf deleted file mode 100644 index 42ed75db..00000000 --- a/Functions/Stalking/fn_getAPlayerToStalk.sqf +++ /dev/null @@ -1,51 +0,0 @@ -#include "..\..\Headers\Stalker Global Strings.hpp" -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_getAPlayerToStalk - -Description: - Finds the player with the least amount of stalkers that can be stalked. - -Parameters: - NONE - -Returns: - OBJECT - player with least amount of stalkers or null object if none found - -Examples: - (begin example) - _bestStalkablePlayer = call BLWK_fnc_getAPlayerToStalk; - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -private _players = call CBAP_fnc_players; -// sort players that can be stalked -_players = _players select {[_x] call BLWK_fnc_canUnitBeStalked}; -if (_players isEqualTo []) exitWith { - objNull -}; - -// get the player with the least amount of stalkers -private _playerStalkerCounts = []; -private ["_lowestStalkerCount","_playerWithLowestStalkers","_numberOfStalkers"]; -{ - _numberOfStalkers = _x getVariable [STALKER_COUNT_VAR,0]; - _playerStalkerCounts pushBack _numberOfStalkers; - if (_forEachIndex isEqualTo 0) then { - _lowestStalkerCount = _numberOfStalkers; - _playerWithLowestStalkers = _x; - } else { - if (_numberOfStalkers < _lowestStalkerCount) then { - _lowestStalkerCount = _numberOfStalkers; - _playerWithLowestStalkers = _x; - }; - }; -} forEach _players; - -//private _lowestStalkerCount = selectMin _playerStalkerCounts; -//private _playerWithLowestStalkers = _players select (_playerStalkerCounts findIf {_x isEqualTo _lowestStalkerCount}); - - -[["Returning player: ",_playerWithLowestStalkers," with a stalker count of: ",_lowestStalkerCount],false] call KISKA_fnc_log; -_playerWithLowestStalkers \ No newline at end of file diff --git a/Functions/Stalking/fn_registerStalkers.sqf b/Functions/Stalking/fn_registerStalkers.sqf deleted file mode 100644 index e5bb7541..00000000 --- a/Functions/Stalking/fn_registerStalkers.sqf +++ /dev/null @@ -1,35 +0,0 @@ -#include "..\..\Headers\Stalker Global Strings.hpp" -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_registerStalkers - -Description: - Registers the count of _stalkerGroup's units to the total units stalking - _unit currently so that we can track how many at any given time are stalking - a specific unit. - -Parameters: - 0: _unit : - The unit being stalked - 1: _stalkerGroup : - The group that will now be stalking the unit - -Returns: - NOTHING - -Examples: - (begin example) - - [aUnit,aStalkerGroup] call BLWK_fnc_registerStalkers; - - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -params [ - ["_unit",objNull,[objNull]], - ["_stalkerGroup",grpNull,[grpNull]] -]; - -if (isNull _unit OR {isNull _stalkerGroup}) exitWith {}; - -private _currentStalkerCount = _unit getVariable [STALKER_COUNT_VAR,0]; -_unit setVariable [STALKER_COUNT_VAR,_currentStalkerCount + (count (units _stalkerGroup))]; \ No newline at end of file diff --git a/Functions/Stalking/fn_stalking_queueRedistribute.sqf b/Functions/Stalking/fn_stalking_queueRedistribute.sqf index 172affdc..384abb80 100644 --- a/Functions/Stalking/fn_stalking_queueRedistribute.sqf +++ b/Functions/Stalking/fn_stalking_queueRedistribute.sqf @@ -13,7 +13,10 @@ Returns: Examples: (begin example) - [] remoteExec ["BLWK_fnc_stalking_start",BLWK_theAiHandlerOwnerId]; + [] remoteExec [ + "BLWK_fnc_stalking_queueRedistribute", + BLWK_theAiHandlerOwnerId + ]; (end) Author(s): diff --git a/Functions/Stalking/fn_stalking_start.sqf b/Functions/Stalking/fn_stalking_start.sqf index 5b9e1821..571ec428 100644 --- a/Functions/Stalking/fn_stalking_start.sqf +++ b/Functions/Stalking/fn_stalking_start.sqf @@ -36,13 +36,6 @@ if (isNull _stalkerGroup) exitWith { }; -// private _playerToStalk = call BLWK_fnc_stalking_getPlayer; -// if !(isNull _playerToStalk) then { -// private _currentStalkingGroupCount = _playerToStalk getVariable ["BLWK_stalking_numberOfStalkerGroups",0]; -// _playerToStalk setVariable ["BLWK_stalking_numberOfStalkerGroups",_currentStalkingGroupCount + 1]; -// _stalkerGroup setVariable ["BLWK_stalking_stalkedPlayer",_playerToStalk]; -// }; - _stalkerGroup setVariable ["BLWK_stalking_doStalk",true]; /* ---------------------------------------------------------------------------- @@ -86,12 +79,19 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; params ["_stalkerGroup"]; while { !(isNull _stalkerGroup) AND (_stalkerGroup getVariable ["BLWK_stalking_doStalk",false]) } do { - + if !([_stalkerGroup] call KISKA_fnc_isGroupAlive) then { [_stalkerGroup] call BLWK_fnc_stalking_stop; break; }; + if ( + (leader _stalkerGroup) getVariable [ + "BLWK_isACEUnconscious", + false + ] + ) then { continue }; + private _currentPlayerBeingStalked = _stalkerGroup getVariable ["BLWK_stalking_stalkedPlayer",objNull]; /* -------------------------------------- verify player to stalk @@ -212,6 +212,4 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; }; -// TODO: be able to rebalance if a player respawns - nil diff --git a/Functions/Stalking/fn_startStalkingPlayers.sqf b/Functions/Stalking/fn_startStalkingPlayers.sqf deleted file mode 100644 index 91ef6a8a..00000000 --- a/Functions/Stalking/fn_startStalkingPlayers.sqf +++ /dev/null @@ -1,221 +0,0 @@ -#include "..\..\Headers\Stalker Global Strings.hpp" -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_startStalkingPlayers - -Description: - Adds the number of a stalker group's units to the unit being stalked - total's so that they can be evenly spread across all units. - - Also adds a KILLED EH that automatically adjusts the player's stalker count. - -Parameters: - 0: _stalkerGroup : - The group that will be stalking - 1: _defaultPosition : - The position to move to if no players - 2: _checkRate : - How often to update the stalk position - 3: _conditionToEndStalking : - Code that evaluates to a boolean, if met, - it will have the units move to the _defaultPosition - -Returns: - NOTHING - -Examples: - (begin example) - [aStalkerGroup,BLWK_mainCrate,20,{false}] spawn BLWK_fnc_startStalkingPlayers; - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -scriptName "BLWK_fnc_startStalkingPlayers"; - -if (!canSuspend) exitWith { - ["Must be run in a scheduled environment. Exiting to scheduled...",true] call KISKA_fnc_log; - _this spawn BLWK_fnc_startStalkingPlayers; -}; - -params [ - ["_stalkerGroup",grpNull,[objNull,grpNull]], - ["_defaultPosition",getPosATL BLWK_mainCrate,[objNull,grpNull,[]]], - ["_checkRate",20,[123]], - ["_conditionToEndStalking",{false},[{}]] -]; - - -// verify params -if (isNull _stalkerGroup) exitWith { - ["_stalkerGroup is null",true] call KISKA_fnc_log; -}; -if (_stalkerGroup isEqualType objNull) then { - _stalkerGroup = group _stalkerGroup; -}; -if (_conditionToEndStalking isEqualTo {}) then { - _conditionToEndStalking = {false}; -}; - - -// register stalkers -private _playerToStalk = call BLWK_fnc_getAPlayerToStalk; -if (isNull _playerToStalk) exitWith { - sleep 0.5; - [_stalkerGroup, _defaultPosition] remoteExecCall ["move", groupOwner _stalkerGroup]; -}; -[_playerToStalk,_stalkerGroup] call BLWK_fnc_registerStalkers; -_stalkerGroup setVariable [DO_STALK_VAR,true]; -_stalkerGroup setVariable [STALKED_UNIT_VAR,_playerToStalk]; - - -// update units stalker numbers -private _stalkerGroupUnits = units _stalkerGroup; -_stalkerGroupUnits apply { - if !(isNull _x) then { - private _killedEventId = _x addEventHandler ["KILLED",{ - params ["_unit"]; - - private _group = group _unit; - if !(isNull _group) then { - private _stalkedPlayer = _group getVariable STALKED_UNIT_VAR; - - if !(isNull _stalkedPlayer) then { - private _numberOfStalkers = _stalkedPlayer getVariable STALKER_COUNT_VAR; - _numberOfStalkers = _numberOfStalkers - 1; - _stalkedPlayer setVariable [STALKER_COUNT_VAR,_numberOfStalkers]; - }; - - }; - }]; - - // for removal with BLWK_fnc_stopStalking - _x setVariable [UNIT_KILLED_EVENT_VAR, _killedEventId]; - }; -}; - -// FOR PATH DEBUGGING -// addMissionEventHandler ["Draw3D", { -// _thisArgs params [ -// ["_stalkerGroup",grpNull,[grpNull]] -// ]; - -// if (isNull _stalkerGroup OR !(_stalkerGroup getVariable ["BLWK_doStalkPlayers",false])) then { -// removeMissionEventHandler ["draw3d",_thisEventHandler]; -// } else { -// if (missionNamespace getVariable ["BLWK_debug",false]) then { -// private _text = (_stalkerGroup getVariable ["BLWK_stalkerText",[""]]) joinString " | "; -// drawIcon3D ["", [1,0,0,1], ASLToAGL (getPosASLVisual (leader _stalkerGroup)), 0, 0, 0, _text, 1, 0.05, "PuristaMedium"]; -// }; -// }; - -// },[_stalkerGroup]]; - -// private _fn_add3dLog = { -// params ["_group","_text"]; -// private _array = _group getVariable ["BLWK_stalkerText",[]]; -// if (_array isEqualTo []) then { -// _group setVariable ["BLWK_stalkerText",_array]; -// }; - -// if ((count _array) isEqualTo 5) then { -// _array deleteAt 0; -// }; -// _array pushBack _text; -// }; - -[_stalkerGroup] call KISKA_fnc_clearWaypoints; -// [_stalkerGroup,"Cleared Initial Waypoints"] call _fn_add3dLog; - -// do the stalking -[_stalkerGroup,"full"] remoteExec ["setSpeedMode",groupOwner _stalkerGroup]; -while {!(isNull _stalkerGroup) AND (_stalkerGroup getVariable DO_STALK_VAR) } do { - - // check if there are any units left in the stalker group to do the stalking - _stalkerGroupUnits = units _stalkerGroup; - private _stalkerGroupIsEmpty = _stalkerGroupUnits isEqualTo []; - private _allStalkerUnitsAreDead = { (_stalkerGroupUnits findIf {alive _x}) isEqualTo -1 }; - if (_stalkerGroupIsEmpty OR _allStalkerUnitsAreDead) then { - [_stalkerGroup] call BLWK_fnc_stopStalking; - break; - }; - - private _stalkerLeader = leader _stalkerGroup; - if !(alive _stalkerLeader) then {break}; - - - private _stalkerGroupShouldUseMove = _stalkerLeader distance2D _playerToStalk < 50; - private _stalkerGroupIsUnderMoveOrders = _stalkerGroup getVariable ["BLWK_isUnderMove",false]; - if (_stalkerGroupIsUnderMoveOrders AND (!_stalkerGroupShouldUseMove)) then { - // [_stalkerGroup,"Used doStop"] call _fn_add3dLog; - doStop _stalkerGroupUnits; - sleep 1; - _stalkerGroupUnits doFollow _stalkerLeader; - // [_stalkerGroup,"Used doFollow"] call _fn_add3dLog; - }; - - private "_waypointCount"; - // [_stalkerGroup,"Waiting to clear waypoints"] call _fn_add3dLog; - // Waypoints are not immediately deleted - waitUntil { - _waypointCount = count (waypoints _stalkerGroup); - [ - _stalkerGroup, - (_waypointCount - 1) - ] call KISKA_fnc_clearWaypoints; - - private _stalkerGroupWaypointsDeleted = _waypointCount < 2; - if (_stalkerGroupWaypointsDeleted) exitWith {true}; - - sleep 1; - - (units _stalkerGroup) isEqualTo [] - }; - // [_stalkerGroup,str ["Cleared waypoints: ",_waypointCount]] call _fn_add3dLog; - - // move allows units to go to a 3d position (inside a building) - // therefore, when they are close to their target, start using "move" instead - private _hasWaypoint = _waypointCount isEqualTo 1; - if (_stalkerGroupShouldUseMove) then { - // [_stalkerGroup,"Using Move"] call _fn_add3dLog; - - _stalkerGroup setVariable ["BLWK_isUnderMove",true]; - [_stalkerLeader,(getPosATL _playerToStalk)] remoteExecCall ["move", _stalkerLeader]; - - if (_hasWaypoint) then { - // [_stalkerGroup,"Deleted waypoint after move"] call _fn_add3dLog; - deleteWaypoint [_stalkerGroup,0]; - }; - - } else { - // [_stalkerGroup,"Using waypoints"] call _fn_add3dLog; - - private _hasStalkerWaypoint = waypointName [_stalkerGroup,currentWaypoint _stalkerGroup] == "BLWK_stalkWaypoint"; - if (_hasWaypoint AND !_hasStalkerWaypoint) then { - [_stalkerGroup] call KISKA_fnc_clearWaypoints; - // [_stalkerGroup,"Deleted non stalker WPs"] call _fn_add3dLog; - }; - - _stalkerGroup setVariable ["BLWK_isUnderMove",false]; - - if (_hasStalkerWaypoint) then { - // [_stalkerGroup,"Moving stalker WP"] call _fn_add3dLog; - - private _waypoint = [_stalkerGroup,0]; - _waypoint setWaypointBehaviour "AWARE"; - _waypoint setWaypointPosition [getPos _playerToStalk,5]; - - } else { - // [_stalkerGroup,"Adding stalker WP"] call _fn_add3dLog; - private _waypoint = [_stalkerGroup, _playerToStalk, 0, "MOVE", "AWARE", "FULL"] call CBAP_fnc_addWaypoint; - _waypoint setWaypointName "BLWK_stalkWaypoint"; - }; - - }; - - sleep _checkRate; - - if !([_playerToStalk] call BLWK_fnc_canUnitBeStalked) then { - _playerToStalk = call BLWK_fnc_getAPlayerToStalk; - }; - - if ((isNull _playerToStalk) OR {[_stalkerGroup] call _conditionToEndStalking}) then { - [_stalkerGroup,_defaultPosition] call BLWK_fnc_stopStalking; - break; - }; -}; diff --git a/Functions/Stalking/fn_stopStalking.sqf b/Functions/Stalking/fn_stopStalking.sqf deleted file mode 100644 index 20db2891..00000000 --- a/Functions/Stalking/fn_stopStalking.sqf +++ /dev/null @@ -1,79 +0,0 @@ -#include "..\..\Headers\Stalker Global Strings.hpp" -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_stopStalking - -Description: - Stops a unit from stalking and readjusts the stalker counts for the unit - they were stalking. - -Parameters: - 0: _stalkerGroup : - The group that you want to stop being a stalker - 1: _defaultPosition : - The position for the - _stalkerGroup to travel to and patrol if (OPTIONAL) - -Returns: - BOOL - -Examples: - (begin example) - [aStalkerGroup,positionToGoTo] call BLWK_fnc_stopStalking; - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -scriptName "BLWK_fnc_stopStalking"; - -params [ - ["_stalkerGroup",grpNull,[grpNull]], - ["_defaultPosition",[],[objNull,grpNull,[]]] -]; - - -if (isNull _stalkerGroup) exitWith { - ["_stalkerGroup is null",true] call KISKA_fnc_log; - - false -}; -if (isNil {_stalkerGroup getVariable DO_STALK_VAR}) exitWIth { - ["_stalkerGroup was not registered as a stalker",true] call KISKA_fnc_log; - - false -}; -_stalkerGroup setVariable [DO_STALK_VAR,nil]; - - -private _stalkerGroupUnits = units _stalkerGroup; -if (_stalkerGroupUnits isEqualTo []) exitWith { - _stalkerGroup setVariable [STALKED_UNIT_VAR,nil]; - true -}; - -// update stalker count -private _stalkedUnit = _stalkerGroup getVariable STALKED_UNIT_VAR; -if (!isNull _stalkedUnit) then { - private _numberOfStalkers = _stalkedUnit getVariable [STALKER_COUNT_VAR,0]; - _stalkerGroup setVariable [STALKED_UNIT_VAR,nil]; - - private _stalkerNumber = _numberOfStalkers - (count _stalkerGroupUnits); - if (_stalkerNumber < 0) then {_stalkerNumber = 0}; - - _stalkedUnit setVariable [STALKER_COUNT_VAR,_stalkerNumber]; -}; - -// remove events -private "_id_temp"; -_stalkerGroupUnits apply { - if !(isNull _x) then { - _id_temp = _x getVariable UNIT_KILLED_EVENT_VAR; - _x removeEventHandler ["KILLED",_id_temp]; - }; -}; - -// move units to default position if defined -if (_defaultPosition isNotEqualTo []) then { - [_stalkerGroup, _defaultPosition, 100, 3, "MOVE", "AWARE"] call CBAP_fnc_taskPatrol; -}; - - -true \ No newline at end of file diff --git a/Functions/Supports/fn_endAircraftGunner.sqf b/Functions/Supports/fn_endAircraftGunner.sqf index 87b02f96..86e07170 100644 --- a/Functions/Supports/fn_endAircraftGunner.sqf +++ b/Functions/Supports/fn_endAircraftGunner.sqf @@ -2,13 +2,13 @@ Function: BLWK_fnc_endAircraftGunner Description: - Stops a player's use of their current aircraft gunner support. + Stops a player's use of their current aircraft gunner support. - This is a companion function that is meant to be called after a running of - BLWK_fnc_startAircraftGunner. + This is a companion function that is meant to be called after a running of + BLWK_fnc_startAircraftGunner. Parameters: - NONE + NONE Returns: NOTHING @@ -24,19 +24,19 @@ Author(s): scriptName "BLWK_fnc_endAircraftGunner"; if ( - (!hasInterface) OR - !(missionNamespace getVariable ["BLWK_isAircraftGunner",false]) + (!hasInterface) OR + !(missionNamespace getVariable ["BLWK_isAircraftGunner",false]) ) exitWith {}; (localNamespace getVariable ["BLWK_aircraftGunnerEndData",[]]) params [ - ["_holdActionIdsToRemove",[],[[]]], - ["_vehicle",objNull,[objNull]], - ["_vehicleGroup",grpNull,[grpNull]], - ["_supportTypeInUseVariableName","",[""]], - ["_VDLWasRunning",false,[true]], - ["_damageAllowedAdjustmentId",-1,[123]], - ["_soundAdjustId",-1,[123]] + ["_holdActionIdsToRemove",[],[[]]], + ["_vehicle",objNull,[objNull]], + ["_vehicleGroup",grpNull,[grpNull]], + ["_supportTypeInUseVariableName","",[""]], + ["_VDLWasRunning",false,[true]], + ["_damageAllowedAdjustmentId",-1,[123]], + ["_soundAdjustId",-1,[123]] ]; missionNamespace setVariable ["BLWK_isAircraftGunner",false]; @@ -45,21 +45,24 @@ setViewDistance -1; setObjectViewDistance -1; if (_VDLWasRunning) then { - [] spawn KISKA_fnc_viewDistanceLimiter; + [] spawn KISKA_fnc_viewDistanceLimiter; }; moveOut player; player setVehiclePosition [BLWK_mainCrate,[],5,"NONE"]; player setVelocity [0,0,0]; -[player,true] call BLWK_fnc_adjustStalkable; +[player,true] remoteExecCall [ + "BLWK_fnc_stalking_setPlayerStalkable", + BLWK_theAiHandlerOwnerId +]; _holdActionIdsToRemove apply { - [player,_x] call BIS_fnc_holdActionRemove; + [player,_x] call BIS_fnc_holdActionRemove; }; (units _vehicleGroup) apply { - _vehicle deleteVehicleCrew _x; + _vehicle deleteVehicleCrew _x; }; deleteGroup _vehicleGroup; deleteVehicle _vehicle; @@ -70,18 +73,18 @@ missionNamespace setVariable [_supportTypeInUseVariableName,false,true]; [false] call BLWK_fnc_playAreaEnforcementLoop; [ - "BLWK_manage_aircraftSound", - [3, (localNamespace getVariable "BLWK_soundVolume"),true], - localNamespace, - _soundAdjustId + "BLWK_manage_aircraftSound", + [3, (localNamespace getVariable "BLWK_soundVolume"),true], + localNamespace, + _soundAdjustId ] call KISKA_fnc_managedRun_execute; [ - { - [player,false,_damageAllowedAdjustmentId] call BLWK_fnc_allowDamage; - }, - [_damageAllowedAdjustmentId], - 10 + { + [player,false,_damageAllowedAdjustmentId] call BLWK_fnc_allowDamage; + }, + [_damageAllowedAdjustmentId], + 10 ] call CBAP_fnc_waitAndExecute; localNamespace setVariable ["BLWK_aircraftGunnerEndData",nil]; diff --git a/Functions/Supports/fn_startAircraftGunner.sqf b/Functions/Supports/fn_startAircraftGunner.sqf index ec68fd93..cc0f5a0a 100644 --- a/Functions/Supports/fn_startAircraftGunner.sqf +++ b/Functions/Supports/fn_startAircraftGunner.sqf @@ -160,7 +160,10 @@ if ((getObjectViewDistance select 0) < _objectViewDistance) then { // setup player interaction BLWK_enforceArea = false; -[player,false] call BLWK_fnc_adjustStalkable; // make it so AI don't hunt the player +[player,false] remoteExecCall [ + "BLWK_fnc_stalking_setPlayerStalkable", + BLWK_theAiHandlerOwnerId +]; private _damageAllowedAdjustmentId = [player,false] call BLWK_fnc_allowDamage; player moveInTurret [_vehicle,_turretsWithWeapons select 0]; diff --git a/Functions/Wave Type Libraries/Mortar Wave Lib/fn_mortarWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Mortar Wave Lib/fn_mortarWave_onWaveInit.sqf index 4e46388c..45eb6ccd 100644 --- a/Functions/Wave Type Libraries/Mortar Wave Lib/fn_mortarWave_onWaveInit.sqf +++ b/Functions/Wave Type Libraries/Mortar Wave Lib/fn_mortarWave_onWaveInit.sqf @@ -20,38 +20,45 @@ Author(s): ---------------------------------------------------------------------------- */ scriptName "BLWK_fnc_mortarWave_onWaveInit"; -private _startingWaveUnits = call BLWK_fnc_getMustKillList; #define MORTAR_CLASS "O_Mortar_01_F" -[_startingWaveUnits select 0] spawn { - params ["_mortarMan"]; - private _spawnPosition = [ - BLWK_playAreaCenter, - BLWK_playAreaRadius - 15, - BLWK_playAreaRadius - 5, - 3, - 0, - 10 - ] call BIS_fnc_findSafePos; - private _mortarTube = MORTAR_CLASS createVehicle _spawnPosition; +private _spawnPosition = [ + BLWK_playAreaCenter, + BLWK_playAreaRadius - 15, + BLWK_playAreaRadius - 5, + 3, + 0, + 10 +] call BIS_fnc_findSafePos; +private _mortarTube = MORTAR_CLASS createVehicle _spawnPosition; + +private _startingWaveUnits = call BLWK_fnc_getMustKillList; +private _mortarMan = _startingWaveUnits select 0; +private _mortarGroup = createGroup [OPFOR,true]; +[_mortarMan] joinSilent _mortarGroup; - [group _mortarMan] call BLWK_fnc_stopStalking; +_mortarMan moveInGunner _mortarTube; +[BLWK_zeus,[[_mortarTube],true]] remoteExec ["addCuratorEditableObjects",2]; - _mortarMan moveInGunner _mortarTube; - [BLWK_zeus,[[_mortarTube],true]] remoteExec ["addCuratorEditableObjects",2]; +[_mortarMan] spawn { + params ["_mortarMan"]; // give players a bit of time before starting sleep 20; private _ammo = getArtilleryAmmo [_mortarTube] select 0; - private "_fireAtPosition"; private _doFire = true; while {_doFire} do { - _fireAtPosition = [BLWK_mainCrate,random 45,random 360] call CBAP_fnc_randPos; + private _fireAtPosition = [ + BLWK_mainCrate, + (random 45), + (random 360) + ] call CBAP_fnc_randPos; _mortarTube doArtilleryFire [_fireAtPosition,_ammo,1]; sleep (random [15,20,25]); + if (!alive _mortarMan) exitWith { deleteVehicle _mortarTube; _doFire = false; diff --git a/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_onWaveInit.sqf index dfda32dd..9bd067d5 100644 --- a/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_onWaveInit.sqf +++ b/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_onWaveInit.sqf @@ -64,9 +64,11 @@ private _startingWaveUnits = call BLWK_fnc_getMustKillList; _x setVehiclePosition [_teleportPosition, [], 1, "NONE"]; }; - _startingWaveUnits apply { - [group _x,BLWK_playerBasePosition] remoteExecCall ["BLWK_fnc_stopStalking",BLWK_theAIHandlerOwnerID]; - }; + // TODO: was previously telling units to not stalk players, + // might end up with players being killed in an open field, + // or might make the overrun more challenging if the players + // need to fight. + // Reimplement this logic if it doesn't go well }, [_startingWaveUnits], 5 diff --git a/Functions/Waves/fn_waves_end.sqf b/Functions/Waves/fn_waves_end.sqf index 3fc23383..06dacf00 100644 --- a/Functions/Waves/fn_waves_end.sqf +++ b/Functions/Waves/fn_waves_end.sqf @@ -1,4 +1,3 @@ -#include "..\..\Headers\Stalker Global Strings.hpp" /* ---------------------------------------------------------------------------- Function: BLWK_fnc_waves_end @@ -82,9 +81,6 @@ if (_factionQueue isNotEqualTo []) then { Revive downed players ---------------------------------------------------------------------------- */ _players apply { - // clear all stalkers counts - _x setVariable [STALKER_COUNT_VAR,0,BLWK_theAIHandlerOwnerID]; - if (!alive _x) then { // add a single respawn ticket for each dead unit private _respawns = [BLUFOR,1] call BIS_fnc_respawnTickets; @@ -94,7 +90,7 @@ _players apply { } else { - if (lifeState _x == "INCAPACITATED") then { + if ((lifeState _x) == "INCAPACITATED") then { if (BLWK_dontUseRevive) then { if (BLWK_ACELoaded) then { [_x] remoteExecCall ["ace_medical_treatment_fnc_fullHealLocal",_x]; diff --git a/Headers/Stalker Global Strings.hpp b/Headers/Stalker Global Strings.hpp deleted file mode 100644 index 73278dd3..00000000 --- a/Headers/Stalker Global Strings.hpp +++ /dev/null @@ -1,5 +0,0 @@ -#define DO_STALK_VAR "BLWK_doStalkPlayers" -#define STALKER_COUNT_VAR "BLWK_stalkerAmount" -#define STALKED_UNIT_VAR "BLWK_stalkedUnit" -#define IS_UNIT_AVAILABLE_VAR "BLWK_availableForStalking" -#define UNIT_KILLED_EVENT_VAR "BLWK_unitStalkerKilledEH_ID" \ No newline at end of file diff --git a/onPlayerRespawn.sqf b/onPlayerRespawn.sqf index 7c55dab7..0d601ae3 100644 --- a/onPlayerRespawn.sqf +++ b/onPlayerRespawn.sqf @@ -35,7 +35,7 @@ if (missionNamespace getVariable ["BLWK_isAircraftGunner",false]) then { missionNamespace setVariable ["BLWK_isAircraftGunner",false]; }; - +[] remoteExec ["BLWK_fnc_stalking_queueRedistribute",BLWK_theAiHandlerOwnerId]; // make players briefly invincible [_player] spawn { From d7ebe1f4da4f0cc6e9bd8b90512e7c9730f27672 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 16 Jul 2023 17:02:47 -0600 Subject: [PATCH 075/133] (#642): fixed syntax errors with new stalker system --- Functions/Stalking/fn_stalking_removeStalkedPlayer.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Functions/Stalking/fn_stalking_removeStalkedPlayer.sqf b/Functions/Stalking/fn_stalking_removeStalkedPlayer.sqf index d2ed47fa..3873f1b4 100644 --- a/Functions/Stalking/fn_stalking_removeStalkedPlayer.sqf +++ b/Functions/Stalking/fn_stalking_removeStalkedPlayer.sqf @@ -25,7 +25,7 @@ params [ ]; if ((isNull _stalkerGroup) OR (isNull _playerToStalk)) exitWith { - [["Null argument passed, params are: "_this]] call KISKA_fnc_log; + [["Null argument passed, params are: ",_this]] call KISKA_fnc_log; nil }; From a7d8ab3617268375f1a01fb9177e57ef9788d783 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 16 Jul 2023 17:12:54 -0600 Subject: [PATCH 076/133] (#642): added missing function definitions and fixed syntax error --- Functions/Stalking/fn_stalking_setStalkedPlayer.sqf | 2 +- Headers/descriptionEXT/functions.hpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Functions/Stalking/fn_stalking_setStalkedPlayer.sqf b/Functions/Stalking/fn_stalking_setStalkedPlayer.sqf index cc1612a5..65df4061 100644 --- a/Functions/Stalking/fn_stalking_setStalkedPlayer.sqf +++ b/Functions/Stalking/fn_stalking_setStalkedPlayer.sqf @@ -27,7 +27,7 @@ params [ ]; if ((isNull _stalkerGroup) OR (isNull _playerToStalk)) exitWith { - [["Null argument passed, params are: "_this]] call KISKA_fnc_log; + [["Null argument passed, params are: ",_this]] call KISKA_fnc_log; nil }; diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index e42902c1..b8d72861 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -400,6 +400,8 @@ class BLWK{ class Stalking { file = "Functions\Stalking"; + class stalking_canPlayerBeStalked + {}; class stalking_getPlayer {}; class stalking_queueRedistribute @@ -408,6 +410,8 @@ class BLWK{ {}; class stalking_setPlayerStalkable {}; + class stalking_setStalkedPlayer + {}; class stalking_start {}; class stalking_stop From d138b9d2fa9a2e86b01a91c9132c3e055f998639 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 16 Jul 2023 19:11:10 -0600 Subject: [PATCH 077/133] (#642): tweaked stalking system and fixed init bug for spawning units --- Functions/Queue/fn_spawnQueue_popAndCreate.sqf | 9 +++++++-- Functions/Stalking/fn_stalking_start.sqf | 14 ++++++++++++-- Functions/Waves/fn_waves_create.sqf | 7 +++---- Functions/Waves/fn_waves_start.sqf | 5 +---- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/Functions/Queue/fn_spawnQueue_popAndCreate.sqf b/Functions/Queue/fn_spawnQueue_popAndCreate.sqf index 6ef20252..1c24e913 100644 --- a/Functions/Queue/fn_spawnQueue_popAndCreate.sqf +++ b/Functions/Queue/fn_spawnQueue_popAndCreate.sqf @@ -6,7 +6,8 @@ Description: spawns the unit from the arguments. Parameters: - NONE + 0: _forceSpawnStaged - If true, any staged units will be spawned with this + new pop and create. Returns: <[STRING, PositionATL[] OR OBJECT, STRING]> - the element removed or empty `[]` @@ -24,6 +25,10 @@ scriptName "BLWK_fnc_spawnQueue_popAndCreate"; if (!isServer) exitWith {}; +params [ + ["_forceSpawnStaged",false,[true]] +]; + private _stagedSpawns = localNamespace getVariable ["BLWK_spawnQueue_stagedSpawns",-1]; private _stagedIsUninitialized = _stagedSpawns isEqualTo -1; if (_stagedIsUninitialized) then { @@ -45,7 +50,7 @@ if (_queue isEqualTo []) exitWith { private _maxGroupSize = localNamespace getVariable ["BLWK_spawnQueue_maxGroupSize",1]; private _insertedIndex = _stagedSpawns pushBack (_queue deleteAt 0); -if ((_insertedIndex + 1) isEqualTo _maxGroupSize) then { +if (((_insertedIndex + 1) isEqualTo _maxGroupSize) OR _forceSpawnStaged) then { localNamespace setVariable ["BLWK_spawnQueue_stagedSpawns",[]]; [_stagedSpawns] remoteExecCall ["BLWK_fnc_spawnQueue_create",BLWK_theAIHandlerOwnerID]; }; diff --git a/Functions/Stalking/fn_stalking_start.sqf b/Functions/Stalking/fn_stalking_start.sqf index 571ec428..fedf9e53 100644 --- a/Functions/Stalking/fn_stalking_start.sqf +++ b/Functions/Stalking/fn_stalking_start.sqf @@ -50,7 +50,9 @@ private _leaderChangedEventId = _stalkerGroup addEventHandler ["LeaderChanged", DEFAULT_POSITION ]; - _newLeader move _currentMovePosition; + (units _stalkerGroup) apply { + _x move _currentMovePosition; + }; }; }]; _stalkerGroup setVariable ["BLWK_stalking_leaderChangedEventId",_leaderChangedEventId]; @@ -132,6 +134,7 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; doStop _stalkerGroupUnits; sleep 1; // regroup units + _stalkerGroupUnits doFollow (leader _stalkerGroup); _stalkerGroupUnits doFollow _stalkerLeader; }; @@ -167,12 +170,18 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; private _playerPosition = getPosATL _currentPlayerBeingStalked; _stalkerGroup setVariable ["BLWK_stalking_currentMovePosition",_playerPosition]; + + // `move` does not work well against group, using it at a unit level + (units _stalkerGroup) apply { + _x move _playerPosition; + }; + _stalkerGroup setFormation "COLUMN"; + (leader _stalkerGroup) move _playerPosition; if (_hasWaypoint) then { deleteWaypoint [_stalkerGroup,0]; }; - } else { _stalkerGroup setVariable ["BLWK_stalking_isUnderMove",false]; _stalkerGroup setVariable ["BLWK_stalking_currentMovePosition",nil]; @@ -205,6 +214,7 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; }; }; + _stalkerGroup setFormation "STAG COLUMN"; _stalkerGroup setVariable ["BLWK_stalking_isPatrolling",false]; sleep UPDATE_RATE; diff --git a/Functions/Waves/fn_waves_create.sqf b/Functions/Waves/fn_waves_create.sqf index 8c5ec578..12a6225d 100644 --- a/Functions/Waves/fn_waves_create.sqf +++ b/Functions/Waves/fn_waves_create.sqf @@ -85,11 +85,10 @@ private _numberOfUnitsInQueue = count (call BLWK_fnc_spawnQueue_get); if (_numberOfUnitsInQueue < BLWK_maxEnemyInfantryAtOnce) then { _numberOfStartingEnemies = _numberOfUnitsInQueue; }; -private _unit = objNull; -private _units = []; -for "_i" from 1 to _numberOfStartingEnemies do { - call BLWK_fnc_spawnQueue_popAndCreate; +for "_i" from 1 to (_numberOfStartingEnemies - 1) do { + [false] call BLWK_fnc_spawnQueue_popAndCreate; }; +[true] call BLWK_fnc_spawnQueue_popAndCreate; /* ---------------------------------------------------------------------------- diff --git a/Functions/Waves/fn_waves_start.sqf b/Functions/Waves/fn_waves_start.sqf index 01b30838..e448ee2e 100644 --- a/Functions/Waves/fn_waves_start.sqf +++ b/Functions/Waves/fn_waves_start.sqf @@ -35,10 +35,7 @@ if (_clearDroppedItems) then { _weaponHolders = _weaponHolders select {typeOf _x == "groundWeaponHolder" AND {!(_x in BLWK_lootHolders)}}; if !(_weaponHolders isEqualTo []) then { - _weaponHolders apply { - deleteVehicle _x; - }; - sleep 1; + _weaponHolders apply { deleteVehicle _x }; }; }; From 3725679e4ea75a0aa1c34e4c22705d7c21fc6ad6 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Mon, 17 Jul 2023 20:36:58 -0600 Subject: [PATCH 078/133] (#642): fixed stalkers not behaving correctly during aircraft gunner --- Functions/Stalking/fn_stalking_start.sqf | 64 +++++++++++++++++++++--- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/Functions/Stalking/fn_stalking_start.sqf b/Functions/Stalking/fn_stalking_start.sqf index fedf9e53..2eba37c8 100644 --- a/Functions/Stalking/fn_stalking_start.sqf +++ b/Functions/Stalking/fn_stalking_start.sqf @@ -72,6 +72,24 @@ private _emptyEventId = _stalkerGroup addEventHandler ["Empty", { _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; +// FOR PATH DEBUGGING +// addMissionEventHandler ["Draw3D", { +// _thisArgs params [ +// ["_stalkerGroup",grpNull,[grpNull]] +// ]; + +// if (isNull _stalkerGroup OR !(_stalkerGroup getVariable ["BLWK_stalking_doStalk",false])) then { +// removeMissionEventHandler ["draw3d",_thisEventHandler]; +// } else { +// if (missionNamespace getVariable ["BLWK_debug",false]) then { +// private _text = (_stalkerGroup getVariable ["BLWK_stalkerText",[""]]) joinString " | "; +// drawIcon3D ["", [1,0,0,1], ASLToAGL (getPosASLVisual (leader _stalkerGroup)), 0, 0, 0, _text, 1, 0.05, "PuristaMedium"]; +// }; +// }; + +// },[_stalkerGroup]]; + + /* ---------------------------------------------------------------------------- Main loop ---------------------------------------------------------------------------- */ @@ -79,6 +97,23 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; [_stalkerGroup] spawn { params ["_stalkerGroup"]; + + // FOR PATH DEBUGGING + // private _fn_add3dLog = { + // params ["_group","_text"]; + // private _array = _group getVariable ["BLWK_stalkerText",[]]; + // private _id = _group getVariable ["BLWK_stalkerIteration",0]; + // if (_array isEqualTo []) then { + // _group setVariable ["BLWK_stalkerText",_array]; + // }; + + // if ((count _array) isEqualTo 5) then { + // _array deleteAt 0; + // }; + // _array pushBack ([_text,_id] joinString " - "); + // _group setVariable ["BLWK_stalkerIteration",_id + 1]; + // }; + while { !(isNull _stalkerGroup) AND (_stalkerGroup getVariable ["BLWK_stalking_doStalk",false]) } do { @@ -92,7 +127,10 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; "BLWK_isACEUnconscious", false ] - ) then { continue }; + ) then { + sleep 3; + continue + }; private _currentPlayerBeingStalked = _stalkerGroup getVariable ["BLWK_stalking_stalkedPlayer",objNull]; /* -------------------------------------- @@ -103,11 +141,14 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; if ((!_currentPlayerCanBeStalked) OR _shouldRedistribute) then { private _playerToStalk = call BLWK_fnc_stalking_getPlayer; if (isNull _playerToStalk) then { - - if !(_stalkerGroup setVariable ["BLWK_stalking_isPatrolling",false]) then { + + private _groupIsPatrolling = _stalkerGroup getVariable ["BLWK_stalking_isPatrolling",false]; + // [_stalkerGroup,["NULL player to stalk: ",_groupIsPatrolling] joinString ""] call _fn_add3dLog; + if !(_groupIsPatrolling) then { _stalkerGroup setVariable ["BLWK_stalking_isPatrolling",true]; [_stalkerGroup] call KISKA_fnc_clearWaypoints; [_stalkerGroup, DEFAULT_POSITION, 100, 3, "MOVE", "AWARE"] call CBAP_fnc_taskPatrol; + // [_stalkerGroup,"told to patrol"] call _fn_add3dLog; }; sleep UPDATE_RATE; @@ -117,6 +158,7 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; } else { [_stalkerGroup,_playerToStalk] call BLWK_fnc_stalking_setStalkedPlayer; _currentPlayerBeingStalked = _playerToStalk; + // [_stalkerGroup,"set new stalked player"] call _fn_add3dLog; }; }; @@ -135,7 +177,7 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; sleep 1; // regroup units _stalkerGroupUnits doFollow (leader _stalkerGroup); - _stalkerGroupUnits doFollow _stalkerLeader; + // [_stalkerGroup,"told to stop and then follow"] call _fn_add3dLog; }; @@ -144,6 +186,7 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; Waypoints are not immediately deleted so need to wait -------------------------------------- */ private "_waypointCount"; + // tODO: maybe a problem??? waitUntil { _waypointCount = count (waypoints _stalkerGroup); [ @@ -159,6 +202,7 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; // prevent infinte loop (units _stalkerGroup) isEqualTo [] }; + // [_stalkerGroup,"cleared waypoints"] call _fn_add3dLog; /* -------------------------------------- @@ -177,10 +221,10 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; }; _stalkerGroup setFormation "COLUMN"; - - (leader _stalkerGroup) move _playerPosition; + // [_stalkerGroup,["told to move ",_playerPosition] joinString ""] call _fn_add3dLog; if (_hasWaypoint) then { deleteWaypoint [_stalkerGroup,0]; + // [_stalkerGroup,"deleted waypoint"] call _fn_add3dLog; }; } else { _stalkerGroup setVariable ["BLWK_stalking_isUnderMove",false]; @@ -194,12 +238,14 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; private _hasWaypointThatIsNotStalkerWaypoint = _hasWaypoint AND (!_hasStalkerWaypoint); if (_hasWaypointThatIsNotStalkerWaypoint) then { [_stalkerGroup] call KISKA_fnc_clearWaypoints; + // [_stalkerGroup,"cleared WPs because excess"] call _fn_add3dLog; }; if (_hasStalkerWaypoint) then { private _waypoint = [_stalkerGroup,0]; _waypoint setWaypointBehaviour "AWARE"; _waypoint setWaypointPosition [getPos _currentPlayerBeingStalked,5]; + // [_stalkerGroup,"updated stalker WP"] call _fn_add3dLog; } else { private _waypoint = [ @@ -211,6 +257,7 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; "FULL" ] call CBAP_fnc_addWaypoint; _waypoint setWaypointName "BLWK_stalking_waypoint"; + // [_stalkerGroup,"Added new WP"] call _fn_add3dLog; }; }; @@ -223,3 +270,8 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; nil + +// TODO: units do not patrol when there is nobody to stalk, +// they just sit still after spawn or move to the main crate + +// user 3d log and aircraft gunner support to see what orders they are given \ No newline at end of file From 0d326ecdb13c6f25c31b4a54ab6b6022cd9006aa Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Mon, 17 Jul 2023 23:40:39 -0600 Subject: [PATCH 079/133] (#642): fixed paratrooper wave errors --- .../fn_paratrooperWave_onWaveInit.sqf | 72 +++++++++++-------- 1 file changed, 44 insertions(+), 28 deletions(-) diff --git a/Functions/Wave Type Libraries/Paratrooper Wave Lib/fn_paratrooperWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Paratrooper Wave Lib/fn_paratrooperWave_onWaveInit.sqf index 0e9b1c5c..3a40053b 100644 --- a/Functions/Wave Type Libraries/Paratrooper Wave Lib/fn_paratrooperWave_onWaveInit.sqf +++ b/Functions/Wave Type Libraries/Paratrooper Wave Lib/fn_paratrooperWave_onWaveInit.sqf @@ -23,6 +23,8 @@ scriptName "BLWK_fnc_paratrooperWave_onWaveInit"; #define FLY_IN_HEIGHT 200 #define APPROACH_DIRECTION -1 #define NUMBER_OF_UNITS_TO_DROP -1 +#define MAX_NUM_PARAS 14 +#define DROP_AREA_RADIUS 50 private _startingWaveUnits = call BLWK_fnc_getMustKillList; private _unitCount = count _startingWaveUnits; @@ -52,35 +54,49 @@ if (_numberOfUnitsToDrop <= _vehicleCargoCapacity) exitWith { }; -private _parasAllocated = false; -private _startCount = 0; -private _numUnitsAllocated = 0; -while {!_parasAllocated} do { - // get units to put into vehicle - private _unitsToDropForStick = _startingWaveUnits select [_startCount,_vehicleCargoCapacity]; - - // drop around The Crate - private _dropZoneForStick = [BLWK_mainCrate,DROP_AREA_RADIUS] call CBAP_fnc_randPos; - [ - _dropZoneForStick, - _unitsToDropForStick, - _dropVehicleClass, - NUMBER_OF_UNITS_TO_DROP, - APPROACH_DIRECTION, - FLY_IN_HEIGHT, - OPFOR - ] spawn KISKA_fnc_paratroopers; - - // check if the amount to drop has been reached - _numUnitsAllocated = _numUnitsAllocated + _vehicleCargoCapacity; - if (_numUnitsAllocated >= _numberOfUnitsToDrop) then { - _parasAllocated = true; - } else { - // update select start count - _startCount = _numUnitsAllocated - 1; // want actual array index +[ + _startingWaveUnits, + _vehicleCargoCapacity, + _numberOfUnitsToDrop, + _dropVehicleClass +] spawn { + params [ + "_startingWaveUnits", + "_vehicleCargoCapacity", + "_numberOfUnitsToDrop", + "_dropVehicleClass" + ]; + + private _parasAllocated = false; + private _startCount = 0; + private _numUnitsAllocated = 0; + while {!_parasAllocated} do { + // get units to put into vehicle + private _unitsToDropForStick = _startingWaveUnits select [_startCount,_vehicleCargoCapacity]; + + // drop around The Crate + private _dropZoneForStick = [BLWK_mainCrate,DROP_AREA_RADIUS] call CBAP_fnc_randPos; + [ + _dropZoneForStick, + _unitsToDropForStick, + _dropVehicleClass, + NUMBER_OF_UNITS_TO_DROP, + APPROACH_DIRECTION, + FLY_IN_HEIGHT, + OPFOR + ] spawn KISKA_fnc_paratroopers; + + // check if the amount to drop has been reached + _numUnitsAllocated = _numUnitsAllocated + _vehicleCargoCapacity; + if (_numUnitsAllocated >= _numberOfUnitsToDrop) then { + _parasAllocated = true; + } else { + // update select start count + _startCount = _numUnitsAllocated - 1; // want actual array index + }; + + sleep 5; }; - - sleep 5; }; From 6ea4b47724ac05ef6abbb622ce27d419b9d11359 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Tue, 18 Jul 2023 17:54:57 -0600 Subject: [PATCH 080/133] (#642): fixed errors with player respawn and managed runs --- .../KISKA Utility Functions/fn_managedRun_execute.sqf | 7 +++++-- onPlayerRespawn.sqf | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/KISKA Systems/KISKA Utility Functions/fn_managedRun_execute.sqf b/KISKA Systems/KISKA Utility Functions/fn_managedRun_execute.sqf index ce21791f..30c79bfe 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_managedRun_execute.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_managedRun_execute.sqf @@ -117,12 +117,15 @@ private _isNewManagement = _idToRunAgainst isEqualTo -1; private _currentAdjustmentId = _idNamespace getVariable ["KISKA_managedRun_latestId",-1]; private _idToAdjustIsCurrent = _currentAdjustmentId isEqualTo _idToRunAgainst; +// new id was made, don't run code if ((!_isNewManagement) AND (!_idToAdjustIsCurrent)) exitWith { -1 }; -private _idOfRun = _idToRunAgainst; -if (!_idToAdjustIsCurrent) then { +private _idOfRun = -1; +if (_isNewManagement) then { // assign new adjusment id as latest _idOfRun = ["KISKA_managedRun_latestId",_idNamespace] call KISKA_fnc_idCounter; +} else { + _idOfRun = _idToRunAgainst; }; private _code = _codeMap get _nameOfCode; diff --git a/onPlayerRespawn.sqf b/onPlayerRespawn.sqf index 0d601ae3..1444c782 100644 --- a/onPlayerRespawn.sqf +++ b/onPlayerRespawn.sqf @@ -39,7 +39,7 @@ if (missionNamespace getVariable ["BLWK_isAircraftGunner",false]) then { // make players briefly invincible [_player] spawn { - param ["_player"]; + params ["_player"]; private _idOfRespawnInvincibility = [_player,false] call BLWK_fnc_allowDamage; sleep 15; From 218b91bf86d3a3bf665b0995cfeff75c0a43f76b Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Tue, 18 Jul 2023 18:50:01 -0600 Subject: [PATCH 081/133] Updated error message output for KISKA_fnc_setCrew --- KISKA Systems/KISKA Utility Functions/fn_setCrew.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KISKA Systems/KISKA Utility Functions/fn_setCrew.sqf b/KISKA Systems/KISKA Utility Functions/fn_setCrew.sqf index d0fcd908..038b1a11 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_setCrew.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_setCrew.sqf @@ -37,7 +37,7 @@ if (_crew isEqualType objNull) then { }; if (_crew isEqualTo []) exitWith { - [["Found that ",_crew," is not defined, exiting..."],true] call KISKA_fnc_log; + [["Found that vehicle crew is empty, exiting..."],true] call KISKA_fnc_log; false }; From 401991136b5f8bcb090a0a77ea9f500e441a12cd Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Tue, 18 Jul 2023 18:54:28 -0600 Subject: [PATCH 082/133] (#642): fixed vehicles not spawning on vehicle wave --- .../Standard Wave Lib/fn_standardWave_vehicles.sqf | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_vehicles.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_vehicles.sqf index b5db87df..a0ebba39 100644 --- a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_vehicles.sqf +++ b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_vehicles.sqf @@ -106,7 +106,7 @@ if (_vehicleTypeValues isEqualTo []) exitWith { private _returnedVehicles = []; private _fn_spawnAVehicle = { params [ - ["_startingIndex",0] + ["_startingIndex",0,[123]] ]; // [str _likelihoodWeights,false,true,false] call KISKA_fnc_log; // [str _vehicleTypeValues,false,true,false] call KISKA_fnc_log; @@ -124,7 +124,6 @@ private _fn_spawnAVehicle = { private _vehicleClass = selectRandom (_vehicleTypeHash get _vehicleType); private _spawnPosition = selectRandom BLWK_vehicleSpawnPositions; private _vehicle = _vehicleClass createVehicle _spawnPosition; - private _totalNumberOfAvailableUnits = (count _availableInfantry) - (_startingIndex + 1); if (_totalNumberOfAvailableUnits isEqualTo 0) exitWith { ["Could not find any units to for vehicle",false] call KISKA_fnc_log; @@ -145,14 +144,14 @@ private _fn_spawnAVehicle = { private _nextAvailableIndex = _startingIndex + _crewCount; private _selectionEndIndex = _nextAvailableIndex - 1; - private _crew = _availableInfantry select [_startingIndex,_lastIndex]; + private _crew = _availableInfantry select [_startingIndex,_selectionEndIndex]; private _group = createGroup (side (_crew select 0)); _group deleteGroupWhenEmpty true; _group allowFleeing 0; _crew joinSilent _group; - [_group,_vehicle] call KISKA_fnc_setCrew; + [_crew,_vehicle] call KISKA_fnc_setCrew; _crew doMove (getPosATL BLWK_mainCrate); [BLWK_zeus, [[_vehicle],false]] remoteExecCall ["addCuratorEditableObjects",2]; @@ -165,7 +164,7 @@ private _fn_spawnAVehicle = { }; -private _nextAvailableIndex = call _fn_spawnAVehicle; +private _nextAvailableIndex = [] call _fn_spawnAVehicle; // do a role for a second vehicle // make sure there are enough AI to even crew a ground vehicle From e9425d9b8e91eba48ea3ee3dcd9b1fbe2f902f48 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Tue, 18 Jul 2023 19:26:15 -0600 Subject: [PATCH 083/133] (#642): fixed drone hits giving points to host --- Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf b/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf index 6d437ed4..855374c2 100644 --- a/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf +++ b/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf @@ -33,7 +33,9 @@ if (isNull _unit) exitWith { private _hitEventId = _unit addEventHandler ["Hit", { params ["_unit", "", "_damage", "_instigator"]; - [_unit,_damage] remoteExecCall ["BLWK_fnc_event_hitEnemy",_instigator]; + if (isPlayer _instigator) then { + [_unit,_damage] remoteExecCall ["BLWK_fnc_event_hitEnemy",_instigator]; + }; }]; _unit setVariable ["BLWK_spawnQueue_hitEventId",_hitEventId]; From 75264cd3f929cbc1fef016d7914c0cfe53fd7d63 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Tue, 18 Jul 2023 19:26:27 -0600 Subject: [PATCH 084/133] (#642): fixed drone wave error --- .../fn_droneWave_onWaveInit.sqf | 112 +++++++++--------- 1 file changed, 54 insertions(+), 58 deletions(-) diff --git a/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf index a9d4a6da..1ade327d 100644 --- a/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf +++ b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf @@ -27,65 +27,61 @@ scriptName "BLWK_fnc_droneWave_onWaveInit"; #define FLY_HEIGHT 10 #define DRONE_SPAWN_OFFSET 10 -if (!canSuspend) exitWith { - ["Must be run in scheduled environment, exiting to scheduled",true] call KISKA_fnc_log; - [] spawn BLWK_fnc_createDroneWave; -}; - localNamespace setVariable ["BLWK_droneWave_allDronesCreated",false]; -for "_i" from 1 to DRONE_NUMBER do { - // Spawn position - private _droneGroup = createGroup OPFOR; - private _flyDirection = round (random 360); - private _flyFromDirection = [_flyDirection + 180] call CBAP_fnc_simplifyAngle; - private _spawnPosition = BLWK_mainCrate getPos [ - BLWK_playAreaRadius + (random [100,125,150]), - _flyFromDirection - ]; - _spawnPosition set [2,FLY_HEIGHT]; - - // Create - private _droneSpawnInfo = [ - _spawnPosition, - _flyDirection, - DRONE_CLASS, - _droneGroup - ] call BIS_fnc_spawnVehicle; - - private _drone = _droneSpawnInfo select 0; - _drone flyInHeight FLY_HEIGHT; - _drone setSkill 1; - - - [_drone,_droneGroup,_spawnPosition] spawn BLWK_fnc_droneWave_attackLoop; - - - _drone addEventHandler ["HIT", { - params ["_drone", "", "", "_instigator"]; - - if (isPlayer _instigator) then { - private _points = [_drone] call BLWK_fnc_getPointsForKill; - [_drone,_points] remoteExec ["BLWK_fnc_droneWave_onDroneKilled",_instigator]; - }; - - private _explosion = "DemoCharge_Remote_Ammo_Scripted" createVehicle (getPosATLVisual _drone); - _explosion setdamage 1; - deleteVehicle _unit; - - if (call BLWK_fnc_waves_isCleared) then { - call BLWK_fnc_waves_end - }; - }]; - - - [_drone] call BLWK_fnc_addToMustKillList; - BLWK_zeus addCuratorEditableObjects [[_drone], true]; - - // space out spawns so that you don't get spammed - sleep DRONE_SPAWN_OFFSET; +[] spawn { + for "_i" from 1 to DRONE_NUMBER do { + // Spawn position + private _droneGroup = createGroup OPFOR; + private _flyDirection = round (random 360); + private _flyFromDirection = [_flyDirection + 180] call CBAP_fnc_simplifyAngle; + private _spawnPosition = BLWK_mainCrate getPos [ + BLWK_playAreaRadius + (random [100,125,150]), + _flyFromDirection + ]; + _spawnPosition set [2,FLY_HEIGHT]; + + // Create + private _droneSpawnInfo = [ + _spawnPosition, + _flyDirection, + DRONE_CLASS, + _droneGroup + ] call BIS_fnc_spawnVehicle; + + private _drone = _droneSpawnInfo select 0; + _drone flyInHeight FLY_HEIGHT; + _drone setSkill 1; + + + [_drone,_droneGroup,_spawnPosition] spawn BLWK_fnc_droneWave_attackLoop; + + + _drone addEventHandler ["HIT", { + params ["_drone", "", "", "_instigator"]; + + if (isPlayer _instigator) then { + private _points = [_drone] call BLWK_fnc_getPointsForKill; + [_drone,_points] remoteExec ["BLWK_fnc_droneWave_onDroneKilled",_instigator]; + }; + + private _explosion = "DemoCharge_Remote_Ammo_Scripted" createVehicle (getPosATLVisual _drone); + _explosion setdamage 1; + deleteVehicle _unit; + + if (call BLWK_fnc_waves_isCleared) then { + call BLWK_fnc_waves_end + }; + }]; + + private _droneArray = [_drone]; + [_droneArray] call BLWK_fnc_addToMustKillList; + BLWK_zeus addCuratorEditableObjects [_droneArray, true]; + + // space out spawns so that you don't get spammed + sleep DRONE_SPAWN_OFFSET; + }; + + localNamespace setVariable ["BLWK_droneWave_allDronesCreated",true]; }; - -localNamespace setVariable ["BLWK_droneWave_allDronesCreated",true]; - nil From f328a5128aa57b76e86d796d980a573a45864e42 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Tue, 18 Jul 2023 22:14:26 -0600 Subject: [PATCH 085/133] (#642): fixed supply drop aircraft flying away during drone waves --- Functions/Supports/fn_arsenalSupplyDrop.sqf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Functions/Supports/fn_arsenalSupplyDrop.sqf b/Functions/Supports/fn_arsenalSupplyDrop.sqf index 52ae02bd..7a597548 100644 --- a/Functions/Supports/fn_arsenalSupplyDrop.sqf +++ b/Functions/Supports/fn_arsenalSupplyDrop.sqf @@ -50,19 +50,19 @@ private _vehicleArray = [ ] call KISKA_fnc_spawnVehicle; -private _aircraftCrew = _vehicleArray select 1; +_vehicleArray params ["_aircraft","_aircraftCrew","_aircraftGroup"]; _aircraftCrew apply { _x setCaptive true; }; -private _aircraft = _vehicleArray select 0; +_aircraftGroup setBehaviourStrong "CARELESS"; + _aircraft flyInHeight DROP_ALT; _airCraft move _dropPosition; // give it a waypoint and delete it after it gets there private _flyToPosition = _dropPosition getPos [FLY_RADIUS,_relativeDirection]; -private _aircraftGroup = _vehicleArray select 2; [_aircraft,_dropPosition,_aircraftGroup,_flyToPosition] spawn { params ["_aircraft","_dropPosition","_aircraftGroup","_flyToPosition"]; From a8fc016d6b524c2718a60da2ca8b76159785b3b1 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Tue, 18 Jul 2023 22:41:30 -0600 Subject: [PATCH 086/133] (#642): fixed being able to call multiple wave ends --- Functions/Waves/fn_waves_end.sqf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Functions/Waves/fn_waves_end.sqf b/Functions/Waves/fn_waves_end.sqf index 06dacf00..ecbf0685 100644 --- a/Functions/Waves/fn_waves_end.sqf +++ b/Functions/Waves/fn_waves_end.sqf @@ -27,6 +27,11 @@ scriptName "BLWK_fnc_waves_end"; if (!isServer) exitWith {}; +private _lastWaveEnd = localNamespace getVariable ["BLWK_waves_lastEndedWave",0]; +// prevent multiple wave ends from being called +if (_lastWaveEnd isEqualTo BLWK_currentWaveNumber) exitWith {}; +localNamespace setVariable ["BLWK_waves_lastEndedWave",BLWK_currentWaveNumber]; + private _waveConfig = localNamespace getVariable ["BLWK_currentWaveConfig",configNull]; private _waveEndEvent = [ _waveConfig, From 9b9bf447489f668c0ada1b0f3adf9461792f7da0 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Tue, 18 Jul 2023 22:43:45 -0600 Subject: [PATCH 087/133] (#642): fixed drone waves not ending when drones are deleted or killed last --- .../fn_droneWave_onWaveInit.sqf | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf index 1ade327d..f20d4848 100644 --- a/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf +++ b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf @@ -57,7 +57,7 @@ localNamespace setVariable ["BLWK_droneWave_allDronesCreated",false]; [_drone,_droneGroup,_spawnPosition] spawn BLWK_fnc_droneWave_attackLoop; - _drone addEventHandler ["HIT", { + private _hitEventId = _drone addEventHandler ["HIT", { params ["_drone", "", "", "_instigator"]; if (isPlayer _instigator) then { @@ -67,12 +67,43 @@ localNamespace setVariable ["BLWK_droneWave_allDronesCreated",false]; private _explosion = "DemoCharge_Remote_Ammo_Scripted" createVehicle (getPosATLVisual _drone); _explosion setdamage 1; - deleteVehicle _unit; + _drone setDamage 1; + }]; + _drone setVariable ["BLWK_droneWave_droneHitEventId",_hitEventId]; + + private _deletedEventId = _drone addEventHandler ["DELETED", { + // deleted ai is not actually dead when deleted event runs + // need to wait before checking for wave clear + [ + { + if (call BLWK_fnc_waves_isCleared) then { + call BLWK_fnc_waves_end + }; + }, + [], + 0.5 + ] call CBAP_fnc_waitAndExecute; + }]; + _drone setVariable ["BLWK_droneWave_droneDeletedEventId",_deletedEventId]; + + private _killedEventId = _drone addEventHandler ["KILLED", { + params ["_drone"]; + [ + ["BLWK_droneWave_droneHitEventId","HIT"], + ["BLWK_droneWave_droneKilledEventId","KILLED"], + ["BLWK_droneWave_droneDeletedEventId","DELETED"] + ] apply { + _x params ["_eventIdVarName","_eventType"]; + private _eventId = _drone getVariable [_eventIdVarName,-1]; + _drone removeEventHandler [_eventType,_eventId]; + }; if (call BLWK_fnc_waves_isCleared) then { call BLWK_fnc_waves_end }; - }]; + }]; + _drone setVariable ["BLWK_droneWave_droneKilledEventId",_killedEventId]; + private _droneArray = [_drone]; [_droneArray] call BLWK_fnc_addToMustKillList; From e0bdc492c9d5dcb1d916425c567c1f8a75d461a9 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Tue, 18 Jul 2023 22:47:09 -0600 Subject: [PATCH 088/133] (#642): cleaned up old drone wave functions --- .../Drone Wave Library/fn_createDroneWave.sqf | 126 ------------------ .../Drone Wave Library/fn_onDroneWaveEnd.sqf | 24 ---- 2 files changed, 150 deletions(-) delete mode 100644 Functions/Wave Type Libraries/Drone Wave Library/fn_createDroneWave.sqf delete mode 100644 Functions/Wave Type Libraries/Drone Wave Library/fn_onDroneWaveEnd.sqf diff --git a/Functions/Wave Type Libraries/Drone Wave Library/fn_createDroneWave.sqf b/Functions/Wave Type Libraries/Drone Wave Library/fn_createDroneWave.sqf deleted file mode 100644 index d573d123..00000000 --- a/Functions/Wave Type Libraries/Drone Wave Library/fn_createDroneWave.sqf +++ /dev/null @@ -1,126 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_createDroneWave - -Description: - Creates the the wave of drones that drop bombs from overhead - - Executed from "BLWK_fnc_handleDroneWave" - -Parameters: - NONE - -Returns: - NOTHING - -Examples: - (begin example) - [] spawn BLWK_fnc_createDroneWave; - (end) - -Author(s): - Hilltop(Willtop) & omNomios, - Modified by: Ansible2 // Cipher ----------------------------------------------------------------------------- */ -#define DRONE_CLASS "C_IDAP_UAV_06_antimine_F" -#define DRONE_NUMBER 12 -#define FLY_HEIGHT 10 - -if (!canSuspend) exitWith { - ["Must be run in scheduled environment, exiting to scheduled",true] call KISKA_fnc_log; - [] spawn BLWK_fnc_createDroneWave; -}; - -missionNamespace setVariable ["BLWK_allDronesCreated",false,[0,2] select isMultiplayer]; - -private [ - "_drone_temp", - "_droneArray_temp", - "_spawnPosition_temp", - "_flyDirection", - "_flyFromDirection", - "_droneGroup_temp" -]; -for "_i" from 1 to DRONE_NUMBER do { - _droneGroup_temp = createGroup OPFOR; - // get directions for vehicle to fly - _flyDirection = round (random 360); - _flyFromDirection = [_flyDirection + 180] call CBAP_fnc_simplifyAngle; - _spawnPosition_temp = BLWK_mainCrate getPos [BLWK_playAreaRadius + (random [100,125,150]),_flyFromDirection]; - _spawnPosition_temp set [2,FLY_HEIGHT]; - - // create drone - _droneArray_temp = [_spawnPosition_temp, _flyDirection, DRONE_CLASS, _droneGroup_temp] call BIS_fnc_spawnVehicle; - _drone_temp = _droneArray_temp select 0; - _drone_temp flyInHeight FLY_HEIGHT; - _drone_temp setSkill 1; - - // attack The Crate - [_drone_temp,_droneGroup_temp,_spawnPosition_temp] spawn { - params [ - "_drone", - "_droneGroup", - "_spawnPosition" - ]; - - private _distanceToFire = FLY_HEIGHT + 37; - while {alive _drone} do { - _drone move (position BLWK_mainCrate); - - // wait to be in position to fire - waitUntil { - if !(alive _drone) exitWith {true}; - if ( - (_drone distance BLWK_mainCrate) <= _distanceToFire OR - // sometimes units can just slightly out of the ideal 3d range - {(_drone distance2D BLWK_mainCrate) <= 10} - ) exitWith {true}; - - sleep 2; - false - }; - - // do fire - waitUntil { - if !(alive _drone) exitWith {true}; - if (_drone fireAtTarget [BLWK_mainCrate]) exitWith {true}; - - sleep 2; - false - }; - - // move back to spawn - _drone move _spawnPosition; - waitUntil { - if !(alive _drone) exitWith {true}; - if ((_drone distance2d _spawnPosition) <= 10) exitWith {true}; - - sleep 2; - false - }; - - }; - }; - - // add hit event - _drone_temp addEventHandler ["HIT",{ - params ["_unitKilled", "", "", "_instigator"]; - - if (isPlayer _instigator) then { - private _points = [_unitKilled] call BLWK_fnc_getPointsForKill; - [_points] remoteExecCall ["BLWK_fnc_addPoints",_instigator]; - [_unitKilled,_points,true] remoteExecCall ["BLWK_fnc_createHitMarker",_instigator]; - }; - - private _explosion = "DemoCharge_Remote_Ammo_Scripted" createVehicle (getPosATLVisual _unitKilled); - _explosion setdamage 1; - deleteVehicle _unit; - }]; - - [_drone_temp] remoteExec ["BLWK_fnc_addToMustKillList",2]; - [BLWK_zeus,[[_drone_temp], true]] remoteExecCall ["addCuratorEditableObjects",2]; - - // space out spawns so that you don't get spammed - sleep 10; -}; - -missionNamespace setVariable ["BLWK_allDronesCreated",true,[0,2] select isMultiplayer]; \ No newline at end of file diff --git a/Functions/Wave Type Libraries/Drone Wave Library/fn_onDroneWaveEnd.sqf b/Functions/Wave Type Libraries/Drone Wave Library/fn_onDroneWaveEnd.sqf deleted file mode 100644 index 2efdfc18..00000000 --- a/Functions/Wave Type Libraries/Drone Wave Library/fn_onDroneWaveEnd.sqf +++ /dev/null @@ -1,24 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_onDroneWaveEnd - -Description: - Nils BLWK_allDronesCreated - -Parameters: - NONE - -Returns: - NOTHING - -Examples: - (begin example) - call BLWK_fnc_onDroneWaveEnd; - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -scriptName "BLWK_fnc_onDroneWaveEnd"; - -// handle drone wave global -missionNamespace setVariable ["BLWK_allDronesCreated",nil,[0,2] select isMultiplayer]; From 5eef27eb6452b5d85f5ebcb5aa1dbdd6b7c8be24 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Tue, 18 Jul 2023 22:47:44 -0600 Subject: [PATCH 089/133] (#642): allowed BLWK_fnc_addToMustKillList to take object as first arg --- .../Drone Wave Lib/fn_droneWave_onWaveInit.sqf | 2 +- Functions/Waves/fn_addToMustKillList.sqf | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf index f20d4848..6afe13dc 100644 --- a/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf +++ b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf @@ -106,7 +106,7 @@ localNamespace setVariable ["BLWK_droneWave_allDronesCreated",false]; private _droneArray = [_drone]; - [_droneArray] call BLWK_fnc_addToMustKillList; + _droneArray call BLWK_fnc_addToMustKillList; BLWK_zeus addCuratorEditableObjects [_droneArray, true]; // space out spawns so that you don't get spammed diff --git a/Functions/Waves/fn_addToMustKillList.sqf b/Functions/Waves/fn_addToMustKillList.sqf index b6b50d70..ec080ffe 100644 --- a/Functions/Waves/fn_addToMustKillList.sqf +++ b/Functions/Waves/fn_addToMustKillList.sqf @@ -6,7 +6,7 @@ Description: to be killed before the round can be done. Parameters: - 0: _unitsToAdd : - The units to add + 0: _unitsToAdd : - The units to add Returns: NOTHING @@ -25,10 +25,14 @@ params [ ["_unitsToAdd",[],[[]]] ]; +if (_unitsToAdd isEqualType objNull) then { + _unitsToAdd = [_unitsToAdd]; +}; + private _currentList = call BLWK_fnc_getMustKillList; _unitsToAdd apply { - if (isNull _x) exitWith { + if (isNull _x) then { ["A null unit was passed..."] call KISKA_fnc_log; continue }; From 8752bc383928fdcbf3d69b076e4ad2782312fabc Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Tue, 18 Jul 2023 22:49:04 -0600 Subject: [PATCH 090/133] (#642): fixed params definition for BLWK_fnc_addToMustKillList --- Functions/Waves/fn_addToMustKillList.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Functions/Waves/fn_addToMustKillList.sqf b/Functions/Waves/fn_addToMustKillList.sqf index ec080ffe..37e4ca6d 100644 --- a/Functions/Waves/fn_addToMustKillList.sqf +++ b/Functions/Waves/fn_addToMustKillList.sqf @@ -22,7 +22,7 @@ Author(s): if (!isServer) exitWith {}; params [ - ["_unitsToAdd",[],[[]]] + ["_unitsToAdd",[],[[],objNull]] ]; if (_unitsToAdd isEqualType objNull) then { From 9d7e9d1e09ee5b2b9651ccb9daca05767b27d7f5 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Tue, 18 Jul 2023 22:59:32 -0600 Subject: [PATCH 091/133] (#642): fixed logic error in BLWK_fnc_waves_getFunctionFromConfig --- Functions/Waves/fn_waves_getFunctionFromConfig.sqf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Functions/Waves/fn_waves_getFunctionFromConfig.sqf b/Functions/Waves/fn_waves_getFunctionFromConfig.sqf index 84898f9e..014ff6df 100644 --- a/Functions/Waves/fn_waves_getFunctionFromConfig.sqf +++ b/Functions/Waves/fn_waves_getFunctionFromConfig.sqf @@ -45,6 +45,7 @@ params [ private _requestedConfig = _waveConfig >> _configProperty; +private _requestedConfigPropertyIsUndefined = isNull _requestedConfig; private _requestedFunctionName = getText(_requestedConfig); private _functionNameIsEmpty = _requestedFunctionName isEqualTo ""; private _configIsDefinedEmpty = !(isNull _requestedConfig) AND _functionNameIsEmpty; @@ -77,6 +78,7 @@ private _requestedFunction = missionNamespace getVariable [ {} ]; if ( + (!_requestedConfigPropertyIsUndefined) AND (_requestedFunction isEqualTo {}) AND (_waveConfig isNotEqualTo DEFAULT_WAVE_CONFIG_PATH) ) then { From 9b43d65f9466d413c312a708ba3eb3de77ee27c5 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Wed, 19 Jul 2023 20:18:54 -0600 Subject: [PATCH 092/133] (#642): fixed a number of spawns over water and implemented new logic for helicopter gunner AI --- .../fn_event_addVehicleKilledHandler.sqf | 2 +- Functions/Supports/fn_arsenalSupplyDrop.sqf | 8 +- .../Supports/fn_callingForSupportMaster.sqf | 2 +- Functions/Supports/fn_daisyCutter.sqf | 8 +- .../Supports/fn_passiveHelicopterGunner.sqf | 372 ++++-------------- .../fn_droneWave_onWaveInit.sqf | 7 +- .../fn_helicopterWave_onWaveInit.sqf | 6 +- KISKA Systems/KISKA Functions.hpp | 9 +- .../KISKA Utility Functions/fn_CAS.sqf | 14 +- .../fn_engageHeliTurretsLoop.sqf | 190 +++++++++ .../fn_getPosRelativeSurface.sqf | 50 +++ .../fn_helicopterGunner.sqf | 283 +++++++++++++ .../fn_paratroopers.sqf | 9 +- .../fn_spawnVehicle.sqf | 2 +- 14 files changed, 639 insertions(+), 323 deletions(-) create mode 100644 KISKA Systems/KISKA Utility Functions/fn_engageHeliTurretsLoop.sqf create mode 100644 KISKA Systems/KISKA Utility Functions/fn_getPosRelativeSurface.sqf create mode 100644 KISKA Systems/KISKA Utility Functions/fn_helicopterGunner.sqf diff --git a/Functions/Events/fn_event_addVehicleKilledHandler.sqf b/Functions/Events/fn_event_addVehicleKilledHandler.sqf index 8cbe3953..3f76dfb8 100644 --- a/Functions/Events/fn_event_addVehicleKilledHandler.sqf +++ b/Functions/Events/fn_event_addVehicleKilledHandler.sqf @@ -33,7 +33,7 @@ if (isNull _vehicle) exitWith { _vehicle addEventHandler ["KILLED", { params ["_killedUnit", "", "_instigator"]; - if (!(isNull _instigator) AND (isPlayer _instigator)) then { + if (isPlayer _instigator) then { // show a player hit points and add them to there score [_killedUnit,true] remoteExecCall ["BLWK_fnc_event_killedEnemy",_instigator]; }; diff --git a/Functions/Supports/fn_arsenalSupplyDrop.sqf b/Functions/Supports/fn_arsenalSupplyDrop.sqf index 7a597548..623cf77c 100644 --- a/Functions/Supports/fn_arsenalSupplyDrop.sqf +++ b/Functions/Supports/fn_arsenalSupplyDrop.sqf @@ -34,8 +34,12 @@ params [ // get directions for vehicle to fly private _flyDirection = round (random 360); private _flyFromDirection = [_flyDirection + 180] call CBAP_fnc_simplifyAngle; -private _spawnPosition = _dropPosition getPos [FLY_RADIUS,_flyFromDirection]; -_spawnPosition set [2,DROP_ALT]; +private _spawnPosition = [ + _dropPosition, + FLY_RADIUS, + _flyFromDirection +] call KISKA_fnc_getPosRelativeSurface; +_spawnPosition vectorAdd [0,0,DROP_ALT]; private _relativeDirection = _spawnPosition getDir _dropPosition; diff --git a/Functions/Supports/fn_callingForSupportMaster.sqf b/Functions/Supports/fn_callingForSupportMaster.sqf index 63725d26..2d7553b8 100644 --- a/Functions/Supports/fn_callingForSupportMaster.sqf +++ b/Functions/Supports/fn_callingForSupportMaster.sqf @@ -57,7 +57,7 @@ if (_targetPosition isEqualTo []) exitWith { \ #define NUMBER_OF_PARATROOPERS 5 #define HELI_CAS_EXPRESSION(VEHICLE_TYPE,TIME_ON_STATION,FLYIN_ALT,DEFAULT_TYPE,GLOBAL_VAR) \ - [BLWK_playAreaCenter,BLWK_playAreaRadius,VEHICLE_TYPE,TIME_ON_STATION,10,FLYIN_ALT,-1,DEFAULT_TYPE,GLOBAL_VAR] call BLWK_fnc_passiveHelicopterGunner; \ + [VEHICLE_TYPE,TIME_ON_STATION,FLYIN_ALT,DEFAULT_TYPE,GLOBAL_VAR] call BLWK_fnc_passiveHelicopterGunner; \ CAS_RADIO diff --git a/Functions/Supports/fn_daisyCutter.sqf b/Functions/Supports/fn_daisyCutter.sqf index 02c7ccd9..57ed067f 100644 --- a/Functions/Supports/fn_daisyCutter.sqf +++ b/Functions/Supports/fn_daisyCutter.sqf @@ -45,8 +45,12 @@ if (_dropPosition isEqualType objNull) then { // get directions for vehicle to fly private _flyDirection = round (random 360); private _flyFromDirection = [_flyDirection + 180] call CBAP_fnc_simplifyAngle; -private _spawnPosition = _dropPosition getPos [FLY_RADIUS,_flyFromDirection]; -_spawnPosition set [2,DROP_ALT]; +private _spawnPosition = [ + _dropPosition, + FLY_RADIUS, + _flyFromDirection +] call KISKA_fnc_getPosRelativeSurface; +_spawnPosition vectorAdd [0,0,DROP_ALT]; private _relativeDirection = _spawnPosition getDir _dropPosition; diff --git a/Functions/Supports/fn_passiveHelicopterGunner.sqf b/Functions/Supports/fn_passiveHelicopterGunner.sqf index 66523351..137f04cb 100644 --- a/Functions/Supports/fn_passiveHelicopterGunner.sqf +++ b/Functions/Supports/fn_passiveHelicopterGunner.sqf @@ -3,334 +3,102 @@ Function: BLWK_fnc_passiveHelicopterGunner Description: - Spawns a helicopter that will partol a given area for a period of time. + Spawns a helicopter that will partol a given area for a period of time. Parameters: - 0: _centerPosition : - The position around which the helicopter will patrol - 1: _radius : - The size of the radius to patrol around - 2: _aircraftType : - The class of the helicopter to spawn - 3: _timeOnStation : - How long will the aircraft be supporting - 4: _supportSpeedLimit : - The max speed the aircraft can fly while in the support radius - 5: _flyinHeight : - The altittude the aircraft flys at - 6: _approachBearing : - The bearing from which the aircraft will approach from (if below 0, it will be random) - 7: _globalLimiter - The global used to limit having too many of a certain support active at any time - 8: _side : - The side of the created helicopter + 0: _aircraftType : - The class of the helicopter to spawn + 1: _timeOnStation : - How long will the aircraft be supporting + 2: _flyinHeight : - The altittude the aircraft flys at + 3: _approachBearing : - The bearing from which the aircraft will approach from (if below 0, it will be random) + 4: _defaultVehicleType : - If the _aircraftType fails to meet the requirements + to support, the fallback vehicle type that should be used + 5: _globalLimiter - The global used to limit having too many of a certain support active at any time + 6: _side : - The side of the created helicopter Returns: - ARRAY - The vehicle info - 0: - The vehicle created - 1: - The vehicle crew - 2: - The group the crew is a part of - 3: - Turret units + ARRAY - The vehicle info + 0: - The vehicle created + 1: - The vehicle crew + 2: - The group the crew is a part of + 3: - Turret units Examples: (begin example) - [ - BLWK_playAreaCenter, - BLWK_playAreaRadius, - [7] call BLWK_fnc_getFriendlyVehicleClass, - 180, - 20, - 50, - 0, - "B_Heli_Attack_01_dynamicLoadout_F" - ] call BLWK_fnc_passiveHelicopterGunner; + private _aircraftType = [7] call BLWK_fnc_getFriendlyVehicleClass; + private _timeOnStation = 300; + private _flyInHeight = 30; + private _defaultVehicleType = "B_Heli_Attack_01_dynamicLoadout_F"; + + [ + _aircraftType, + _timeOnStation, + _flyInHeight, + _defaultVehicleType + ] call BLWK_fnc_passiveHelicopterGunner; (end) Author(s): - Ansible2 // Cipher - - - - -Issues: - - Needs to use event handlers for the destruction of the helicopter to say over the radio that the support is dead instead of a loop + Ansible2 ---------------------------------------------------------------------------- */ scriptName "BLWK_fnc_passiveHelicopterGunner"; -#define SPAWN_DISTANCE 2000 -#define DETECT_ENEMY_RADIUS 700 -#define MIN_RADIUS 200 -#define STAR_BEARINGS [0,144,288,72,216] -#define VEHICLE_DOWNED(theVehicle) ((!alive theVehicle) OR {(crew theVehicle) isEqualTo []} OR {((getPosATL theVehicle) select 2) < 3}) +#define SPEED_LIMIT 10 +#define FLY_IN_DIRECTION -1 params [ - "_centerPosition", - "_radius", - "_aircraftType", - "_timeOnStation", - ["_supportSpeedLimit",10,[123]], - ["_flyInHeight",30,[123]], - ["_approachBearing",-1], - ["_defaultVehicleType",""], - ["_globalLimiter",""], - ["_side",BLUFOR] + ["_aircraftType","",[""]], + ["_timeOnStation",300,[123]], + ["_flyInHeight",30,[123]], + ["_defaultVehicleType","",[""]], + ["_globalLimiter","",[""]], + ["_side",BLUFOR,[BLUFOR]] ]; -/* ---------------------------------------------------------------------------- - verify vehicle has turrets that are not fire from vehicle and not copilot positions ----------------------------------------------------------------------------- */ -private _turretsWithWeapons = [_aircraftType] call KISKA_fnc_classTurretsWithGuns; - -// go to default aircraft type if no suitable turrets are found -if (_turretsWithWeapons isEqualTo []) exitWith { - if (_aircraftType != _defaultVehicleType AND {_defaultVehicleType != ""}) then { - [[_aircraftType," does not meet standards for function, falling back to: ",_defaultVehicleType],false] call KISKA_fnc_log; - private _newParams = _this; - _newParams set [2,_defaultVehicleType]; - _newParams call BLWK_fnc_passiveHelicopterGunner; - } else { - [[_aircraftType," does not meet standards for function and there is no default to fall back on"],true] call KISKA_fnc_log; - [] - }; -}; - - if (_globalLimiter isNotEqualTo "") then { - missionNamespace setVariable [_globalLimiter,true,true]; -}; - - -/* ---------------------------------------------------------------------------- - Create vehicle ----------------------------------------------------------------------------- */ -if (_approachBearing < 0) then { - _approachBearing = round (random 360); -}; -private _spawnPosition = _centerPosition getPos [SPAWN_DISTANCE,_approachBearing + 180]; -_spawnPosition set [2,_flyInHeight]; - -private _vehicleArray = [_spawnPosition,0,_aircraftType,_side] call BIS_fnc_spawnVehicle; - - -private _vehicle = _vehicleArray select 0; -_vehicle flyInHeight _flyInHeight; -[BLWK_zeus,[[_vehicle],true]] remoteExec ["addCuratorEditableObjects",2]; - - - -// make crew somewhat more effective by changing their behaviour -private _turretUnits = []; -private _vehicleCrew = _vehicleArray select 1; -private _turretSeperated = false; -_vehicleCrew apply { - _x allowDamage false; - _x disableAI "SUPPRESSION"; - _x disableAI "RADIOPROTOCOL"; - _x setSkill 1; - - // give turrets their own groups so that they can engage targets at will - if ((_vehicle unitTurret _x) in _turretsWithWeapons) then { - /* - About seperating one turret... - My testing has revealed that in order to have both turrets on a helicopter (if it has two) - engaging targets simultaneously, one needs to be in a seperate group from the pilot, and one - needs to be grouped with the pilot. - */ - if !(_turretSeperated) then { - _turretSeperated = true; - private _group = createGroup _side; - [_x] joinSilent _group; - _group setBehaviour "COMBAT"; - _group setCombatMode "RED"; - }; - _turretUnits pushBack _x; - } else { // disable targeting for the other crew - _x disableAI "AUTOCOMBAT"; - _x disableAI "TARGET"; - //_x disableAI "AUTOTARGET"; - _x disableAI "FSM"; - }; + missionNamespace setVariable [_globalLimiter,true,true]; }; -_vehicleArray pushBack _turretUnits; - -// keep the pilots from freaking out under fire -private _pilotsGroup = _vehicleArray select 2; -_pilotsGroup setBehaviour "CARELESS"; // Only careless group will follow speed limit -// the pilot group's combat mode MUST be a fire-at-will version as it adjusts it for the entire vehicle -_pilotsGroup setCombatMode "RED"; - - - -/* ---------------------------------------------------------------------------- - Move to support zone ----------------------------------------------------------------------------- */ -private _params = [ - _centerPosition, - _radius, - _timeOnStation, - _supportSpeedLimit, - _approachBearing, - _globalLimiter, - _side, - _vehicle, - _pilotsGroup, - _vehicleCrew, - _turretUnits +private _onSupportEnd = [[_globalLimiter,_side],{ + _this params ["_heli","","_crew"]; + _thisArgs params ["_globalLimiter","_side"]; + if (_globalLimiter isNotEqualTo "") then { + missionNamespace setVariable [_globalLimiter,false,true]; + }; + + if (_side isNotEqualTo BLUFOR) exitWith {}; + + if (isNull (currentPilot _heli)) then { + [TYPE_HELO_DOWN] call BLWK_fnc_supportRadioGlobal; + } else { + [TYPE_CAS_ABORT] call BLWK_fnc_supportRadioGlobal; + }; +}]; + + +private _args = [ + BLWK_playAreaCenter, + BLWK_playAreaRadius, + _aircraftType, + _timeOnStation, + SPEED_LIMIT, + _flyInHeight, + FLY_IN_DIRECTION, + _side, + _onSupportEnd ]; -_params spawn { - params [ - "_centerPosition", - "_radius", - "_timeOnStation", - "_supportSpeedLimit", - "_approachBearing", - "_globalLimiter", - "_side", - "_vehicle", - "_pilotsGroup", - "_vehicleCrew", - "_turretUnits" - ]; - - // once you go below a certain radius, it becomes rather unnecessary - if (_radius < MIN_RADIUS) then { - _radius = MIN_RADIUS; - }; - - private _downed = false; - - // move to support zone - waitUntil { - if (VEHICLE_DOWNED(_vehicle)) exitWith { - _downed = true; - true - }; - if ((_vehicle distance2D _centerPosition) <= _radius) exitWith { - true - }; +private _heliInfo = _args call KISKA_fnc_helicopterGunner; - _vehicle move _centerPosition; - - sleep 2; - - false - }; - - // delete crew if vehicle got blown up on the way - private _fn_exitForDownedVehicle = { - if (_globalLimiter isNotEqualTo "") then { - missionNamespace setVariable [_globalLimiter,false,true]; - }; - - if (_side isEqualTo BLUFOR) then { - [TYPE_HELO_DOWN] call BLWK_fnc_supportRadioGlobal; - }; - - _vehicleCrew apply { - deleteVehicle _x; - }; - - if (alive _vehicle) then { - _vehicle setDamage 1; - - }; - - }; - - if (_downed OR {VEHICLE_DOWNED(_vehicle)}) exitWith { - call _fn_exitForDownedVehicle; - }; - - - /* ---------------------------------------------------------------------------- - Do support - ---------------------------------------------------------------------------- */ - // to keep helicopters from just wildly flying around - _vehicle limitSpeed _supportSpeedLimit; - - private _fn_getTargets = { - (_vehicle nearEntities [["MAN","CAR","TANK"],DETECT_ENEMY_RADIUS]) select { - !(isAgent teamMember _x) AND - {[side _x, _side] call BIS_fnc_sideIsEnemy} - }; - }; - private _targetsInArea = []; - - private _sleepTime = _timeOnStation / 5; - private "_currentTarget"; - private _dead = false; - for "_i" from 0 to 4 do { - - if (_downed OR {VEHICLE_DOWNED(_vehicle)}) then { - _downed = true; - break; - }; - - _targetsInArea = call _fn_getTargets; - if !(_targetsInArea isEqualTo []) then { - _targetsInArea apply { - _currentTarget = _x; - _turretUnits apply { - _x reveal [_currentTarget,4]; - }; - }; - }; - - _vehicle doMove (_centerPosition getPos [_radius,STAR_BEARINGS select _i]); - - sleep _sleepTime; - }; - - - /* ---------------------------------------------------------------------------- - After support is done - ---------------------------------------------------------------------------- */ - if (_downed OR {VEHICLE_DOWNED(_vehicle)}) exitWith { - call _fn_exitForDownedVehicle; - }; - - if (_globalLimiter isNotEqualTo "") then { - missionNamespace setVariable [_globalLimiter,false,true]; - }; - - if (_side isEqualTo BLUFOR) then { - [TYPE_CAS_ABORT] call BLWK_fnc_supportRadioGlobal; - }; - - - // remove speed limit - _vehicle limitSpeed 99999; - - // get helicopter to disengage and rtb - (currentPilot _vehicle) disableAI "AUTOTARGET"; - _pilotsGroup setCombatMode "BLUE"; - - // not using waypoints here because they are auto-deleted for an unkown reason a few seconds after being created for the unit - - // return to spawn position area - private _deletePosition = _centerPosition getPos [SPAWN_DISTANCE,_approachBearing + 180]; - _vehicle doMove _deletePosition; - - waitUntil { - if (_downed OR {VEHICLE_DOWNED(_vehicle)}) exitWith { - _downed = true; - true - }; - - if ((_vehicle distance2D _deletePosition) <= 200) exitWith { - true - }; - - sleep 2; - false - }; - - _vehicleCrew apply { - deleteVehicle _x; - }; +if (_heliInfo isEqualTo []) then { + _args set [2,_defaultVehicleType]; + _heliInfo = _args call KISKA_fnc_helicopterGunner; +}; - if (_downed) then { - _vehicle setDamage 1; - } else { - deleteVehicle _vehicle; - }; -}; +_heliInfo params ["_helicopter"]; +[BLWK_zeus,[[_helicopter],true]] remoteExec ["addCuratorEditableObjects",2]; -_vehicleArray +_heliInfo diff --git a/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf index 6afe13dc..cda5d95d 100644 --- a/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf +++ b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf @@ -35,11 +35,12 @@ localNamespace setVariable ["BLWK_droneWave_allDronesCreated",false]; private _droneGroup = createGroup OPFOR; private _flyDirection = round (random 360); private _flyFromDirection = [_flyDirection + 180] call CBAP_fnc_simplifyAngle; - private _spawnPosition = BLWK_mainCrate getPos [ + private _spawnPosition = [ + BLWK_mainCrate, BLWK_playAreaRadius + (random [100,125,150]), _flyFromDirection - ]; - _spawnPosition set [2,FLY_HEIGHT]; + ] call KISKA_fnc_getPosRelativeSurface; + _spawnPosition vectorAdd [0,0,FLY_HEIGHT]; // Create private _droneSpawnInfo = [ diff --git a/Functions/Wave Type Libraries/Helicopter Wave Lib/fn_helicopterWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Helicopter Wave Lib/fn_helicopterWave_onWaveInit.sqf index d99fbf29..cc91f141 100644 --- a/Functions/Wave Type Libraries/Helicopter Wave Lib/fn_helicopterWave_onWaveInit.sqf +++ b/Functions/Wave Type Libraries/Helicopter Wave Lib/fn_helicopterWave_onWaveInit.sqf @@ -43,13 +43,9 @@ private _fn_spawnHeli = { }; private _vehicleArray = [ - BLWK_playAreaCenter, - BLWK_playAreaRadius, _vehicleClass, 99999, - 10, random [40,50,60], - -1, _defaultAircraft, "", OPFOR @@ -57,12 +53,12 @@ private _fn_spawnHeli = { private _crew = _vehicleArray select 1; _crew apply { - [_x] remoteExecCall ["BLWK_fnc_addToMustKillList",2]; [_x] call BLWK_fnc_spawnQueue_addManEventhandlers; _x allowDamage true; _x setSkill 0.05; }; + [_crew] remoteExecCall ["BLWK_fnc_addToMustKillList",2]; private _heli = _vehicleArray select 0; [_heli] call BLWK_fnc_event_addVehicleKilledHandler; diff --git a/KISKA Systems/KISKA Functions.hpp b/KISKA Systems/KISKA Functions.hpp index 4df788a8..ffaba214 100644 --- a/KISKA Systems/KISKA Functions.hpp +++ b/KISKA Systems/KISKA Functions.hpp @@ -94,7 +94,7 @@ class KISKA class battleSound {}; }; - class KISKA_utillities + class KISKA_utilities { file = "KISKA Systems\KISKA Utility Functions"; class addArsenal @@ -175,6 +175,13 @@ class KISKA {}; class supplyDrop {}; + + class getPosRelativeSurface + {}; + class engageHeliTurretsLoop + {}; + class helicopterGunner + {}; class managedRun_execute {}; diff --git a/KISKA Systems/KISKA Utility Functions/fn_CAS.sqf b/KISKA Systems/KISKA Utility Functions/fn_CAS.sqf index 1846acca..e8f9c82a 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_CAS.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_CAS.sqf @@ -202,11 +202,21 @@ if (_exitToDefault) exitwith { }; +/* ---------------------------------------------------------------------------- + Define attack function +---------------------------------------------------------------------------- */ + + /* ---------------------------------------------------------------------------- Position plane towards target ---------------------------------------------------------------------------- */ -private _planeSpawnPosition = _attackPosition getPos [_spawnDistance,_attackDirection + 180]; -_planeSpawnPosition set [2,_spawnHeight]; +private _planeSpawnPosition = [ + _attackPosition, + _spawnDistance, + (_attackDirection + 180) +] call KISKA_fnc_getPosRelativeSurface; +_planeSpawnPosition vectorAdd [0,0,_spawnHeight]; + private _planeArray = [_planeSpawnPosition,_attackDirection,_planeClass,_side,false] call KISKA_fnc_spawnVehicle; private _plane = _planeArray select 0; private _crew = _planeArray select 1; diff --git a/KISKA Systems/KISKA Utility Functions/fn_engageHeliTurretsLoop.sqf b/KISKA Systems/KISKA Utility Functions/fn_engageHeliTurretsLoop.sqf new file mode 100644 index 00000000..633cb2fd --- /dev/null +++ b/KISKA Systems/KISKA Utility Functions/fn_engageHeliTurretsLoop.sqf @@ -0,0 +1,190 @@ +/* ---------------------------------------------------------------------------- +Function: KISKA_fnc_engageHeliTurretsLoop + +Description: + Sets up a helicopter's turrets to be able to properly engage enemies without + without the pilot going crazy. + + Starts a loop that will reveal targets within a given radius to gunners to engage. + + You can use variables in the _heli's namepsace to adjust params dynamically: + "KISKA_heliTurrets_endLoop" - ends the function + "KISKA_heliTurrets_sleepTime" - adjusts the _sleepTime param + "KISKA_heliTurrets_revealAccuracy" - adjusts the _revealAccuracy param + "KISKA_heliTurrets_detectionRadius" - adjusts the _detectionRadius param + "KISKA_heliTurrets_running" - checks if the system is running + +Parameters: + 0: _heli : - The helicopter to set up + 1: _sleepTime : - Time in between each "refresh" of the targets gunners are revealed + 2: _revealAccuracy : - The accuracy of the reveals of targets for gunners + 3: _detectionRadius : - The radius within to search for targets for the gunners + 4: _skill : - The skill of the vehicle crew + 5: _makeInvulnerable : - Makes vehicle crew invulnerable or not + 6: _turretsWithWeapons : - If you've already found which turrets to regard as "gunner" turrets, pass their turret paths + or the function will get them. + +Returns: + NOTHING + +Examples: + (begin example) + [ + _vehicle, + 5, + 4, + 250, + 1, + true + ] spawn KISKA_fnc_engageHeliTurretsLoop; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "KISKA_fnc_engageHeliTurretsLoop"; + +#define MIN_SLEEP_TIME 0.01 +#define EXIT_VAR_STR "KISKA_heliTurrets_endLoop" +#define SLEEP_TIME_VAR_STR "KISKA_heliTurrets_sleepTime" +#define REVEAL_ACC_VAR_STR "KISKA_heliTurrets_revealAccuracy" +#define IS_RUNNING_VAR_STR "KISKA_heliTurrets_running" +#define DETECT_RADIUS_VAR_STR "KISKA_heliTurrets_detectionRadius" + +if (!canSuspend) exitWith { + ["Needs to be run in scheduled! Exiting to scheduled...",true] call KISKA_fnc_log; + _this spawn KISKA_fnc_engageHeliTurretsLoop; +}; + + +params [ + ["_heli",objNull,[objNull]], + ["_sleepTime",5,[123]], + ["_revealAccuracy",4,[123]], + ["_detectionRadius",250,[123]], + ["_skill",1,[123]], + ["_makeInvulnerable",false,[true]], + ["_turretsWithWeapons",[],[[]]] +]; + + +if (isNull _heli) exitWith { + ["A null object was passed",true] call KISKA_fnc_log; + nil +}; + + +/* ---------------------------------------------------------------------------- + verify vehicle is compatible +---------------------------------------------------------------------------- */ +private _aircraftType = typeOf _heli; +if (_turretsWithWeapons isEqualTo []) then { + _turretsWithWeapons = [_aircraftType] call KISKA_fnc_classTurretsWithGuns; +}; +if (_turretsWithWeapons isEqualTo []) exitWith { + [[_aircraftType," does not have properly configured turrets!"],true] call KISKA_fnc_log; + nil +}; + + + +/* ---------------------------------------------------------------------------- + Prepare AI +---------------------------------------------------------------------------- */ +private _turretUnits = []; +private _turretSeperated = false; +private _vehicleCrew = crew _heli; +private _side = side (_vehicleCrew select 0); + +_vehicleCrew apply { + if (_makeInvulnerable) then { + _x allowDamage false; + }; + _x setSkill _skill; + + _x disableAI "SUPPRESSION"; + _x disableAI "RADIOPROTOCOL"; + + // give turrets their own groups so that they can engage targets at will + if ((_heli unitTurret _x) in _turretsWithWeapons) then { + /* + About seperating one turret... + My testing has revealed that in order to have both turrets on a helicopter (if it has two) + engaging targets simultaneously, one needs to be in a seperate group from the pilot, and one + needs to be grouped with the pilot. + */ + if !(_turretSeperated) then { + _turretSeperated = true; + private _group = createGroup _side; + [_x] joinSilent _group; + _group setCombatBehaviour "COMBAT"; + _group setCombatMode "RED"; + }; + _turretUnits pushBack _x; + } else { // disable targeting for the other crew + _x disableAI "AUTOCOMBAT"; + _x disableAI "TARGET"; + //_x disableAI "AUTOTARGET"; + _x disableAI "FSM"; + }; +}; + +// keep the pilots from freaking out under fire +private _pilotsGroup = group (currentPilot _heli); +_pilotsGroup setBehaviour "CARELESS"; // Only careless group will follow speed limit +// the pilot group's combat mode MUST be a fire-at-will version as it adjusts it for the entire vehicle +_pilotsGroup setCombatMode "RED"; + + + +/* ---------------------------------------------------------------------------- + Loop +---------------------------------------------------------------------------- */ +private _fn_getTargets = { + (_heli nearEntities [["MAN","CAR","TANK"],(_heli getVariable [DETECT_RADIUS_VAR_STR, _detectionRadius])]) select { + !(isAgent teamMember _x) AND + {[side _x, _side] call BIS_fnc_sideIsEnemy} + }; +}; + + +if (_sleepTime < MIN_SLEEP_TIME) then { + _sleepTime = MIN_SLEEP_TIME; +}; + + +_heli setVariable [EXIT_VAR_STR,false]; +_heli setVariable [IS_RUNNING_VAR_STR,true]; +_heli setVariable [DETECT_RADIUS_VAR_STR, _detectionRadius]; +_heli setVariable [SLEEP_TIME_VAR_STR, _sleepTime]; +_heli setVariable [REVEAL_ACC_VAR_STR, _revealAccuracy]; + + +private _targetsInArea = []; +// using waituntil to avoid running more then once a frame +waitUntil { + if (!(alive _heli) OR (_heli getVariable [EXIT_VAR_STR,false])) exitWith {true}; + + _targetsInArea = call _fn_getTargets; + if (_targetsInArea isNotEqualTo []) then { + + _targetsInArea apply { + _currentTarget = _x; + + _turretUnits apply { + if !(isNull _x) then { + _x reveal [_currentTarget,(_heli getVariable [REVEAL_ACC_VAR_STR, _revealAccuracy])]; + }; + }; + + }; + + }; + + sleep (_heli getVariable [SLEEP_TIME_VAR_STR, _sleepTime]); + + false +}; + +_heli setVariable [IS_RUNNING_VAR_STR,false]; +_heli setVariable [EXIT_VAR_STR,false]; diff --git a/KISKA Systems/KISKA Utility Functions/fn_getPosRelativeSurface.sqf b/KISKA Systems/KISKA Utility Functions/fn_getPosRelativeSurface.sqf new file mode 100644 index 00000000..5fb6dc4e --- /dev/null +++ b/KISKA Systems/KISKA Utility Functions/fn_getPosRelativeSurface.sqf @@ -0,0 +1,50 @@ +/* ---------------------------------------------------------------------------- +Function: KISKA_fnc_getPosRelativeSurface + +Description: + Returns a relative position but that the position is at the 0 position for the + surface beneath (being either water or the terrain) in an ATL format. + + This means the z will always be 0 or the height of the sea above the terrain level + at the given _centerPosition. + +Parameters: + 0: _centerPosition - The center position to find a + relative position to. If a 2d position, height will be 0. + 1: _distance - The distance away from the _centerPosition to get the position + 2: _bearing - The direction relative to the position to find the new position + +Returns: + PositionATL[] - the new position + +Examples: + (begin example) + [ + player, + 100, + 180 + ] call KISKA_fnc_getPosRelativeSurface; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "KISKA_fnc_getPosRelativeSurface"; + +params [ + ["_centerPosition",[],[objNull,[]],[2,3]], + ["_distance",0,[123]], + ["_bearing",0,[123]] +]; + + +private _relativePosition = _centerPosition getPos [_distance,_bearing]; +private _height = _relativePosition select 2; +private _isUnderwater = _height < 0; +if (_isUnderwater) then { + _relativePosition set [2,0]; + _relativePosition = ASLToATL _relativePosition; +}; + + +_relativePosition diff --git a/KISKA Systems/KISKA Utility Functions/fn_helicopterGunner.sqf b/KISKA Systems/KISKA Utility Functions/fn_helicopterGunner.sqf new file mode 100644 index 00000000..ca6d90f3 --- /dev/null +++ b/KISKA Systems/KISKA Utility Functions/fn_helicopterGunner.sqf @@ -0,0 +1,283 @@ +/* ---------------------------------------------------------------------------- +Function: KISKA_fnc_helicopterGunner + +Description: + Spawns a helicopter (or uses an existing one) to partol a given area for a period of time and + engage enemy targets in a given area. + +Parameters: + 0: _centerPosition : - The position around which the helicopter will patrol + 1: _radius : - The size of the radius to patrol around + 2: _aircraftType : - The class of the helicopter to spawn + If object, it is expected that this is a helicopter with crew + 3: _timeOnStation : - How long will the aircraft be supporting + 4: _supportSpeedLimit : - The max speed the aircraft can fly while in the support radius + 5: _flyinHeight : - The altittude the aircraft flys at + 6: _approachBearing : - The bearing from which the aircraft will approach from (if below 0, it will be random) + This has no effect if an object is used for _aircraftType + 7: _side : - The side of the created helicopter + 8: _postSupportCode : - Code to execute after the support completes. + See KISKA_fnc_callBack. + The default behaviour is for the aircraft to move 2000 meters away and for + its complete crew and self to be deleted. + + Parameters: + - 0: - The helicopter confucting support + - 1: - The group the pilot belongs to + - 2: - The full vehicle crew + - 3: - The position the helicopter was supporting + +Returns: + ARRAY - The vehicle info + 0: - The vehicle created + 1: - The vehicle crew + 2: - The group the crew is a part of + +Examples: + (begin example) + [ + player, + 250, + "B_Heli_Attack_01_dynamicLoadout_F" + ] call KISKA_fnc_helicopterGunner; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "KISKA_fnc_helicopterGunner"; + +#define SPAWN_DISTANCE 2000 +#define DETECT_ENEMY_RADIUS 700 +#define MIN_RADIUS 200 +#define STAR_BEARINGS [0,144,288,72,216] + +params [ + "_centerPosition", + ["_radius",200,[123]], + ["_aircraftType","",["",objNull]], + ["_timeOnStation",180,[123]], + ["_supportSpeedLimit",10,[123]], + ["_flyInHeight",30,[123]], + ["_approachBearing",-1,[123]], + ["_side",BLUFOR,[sideUnknown]], + ["_postSupportCode",{},["",{},[]]] +]; + + +/* ---------------------------------------------------------------------------- + verify vehicle has turrets that are not fire from vehicle and not copilot positions +---------------------------------------------------------------------------- */ +private _vehicleArray = []; +if (_aircraftType isEqualType objNull) then { + private _aircraft = _aircraftType; + _aircraftType = typeOf _aircraft; + + _vehicleArray pushBack _aircraft; + _vehicleArray pushBack (crew _aircraft); + _vehicleArray pushBack (group (currentPilot _aircraft)); +}; +private _turretsWithWeapons = [_aircraftType] call KISKA_fnc_classTurretsWithGuns; + +// go to default aircraft type if no suitable turrets are found +if (_turretsWithWeapons isEqualTo []) exitWith { + [[_aircraftType," does not meet standards for function!"],false] call KISKA_fnc_log; + [] +}; + + +/* ---------------------------------------------------------------------------- + Create vehicle +---------------------------------------------------------------------------- */ +if (_approachBearing < 0) then { + _approachBearing = round (random 360); +}; + +private _spawnPosition = [ + _centerPosition, + SPAWN_DISTANCE, + (_approachBearing + 180) +] call KISKA_fnc_getPosRelativeSurface; +_spawnPosition vectorAdd [0,0,_flyInHeight]; + +if (_vehicleArray isEqualTo []) then { + _vehicleArray = [_spawnPosition,0,_aircraftType,_side, false] call KISKA_fnc_spawnVehicle; +}; + +// disable HC transfer +private _pilotsGroup = _vehicleArray select 2; +// [_pilotsGroup,true] call KISKA_fnc_ACEX_setHCTransfer; + +private _vehicle = _vehicleArray select 0; +// if using an already exisiting aircraft, the enigne must be on prior to getting a "move" command +if !(isEngineOn _vehicle) then { + _vehicle engineOn true; +}; +_vehicle flyInHeight _flyInHeight; +// notify side if destroyed +_vehicle addEventHandler ["KILLED",{ + params ["_vehicle"]; + //[TYPE_HELO_DOWN,_vehicleCrew select 0,_side] call KISKA_fnc_supportRadio; + + (crew _vehicle) apply { + if (alive _x) then { + deleteVehicle _x + }; + }; +}]; + + + +private _vehicleCrew = _vehicleArray select 1; + + +/* ---------------------------------------------------------------------------- + Move to support zone +---------------------------------------------------------------------------- */ +// move command only supports position arrays +if (_centerPosition isEqualType objNull) then { + _centerPosition = getPosATL _centerPosition; +}; + +private _params = [ + _centerPosition, + _radius, + _timeOnStation, + _supportSpeedLimit, + _approachBearing, + _side, + _vehicle, + _pilotsGroup, + _vehicleCrew, + _postSupportCode +]; + +_params spawn { + params [ + "_centerPosition", + "_radius", + "_timeOnStation", + "_supportSpeedLimit", + "_approachBearing", + "_side", + "_vehicle", + "_pilotsGroup", + "_vehicleCrew", + "_postSupportCode" + ]; + + // once you go below a certain radius, it becomes rather unnecessary + if (_radius < MIN_RADIUS) then { + _radius = MIN_RADIUS; + }; + + // move to support zone + // checking driver instead of cache to see if they got out of the vehicle + waitUntil { + if ( + (!alive _vehicle) OR + {isNull (driver _vehicle)} OR + {(_vehicle distance2D _centerPosition) <= _radius} + ) then { + breakWith true + }; + _pilotsGroup move _centerPosition; + sleep 2; + false + }; + + + /* ---------------------------------------------------------------------------- + Do support + ---------------------------------------------------------------------------- */ + [ + _vehicle, + 5, + 4, + _radius * 2, + 1, + true + ] spawn KISKA_fnc_engageHeliTurretsLoop; + + // to keep helicopters from just wildly flying around + _vehicle limitSpeed _supportSpeedLimit; + + private _sleepTime = _timeOnStation / 5; + for "_i" from 0 to 4 do { + if ( + (!alive _vehicle) OR + (isNull (driver _vehicle)) + ) then { + break; + }; + + _vehicle doMove (_centerPosition getPos [_radius,STAR_BEARINGS select _i]); + sleep _sleepTime; + }; + + _vehicle setVariable ["KISKA_heliTurrets_endLoop",true]; + + /* ---------------------------------------------------------------------------- + After support is done + ---------------------------------------------------------------------------- */ + //[TYPE_CAS_ABORT,_vehicleCrew select 0,_side] call KISKA_fnc_supportRadio; + + // remove speed limit + _vehicle limitSpeed 99999; + + if (_postSupportCode isNotEqualTo {}) exitWith { + [ + [ + _vehicle, + _pilotsGroup, + _vehicleCrew, + _centerPosition + ], + _postSupportCode + ] call KISKA_fnc_callBack; + }; + + // get helicopter to disengage and rtb + (currentPilot _vehicle) disableAI "AUTOTARGET"; + _pilotsGroup setCombatMode "BLUE"; + + // not using waypoints here because they are auto-deleted for an unkown reason a few seconds after being created for the unit + + // return to spawn position area + private _deletePosition = _centerPosition getPos [SPAWN_DISTANCE,_approachBearing + 180]; + _vehicle doMove _deletePosition; + + waitUntil { + if ( + (!alive _vehicle) OR + {(_vehicle distance2D _deletePosition) <= 200} + ) then { + breakWith true + }; + + // if vehicle is disabled and makes a landing, just blow it up + if ( + (((getPosATL _vehicle) select 2) < 2) OR + (isNull (driver _vehicle)) + ) exitWith { + _vehicle setDamage 1; + true + }; + + sleep 2; + false + }; + + + _vehicleCrew apply { + if (alive _x) then { + _vehicle deleteVehicleCrew _x; + }; + }; + if (alive _vehicle) then { + deleteVehicle _vehicle; + }; +}; + + +_vehicleArray diff --git a/KISKA Systems/KISKA Utility Functions/fn_paratroopers.sqf b/KISKA Systems/KISKA Utility Functions/fn_paratroopers.sqf index dbe8af28..a9e88500 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_paratroopers.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_paratroopers.sqf @@ -101,12 +101,15 @@ if (_flyDirection < 0) then { }; -// get spawn position private _flyFromDirection = [_flyDirection + 180] call CBAP_fnc_simplifyAngle; _dropZone set [2,_flyInHeight]; -private _spawnPosition = _dropZone getPos [_spawnDistance,_flyFromDirection]; -_spawnPosition set [2,_flyInHeight]; +private _spawnPosition = [ + _dropZone, + _spawnDistance, + _flyFromDirection +] call KISKA_fnc_getPosRelativeSurface; +_spawnPosition vectorAdd [0,0,_flyInHeight]; /* ---------------------------------------------------------------------------- Create vehicle to drop units diff --git a/KISKA Systems/KISKA Utility Functions/fn_spawnVehicle.sqf b/KISKA Systems/KISKA Utility Functions/fn_spawnVehicle.sqf index ea45ac45..8f9c88ff 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_spawnVehicle.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_spawnVehicle.sqf @@ -6,7 +6,7 @@ Description: Has support for CUP aircraft to spawn at velocity. Parameters: - 0: _spawnPosition - 3D array in the format of PositionATL + 0: _spawnPosition - 3D array in the format of PositionATL (PositionAGL if boat or amphibious). Objects can be used, however, this 1: _spawnDirection - The direction the vehicle is facing when created (relative to north) if _spawnPosition is an object and _spawnDirection == -1, _spawnDirection will be set to the From be2ad131661ddb410d39ff9207c61d6fd6f5833d Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Wed, 19 Jul 2023 20:21:28 -0600 Subject: [PATCH 093/133] (#642): fixed syntax error for mortar wave --- .../Mortar Wave Lib/fn_mortarWave_onWaveInit.sqf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Functions/Wave Type Libraries/Mortar Wave Lib/fn_mortarWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Mortar Wave Lib/fn_mortarWave_onWaveInit.sqf index 45eb6ccd..b9f4ea3c 100644 --- a/Functions/Wave Type Libraries/Mortar Wave Lib/fn_mortarWave_onWaveInit.sqf +++ b/Functions/Wave Type Libraries/Mortar Wave Lib/fn_mortarWave_onWaveInit.sqf @@ -41,8 +41,8 @@ private _mortarGroup = createGroup [OPFOR,true]; _mortarMan moveInGunner _mortarTube; [BLWK_zeus,[[_mortarTube],true]] remoteExec ["addCuratorEditableObjects",2]; -[_mortarMan] spawn { - params ["_mortarMan"]; +[_mortarMan,_mortarTube] spawn { + params ["_mortarMan","_mortarTube"]; // give players a bit of time before starting sleep 20; From f7c57f929aea621f1488564bc58a3a1bb9c8d461 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Fri, 21 Jul 2023 18:26:26 -0600 Subject: [PATCH 094/133] (#642): implemented new helicopter gunner script to fix auto delete issues --- .../Supports/fn_passiveHelicopterGunner.sqf | 5 +- .../fn_helicopterGunner.sqf | 407 +++++++++++++----- 2 files changed, 302 insertions(+), 110 deletions(-) diff --git a/Functions/Supports/fn_passiveHelicopterGunner.sqf b/Functions/Supports/fn_passiveHelicopterGunner.sqf index 137f04cb..3fa86f9f 100644 --- a/Functions/Supports/fn_passiveHelicopterGunner.sqf +++ b/Functions/Supports/fn_passiveHelicopterGunner.sqf @@ -63,17 +63,20 @@ if (_globalLimiter isNotEqualTo "") then { private _onSupportEnd = [[_globalLimiter,_side],{ _this params ["_heli","","_crew"]; _thisArgs params ["_globalLimiter","_side"]; + if (_globalLimiter isNotEqualTo "") then { missionNamespace setVariable [_globalLimiter,false,true]; }; - if (_side isNotEqualTo BLUFOR) exitWith {}; + if (_side isNotEqualTo BLUFOR) exitWith { true }; if (isNull (currentPilot _heli)) then { [TYPE_HELO_DOWN] call BLWK_fnc_supportRadioGlobal; } else { [TYPE_CAS_ABORT] call BLWK_fnc_supportRadioGlobal; }; + + true }]; diff --git a/KISKA Systems/KISKA Utility Functions/fn_helicopterGunner.sqf b/KISKA Systems/KISKA Utility Functions/fn_helicopterGunner.sqf index ca6d90f3..fe729b27 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_helicopterGunner.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_helicopterGunner.sqf @@ -6,7 +6,7 @@ Description: engage enemy targets in a given area. Parameters: - 0: _centerPosition : - The position around which the helicopter will patrol + 0: _centerPosition : - The position around which the helicopter will patrol 1: _radius : - The size of the radius to patrol around 2: _aircraftType : - The class of the helicopter to spawn If object, it is expected that this is a helicopter with crew @@ -19,13 +19,15 @@ Parameters: 8: _postSupportCode : - Code to execute after the support completes. See KISKA_fnc_callBack. The default behaviour is for the aircraft to move 2000 meters away and for - its complete crew and self to be deleted. + its complete crew and self to be deleted. The _postSupportCode should return a `BOOL` + that if `false` will NOT perform the default behaviour in addition to the callback. Parameters: - 0: - The helicopter confucting support - 1: - The group the pilot belongs to - 2: - The full vehicle crew - - 3: - The position the helicopter was supporting + - 3: - The unit that *should* be the pilot of the helicopter + - 4: - The position the helicopter was supporting Returns: ARRAY - The vehicle info @@ -53,7 +55,7 @@ scriptName "KISKA_fnc_helicopterGunner"; #define STAR_BEARINGS [0,144,288,72,216] params [ - "_centerPosition", + ["_centerPosition",[],[objNull,[]],[2,3]], ["_radius",200,[123]], ["_aircraftType","",["",objNull]], ["_timeOnStation",180,[123]], @@ -69,7 +71,8 @@ params [ verify vehicle has turrets that are not fire from vehicle and not copilot positions ---------------------------------------------------------------------------- */ private _vehicleArray = []; -if (_aircraftType isEqualType objNull) then { +private _vehicleExistedBeforeFunction = _aircraftType isEqualType objNull; +if (_vehicleExistedBeforeFunction) then { private _aircraft = _aircraftType; _aircraftType = typeOf _aircraft; @@ -79,9 +82,8 @@ if (_aircraftType isEqualType objNull) then { }; private _turretsWithWeapons = [_aircraftType] call KISKA_fnc_classTurretsWithGuns; -// go to default aircraft type if no suitable turrets are found if (_turretsWithWeapons isEqualTo []) exitWith { - [[_aircraftType," does not meet standards for function!"],false] call KISKA_fnc_log; + [[_aircraftType," does not meet standards for function!"],true] call KISKA_fnc_log; [] }; @@ -89,46 +91,233 @@ if (_turretsWithWeapons isEqualTo []) exitWith { /* ---------------------------------------------------------------------------- Create vehicle ---------------------------------------------------------------------------- */ -if (_approachBearing < 0) then { - _approachBearing = round (random 360); +if (!_vehicleExistedBeforeFunction) then { + if (_approachBearing < 0) then { + _approachBearing = round (random 360); + }; + + private _spawnPosition = [ + _centerPosition, + SPAWN_DISTANCE, + (_approachBearing + 180), + _flyInHeight + ] call KISKA_fnc_getPosRelativeSurface; + + _vehicleArray = [ + _spawnPosition, + 0, + _aircraftType, + _side, + false + ] call KISKA_fnc_spawnVehicle; }; -private _spawnPosition = [ - _centerPosition, - SPAWN_DISTANCE, - (_approachBearing + 180) -] call KISKA_fnc_getPosRelativeSurface; -_spawnPosition vectorAdd [0,0,_flyInHeight]; +_vehicleArray params ["_heli","_heliCrew","_pilotsGroup"]; +private _pilot = currentPilot _heli; -if (_vehicleArray isEqualTo []) then { - _vehicleArray = [_spawnPosition,0,_aircraftType,_side, false] call KISKA_fnc_spawnVehicle; +[_pilotsGroup,true] call KISKA_fnc_ACEX_setHCTransfer; + +// if using an already exisiting aircraft, the enigne must be on prior to getting a "move" command +if !(isEngineOn _heli) then { + _heli engineOn true; }; +_heli flyInHeight _flyInHeight; -// disable HC transfer -private _pilotsGroup = _vehicleArray select 2; -// [_pilotsGroup,true] call KISKA_fnc_ACEX_setHCTransfer; -private _vehicle = _vehicleArray select 0; -// if using an already exisiting aircraft, the enigne must be on prior to getting a "move" command -if !(isEngineOn _vehicle) then { - _vehicle engineOn true; +_heli setVariable ["KISKA_helicopterGunner_vehicleInfo",[_heli,_pilotsGroup,_heliCrew,_pilot]]; +_pilot setVariable ["KISKA_helicopterGunner_vehicleInfo",[_heli,_pilotsGroup,_heliCrew,_pilot]]; + +/* ---------------------------------------------------------------------------- + Eventhandlers +---------------------------------------------------------------------------- */ +/* --------------------------------------- + Heli Killed Event +--------------------------------------- */ +private _heliKilledEventId = _heli addEventHandler ["KILLED", { + params ["_heli"]; + + private _args = _heli getVariable ["KISKA_helicopterGunner_vehicleInfo",[]]; + [ + _heli, + "KISKA_helicopterGunner_event_heliKilled", + _args, + false + ] call BIS_fnc_callScriptedEventHandler; + + [_heli,"KISKA_helicopterGunner_event_heliKilled"] call BIS_fnc_removeAllScriptedEventHandlers; + + _heli setVariable ["KISKA_helicopterGunner_stop",true]; +}]; +_heli setVariable ["KISKA_helicopterGunner_heliKilledEventId",_heliKilledEventId]; + + +/* --------------------------------------- + Pilot Killed Event +--------------------------------------- */ +private _pilotKilledEventId = _pilot addEventHandler ["KILLED", { + params ["_pilot"]; + + private _args = _pilot getVariable ["KISKA_helicopterGunner_vehicleInfo",[]]; + [ + _pilot, + "KISKA_helicopterGunner_event_pilotKilled", + _args, + false + ] call BIS_fnc_callScriptedEventHandler; + + [_pilot,"KISKA_helicopterGunner_event_pilotKilled"] call BIS_fnc_removeAllScriptedEventHandlers; + + private _heli = _args param [0,objNull]; + _heli setVariable ["KISKA_helicopterGunner_stop",true]; +}]; +_pilot setVariable ["KISKA_helicopterGunner_pilotKilledEventId",_pilotKilledEventId]; + + +/* --------------------------------------- + Pilot Getout Event +--------------------------------------- */ +private _pilotGetOutEventId = _pilot addEventHandler ["GetOutMan", { + params ["_pilot"]; + + private _args = _pilot getVariable ["KISKA_helicopterGunner_vehicleInfo",[]]; + [ + _pilot, + "KISKA_helicopterGunner_event_pilotGotOut", + _args, + false + ] call BIS_fnc_callScriptedEventHandler; + + [_pilot,"KISKA_helicopterGunner_event_pilotGotOut"] call BIS_fnc_removeAllScriptedEventHandlers; + + private _heli = _args param [0,objNull]; + _heli setVariable ["KISKA_helicopterGunner_stop",true]; +}]; +_pilot setVariable ["KISKA_helicopterGunner_pilotGotOutEventId",_pilotGetOutEventId]; + + +/* --------------------------------------- + Add default events +--------------------------------------- */ +if (!_vehicleExistedBeforeFunction) then { + [ + _heli, + "KISKA_helicopterGunner_event_heliKilled", + { + params ["_heli","","_heliCrew"]; + + + _heliCrew apply { + _heli deleteVehicleCrew _x; + }; + } + ] call BIS_fnc_addScriptedEventHandler; + + [ + _heli, + "KISKA_helicopterGunner_event_pilotKilled", + { + params ["_heli"]; + _heli setDamage 1; + } + ] call BIS_fnc_addScriptedEventHandler; + + [ + _heli, + "KISKA_helicopterGunner_event_pilotGotOut", + { + params ["_heli"]; + _heli setDamage 1; + } + ] call BIS_fnc_addScriptedEventHandler; }; -_vehicle flyInHeight _flyInHeight; -// notify side if destroyed -_vehicle addEventHandler ["KILLED",{ - params ["_vehicle"]; - //[TYPE_HELO_DOWN,_vehicleCrew select 0,_side] call KISKA_fnc_supportRadio; - - (crew _vehicle) apply { - if (alive _x) then { - deleteVehicle _x + +/* ---------------------------------------------------------------------------- + Post Support Function +---------------------------------------------------------------------------- */ +private _fn_supportEnded = { + params [ + ["_heli",objNull,[objNull]], + ["_pilotsGroup",grpNull,[grpNull]], + ["_heliCrew",[],[[]]], + ["_pilot",objNull,[objNull]], + ["_centerPosition",[],[[]]], + ["_postSupportCode",{},[{},"",[]]], + ["_approachBearing",0,[123]] + ]; + + private _runDefault = true; + private _postSupportCodeIsNotEmpty = (_postSupportCode isNotEqualTo {}) AND (_postSupportCode isNotEqualTo "") AND (_postSupportCode isNotEqualTo []); + if (_postSupportCodeIsNotEmpty) then { + _runDefault = [ + _this, + _postSupportCode + ] call KISKA_fnc_callBack; + }; + + + if ( + (!_runDefault) OR + (_heli getVariable ["KISKA_helicopterGunner_stop",true]) + ) exitWith { + [_heli,"KISKA_helicopterGunner_event_heliKilled"] call BIS_fnc_removeAllScriptedEventHandlers; + [_pilot,"KISKA_helicopterGunner_event_pilotKilled"] call BIS_fnc_removeAllScriptedEventHandlers; + [_pilot,"KISKA_helicopterGunner_event_pilotGotOut"] call BIS_fnc_removeAllScriptedEventHandlers; + + _heli removeEventHandler [ + "KILLED", + _heli getVariable ["KISKA_helicopterGunner_heliKilledEventId",-1] + ]; + _pilot removeEventHandler [ + "KILLED", + _pilot getVariable ["KISKA_helicopterGunner_pilotKilledEventId",-1] + ]; + _pilot removeEventHandler [ + "GetOutMan", + _pilot getVariable ["KISKA_helicopterGunner_pilotGotOutEventId",-1] + ]; + }; + + + // get helicopter to disengage and rtb + _pilot disableAI "AUTOTARGET"; + _pilotsGroup setCombatMode "BLUE"; + + // not using waypoints here because they are auto-deleted for an unkown reason a few seconds after being created for the unit + + // return to spawn position area + private _deletePosition = _centerPosition getPos [SPAWN_DISTANCE,_approachBearing + 180]; + _heli doMove _deletePosition; + + waitUntil { + private _isOnGround = ((getPosATL _heli) select 2) < 2; + if ( + _isOnGround OR + (_heli getVariable ["KISKA_helicopterGunner_stop",true]) OR + {(_heli distance2D _deletePosition) <= 200} + ) then { + if (_isOnGround) then { + _heli setDamage 1; + }; + + breakWith true }; + + sleep 2; + false }; -}]; + // killed event shousld have taken care of cleanup + if !(alive _heli) exitWith {}; + [_heli,"KISKA_helicopterGunner_event_heliKilled"] call BIS_fnc_removeAllScriptedEventHandlers; + [_pilot,"KISKA_helicopterGunner_event_pilotKilled"] call BIS_fnc_removeAllScriptedEventHandlers; + [_pilot,"KISKA_helicopterGunner_event_pilotGotOut"] call BIS_fnc_removeAllScriptedEventHandlers; -private _vehicleCrew = _vehicleArray select 1; + _heliCrew apply { + _heli deleteVehicleCrew _x; + }; + deleteVehicle _heli; +}; /* ---------------------------------------------------------------------------- @@ -139,6 +328,9 @@ if (_centerPosition isEqualType objNull) then { _centerPosition = getPosATL _centerPosition; }; +_heli setVariable ["KISKA_helicopterGunner_stop",false]; + + private _params = [ _centerPosition, _radius, @@ -146,10 +338,12 @@ private _params = [ _supportSpeedLimit, _approachBearing, _side, - _vehicle, + _heli, _pilotsGroup, - _vehicleCrew, - _postSupportCode + _heliCrew, + _pilot, + _postSupportCode, + _fn_supportEnded ]; _params spawn { @@ -160,10 +354,12 @@ _params spawn { "_supportSpeedLimit", "_approachBearing", "_side", - "_vehicle", + "_heli", "_pilotsGroup", - "_vehicleCrew", - "_postSupportCode" + "_heliCrew", + "_pilot", + "_postSupportCode", + "_fn_supportEnded" ]; // once you go below a certain radius, it becomes rather unnecessary @@ -173,17 +369,34 @@ _params spawn { // move to support zone // checking driver instead of cache to see if they got out of the vehicle + private _vehicleEffective = true; waitUntil { + private _isOnGround = ((getPosATL _heli) select 2) < 2; if ( - (!alive _vehicle) OR - {isNull (driver _vehicle)} OR - {(_vehicle distance2D _centerPosition) <= _radius} + _isOnGround OR + (_heli getVariable ["KISKA_helicopterGunner_stop",true]) ) then { + _vehicleEffective = false; breakWith true }; + _pilotsGroup move _centerPosition; sleep 2; - false + + ((_heli distance2D _centerPosition) <= _radius) + }; + + + if !(_vehicleEffective) exitWith { + [ + _heli, + _pilotsGroup, + _heliCrew, + _pilot, + _centerPosition, + _postSupportCode, + _approachBearing + ] call _fn_supportEnded; }; @@ -191,7 +404,7 @@ _params spawn { Do support ---------------------------------------------------------------------------- */ [ - _vehicle, + _heli, 5, 4, _radius * 2, @@ -200,83 +413,59 @@ _params spawn { ] spawn KISKA_fnc_engageHeliTurretsLoop; // to keep helicopters from just wildly flying around - _vehicle limitSpeed _supportSpeedLimit; - - private _sleepTime = _timeOnStation / 5; - for "_i" from 0 to 4 do { + _heli limitSpeed _supportSpeedLimit; + private _sleepTime = 20; + private _numberOfBearings = count STAR_BEARINGS; + private _elapsedTime = 0; + private _bearingIndex = 0; + while {_timeOnStation > _elapsedTime} do { + private _isOnGround = ((getPosATL _heli) select 2) < 2; if ( - (!alive _vehicle) OR - (isNull (driver _vehicle)) + _isOnGround OR + (_heli getVariable ["KISKA_helicopterGunner_stop",true]) ) then { break; }; - _vehicle doMove (_centerPosition getPos [_radius,STAR_BEARINGS select _i]); - sleep _sleepTime; + private _movePos = _centerPosition getPos [_radius,STAR_BEARINGS select _bearingIndex]; + _bearingIndex = _bearingIndex + 1; + if (_bearingIndex >= _numberOfBearings) then { + _bearingIndex = 0; + }; + + _heli doMove _movePos; + + private _newElapsedTime = _elapsedTime + _sleepTime; + private _isLastRotation = _newElapsedTime > _timeOnStation; + if (_isLastRotation) then { + sleep (_timeOnStation - _elapsedTime); + } else { + sleep _sleepTime; + }; + + _elapsedTime = _newElapsedTime; }; - _vehicle setVariable ["KISKA_heliTurrets_endLoop",true]; + // end engage heli turrets loop + _heli setVariable ["KISKA_heliTurrets_endLoop",true]; /* ---------------------------------------------------------------------------- After support is done ---------------------------------------------------------------------------- */ - //[TYPE_CAS_ABORT,_vehicleCrew select 0,_side] call KISKA_fnc_supportRadio; + //[TYPE_CAS_ABORT,_heliCrew select 0,_side] call KISKA_fnc_supportRadio; // remove speed limit - _vehicle limitSpeed 99999; - - if (_postSupportCode isNotEqualTo {}) exitWith { - [ - [ - _vehicle, - _pilotsGroup, - _vehicleCrew, - _centerPosition - ], - _postSupportCode - ] call KISKA_fnc_callBack; - }; - - // get helicopter to disengage and rtb - (currentPilot _vehicle) disableAI "AUTOTARGET"; - _pilotsGroup setCombatMode "BLUE"; - - // not using waypoints here because they are auto-deleted for an unkown reason a few seconds after being created for the unit + _heli limitSpeed 99999; - // return to spawn position area - private _deletePosition = _centerPosition getPos [SPAWN_DISTANCE,_approachBearing + 180]; - _vehicle doMove _deletePosition; - - waitUntil { - if ( - (!alive _vehicle) OR - {(_vehicle distance2D _deletePosition) <= 200} - ) then { - breakWith true - }; - - // if vehicle is disabled and makes a landing, just blow it up - if ( - (((getPosATL _vehicle) select 2) < 2) OR - (isNull (driver _vehicle)) - ) exitWith { - _vehicle setDamage 1; - true - }; - - sleep 2; - false - }; - - - _vehicleCrew apply { - if (alive _x) then { - _vehicle deleteVehicleCrew _x; - }; - }; - if (alive _vehicle) then { - deleteVehicle _vehicle; - }; + [ + _heli, + _pilotsGroup, + _heliCrew, + _pilot, + _centerPosition, + _postSupportCode, + _approachBearing + ] call _fn_supportEnded; }; From 551fc0c84bdef5003b71c9a988bb4adeaac225be Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Fri, 21 Jul 2023 18:36:59 -0600 Subject: [PATCH 095/133] (#642): fixed incorrect variable name in BLWK_fnc_overrunWave_onWaveInit --- .../Overrun Wave Lib/fn_overrunWave_onWaveInit.sqf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_onWaveInit.sqf index 9bd067d5..03edcee0 100644 --- a/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_onWaveInit.sqf +++ b/Functions/Wave Type Libraries/Overrun Wave Lib/fn_overrunWave_onWaveInit.sqf @@ -33,13 +33,13 @@ missionNamespace setVariable ["BLWK_enforceArea",false,true]; [ { private _playerSpawnPosition = localNamespace getVariable "BLWK_overrunWave_playerSpawn"; - BLWK_mainCrate setPosATL _playerPosition; + BLWK_mainCrate setPosATL _playerSpawnPosition; (call CBAP_fnc_players) apply { // don't teleport players in vehicles if (isNull (objectParent _x)) then { _x setPosATL ( - [_playerPosition,15,random 360] call CBAP_fnc_randPos + [_playerSpawnPosition,15,random 360] call CBAP_fnc_randPos ); }; }; From e30357140f0625440c98f1fb68c85a26336f7584 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Fri, 21 Jul 2023 18:38:23 -0600 Subject: [PATCH 096/133] (#642): fixed all wave types having a weight of zero causing undefined behavior --- Functions/Waves/fn_getConfigForWave.sqf | 16 +++++++++++----- .../Headers/missionParams.hpp | 2 ++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Functions/Waves/fn_getConfigForWave.sqf b/Functions/Waves/fn_getConfigForWave.sqf index 9564754d..be825624 100644 --- a/Functions/Waves/fn_getConfigForWave.sqf +++ b/Functions/Waves/fn_getConfigForWave.sqf @@ -50,15 +50,20 @@ private _getAllowedSpecialWaves = { }; private _fn_getNormalWave = { - if (BLWK_currentWaveNumber >= BLWK_normalWavesStartAt) exitWith { + private _selectedNormalWave = DEFAULT_WAVE_CONFIG; + if (BLWK_currentWaveNumber >= BLWK_normalWavesStartAt) then { private _weights = BLWK_normalWaveConfigs apply { missionNamespace getVariable [getText(_x >> "weightVariable"),0]; }; - BLWK_normalWaveConfigs selectRandomWeighted _weights + private _potentialWave = BLWK_normalWaveConfigs selectRandomWeighted _weights; + private _allNormalWavesAreWeightedZero = isNil "_potentialWave"; + if !(_allNormalWavesAreWeightedZero) then { + _selectedNormalWave = _potentialWave; + }; }; - DEFAULT_WAVE_CONFIG + _selectedNormalWave }; @@ -77,11 +82,12 @@ if (_selectSpecialWave) then { _allowedSpecialWaves = call _getAllowedSpecialWaves; }; - _waveConfigPath = selectRandom _allowedSpecialWaves; - if (isNil "_waveConfigPath") then { + private _allSpecialWavesDisabled = _allowedSpecialWaves isEqualTo []; + if (_allSpecialWavesDisabled) then { _waveConfigPath = call _fn_getNormalWave; } else { + _waveConfigPath = selectRandom _allowedSpecialWaves; _usedSpecialWaves pushBack _waveConfigPath; localNamespace setVariable ["BLWK_usedSpecialWaveConfigs",_usedSpecialWaves]; diff --git a/KISKA Systems/KISKA Parameter Menu/Headers/missionParams.hpp b/KISKA Systems/KISKA Parameter Menu/Headers/missionParams.hpp index 2ad7b275..d3c08244 100644 --- a/KISKA Systems/KISKA Parameter Menu/Headers/missionParams.hpp +++ b/KISKA Systems/KISKA Parameter Menu/Headers/missionParams.hpp @@ -1103,6 +1103,8 @@ class KISKA_missionParams title = "Standard Wave Weight"; tooltip = "Typical enemy infantry wave with a possibility of vehicles to spawn"; default = 1; + // uses weighted array to select wave type and at least one weight needs to be above 0 + min = 0.1; }; }; From bf9265e36cc41dff3059721d50bde3bf7062d0b7 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Fri, 21 Jul 2023 21:34:01 -0600 Subject: [PATCH 097/133] (#642): started on suicide wave testing, added todo for issue --- .../fn_spawnQueue_addManEventhandlers.sqf | 2 +- .../fn_spawnQueue_removeManEventhandlers.sqf | 13 ++- .../fn_suicideWave_bomberLoop.sqf | 4 +- .../fn_suicideWave_explodeBomber.sqf | 3 + .../fn_suicideWave_makeBombers.sqf | 109 ++++++++++++++++++ .../fn_suicideWave_onWaveInit.sqf | 66 +---------- Headers/descriptionEXT/functions.hpp | 2 + 7 files changed, 130 insertions(+), 69 deletions(-) create mode 100644 Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_makeBombers.sqf diff --git a/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf b/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf index 855374c2..18941d2c 100644 --- a/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf +++ b/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf @@ -47,7 +47,7 @@ private _killedEventId = _unit addEventHandler ["Killed", { [_killedUnit] remoteExecCall ["BLWK_fnc_event_killedEnemy",_instigator]; }; - [_killedUnit] call BLWK_fnc_spawnQueue_removeManEventhandlers; + [_killedUnit,true] call BLWK_fnc_spawnQueue_removeManEventhandlers; if !(isNull _killedUnit) then { private _cleanUpGroup = localNamespace getVariable ["BLWK_spawnQueue_cleanUpGroup",grpNull]; if (isNull _cleanUpGroup) then { diff --git a/Functions/Queue/fn_spawnQueue_removeManEventhandlers.sqf b/Functions/Queue/fn_spawnQueue_removeManEventhandlers.sqf index ec2bc889..08e58cc8 100644 --- a/Functions/Queue/fn_spawnQueue_removeManEventhandlers.sqf +++ b/Functions/Queue/fn_spawnQueue_removeManEventhandlers.sqf @@ -7,6 +7,8 @@ Description: Parameters: 0: _unit : - The unit to remove the eventhandlers from + 1: _calledFromKilledEventhandler : - Shouldn't remove the event that called + this function if it is executing. Returns: NOTHING @@ -22,15 +24,18 @@ Author(s): scriptName "BLWK_fnc_spawnQueue_removeManEventhandlers"; params [ - ["_unit",objNull,[objNull]] + ["_unit",objNull,[objNull]], + ["_calledFromKilledEventhandler",false,[true]] ]; - +// TODO: this is causing delete eventhandler to run when bomber is killed????? private _deletedEventId = _unit getVariable ["BLWK_spawnQueue_deletedEventId",-1]; _unit removeEventHandler ["DELETED",_deletedEventId]; -private _killedEventId = _unit getVariable ["BLWK_spawnQueue_killedEventId",-1]; -_unit removeEventHandler ["KILLED",_killedEventId]; +if !(_calledFromKilledEventhandler) then { + private _killedEventId = _unit getVariable ["BLWK_spawnQueue_killedEventId",-1]; + _unit removeEventHandler ["KILLED",_killedEventId]; +}; private _hitEventId = _unit getVariable ["BLWK_spawnQueue_hitEventId",-1]; _unit removeEventHandler ["HIT",_hitEventId]; diff --git a/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_bomberLoop.sqf b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_bomberLoop.sqf index 492d0824..e352adf7 100644 --- a/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_bomberLoop.sqf +++ b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_bomberLoop.sqf @@ -27,7 +27,9 @@ if (!canSuspend) exitWith { nil }; -params ["_bomber"]; +params [ + ["_bomber",objNull,[objNull]] +]; private ["_players","_nearPlayer"]; private _bomberDistanceToBlow = random [10,15,20]; diff --git a/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_explodeBomber.sqf b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_explodeBomber.sqf index c81a251a..f5c29823 100644 --- a/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_explodeBomber.sqf +++ b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_explodeBomber.sqf @@ -22,6 +22,8 @@ scriptName "BLWK_fnc_suicideWave_explodeBomber"; params ["_bomber"]; +hint str "kaboom"; + if (isNull _bomber) exitWith {}; private _explosiveType = selectRandom [ @@ -32,6 +34,7 @@ private _explosiveType = selectRandom [ private _explosive = _explosiveType createVehicle (getPosATLVisual _bomber); _explosive setDamage 1; +hint str "no really"; // give time for BLWK_fnc_event_killedEnemy to execute [ { diff --git a/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_makeBombers.sqf b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_makeBombers.sqf new file mode 100644 index 00000000..b8431929 --- /dev/null +++ b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_makeBombers.sqf @@ -0,0 +1,109 @@ +/* ---------------------------------------------------------------------------- +Function: BLWK_fnc_suicideWave_makeBombers + +Description: + Takes a list of units and turns them into suicide bombers. + +Parameters: + 0: _bombers : - The suicide bombers to outfit + +Returns: + NOTHING + +Examples: + (begin example) + [ + [unit1,unit2] + ] remoteExecCall ["BLWK_fnc_suicideWave_makeBombers",BLWK_theAIHandlerOwnerId]; + (end) + +Author(s): + Hilltop(Willtop) & omNomios, + Modified by: Ansible2 +---------------------------------------------------------------------------- */ +scriptName "BLWK_fnc_suicideWave_makeBombers"; + +#define VEST_CHARGE "DemoCharge_Remote_Ammo" + +if !(local BLWK_theAIHandlerEntity) exitWith { + [ + [ + "BLWK_fnc_spawnQueue_initGroups was called on machine where clientOwner is: ", + clientOwner, + " but BLWK_theAIHandlerEntity is not local" + ] + ] remoteExecCall ["KISKA_fnc_log",2]; + + nil +}; + + +params [ + ["_bombers",[],[[]]] +]; + +_bombers apply { + private _unit = _x; + private _unitGroup = createGroup [OPFOR,true]; + [_unit] joinSilent _unitGroup; + _unit setVariable ["BLWK_spawnQueue_group",_bomberGroup]; + + _unitGroup setBehaviour "CARELESS"; + + private _owner = groupOwner _unitGroup; + _unitGroup move (getPosATL BLWK_mainCrate); + _unitGroup setSpeedMode "full"; + + removeAllWeapons _unit; + removeHeadgear _unit; + removeVest _unit; + _unit addVest "V_HarnessOGL_brn"; + _unit addHeadgear "H_ShemagOpen_khk"; + + private _unitPosition = position _unit; + private _bombs = [ + [ + [-0.1, 0.1, 0.15], + [ [0.5, 0.5, 0], [-0.5, 0.5, 0] ] + ], + [ + [0.1, 0.1, 0.15], + [ [0.5, -0.5, 0], [0.5, 0.5, 0] ] + ], + [ + [0, 0.15, 0.15], + [ [1, 0, 0], [0, 1, 0] ] + ] + ] apply { + _x params ["_attachmentPoint","_vectorDirAndUp"]; + + private _explosive = VEST_CHARGE createVehicle _unitPosition; + _explosive attachTo [_unit, _attachmentPoint, "Pelvis"]; + _explosive setVectorDirAndUp _vectorDirAndUp; + + _explosive + }; + _unit setVariable ["BLWK_suicideBombs",_bombs]; + + + _unit addEventHandler ["KILLED",{ + hint "BOMBER - KILLED"; + params ["_bomber"]; + [_bomber] call BLWK_fnc_suicideWave_explodeBomber; + }]; + + _unit addEventHandler ["Deleted", { + hint "BOMBER - DELETED"; + params ["_unit"]; + + (_unit getVariable ["BLWK_suicideBombs",[]]) apply { + deleteVehicle _x; + }; + }]; + + + [_unit] spawn BLWK_fnc_suicideWave_bomberLoop; +}; + + +nil diff --git a/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_onWaveInit.sqf index 8e83e7b1..8586d3ee 100644 --- a/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_onWaveInit.sqf +++ b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_onWaveInit.sqf @@ -16,75 +16,15 @@ Examples: (end) Author(s): - Hilltop(Willtop) & omNomios, - Modified by: Ansible2 + Hilltop(Willtop) & omNomios, + Modified by: Ansible2 ---------------------------------------------------------------------------- */ scriptName "BLWK_fnc_suicideWave_onWaveInit"; -#define VEST_CHARGE "DemoCharge_Remote_Ammo" - private _startingWaveUnits = call BLWK_fnc_getMustKillList; private _numberOfBombers = round (count _startingWaveUnits / 4); private _bombers = _startingWaveUnits select [0,_numberOfBombers]; -_bombers apply { - private _unit = _unit; - private _unitGroup = group _unit; - - _unitGroup setBehaviour "CARELESS"; - - private _owner = groupOwner _unitGroup; - [_unitGroup,(getPosATL BLWK_mainCrate)] remoteExec ["move", _owner]; - [_unitGroup,"full"] remoteExec ["setSpeedMode", _owner]; - - removeAllWeapons _unit; - removeHeadgear _unit; - removeVest _unit; - _unit addVest "V_HarnessOGL_brn"; - _unit addHeadgear "H_ShemagOpen_khk"; - - private _unitPosition = position _unit; - private _bombs = [ - [ - [-0.1, 0.1, 0.15], - [ [0.5, 0.5, 0], [-0.5, 0.5, 0] ] - ], - [ - [0.1, 0.1, 0.15], - [ [0.5, -0.5, 0], [0.5, 0.5, 0] ] - ], - [ - [0, 0.15, 0.15], - [ [1, 0, 0], [0, 1, 0] ] - ] - ] apply { - _x params ["_attachmentPoint","_vectorDirAndUp"]; - - private _explosive = VEST_CHARGE createVehicle _unitPosition; - _explosive attachTo [_unit, _attachmentPoint, "Pelvis"]; - _explosive setVectorDirAndUp _vectorDirAndUp; - - _explosive - }; - _unit setVariable ["BLWK_suicideBombs",_bombs]; - - - _unit addEventHandler ["KILLED",{ - params ["_bomber"]; - [_bomber] call BLWK_fnc_suicideWave_explodeBomber; - }]; - - _unit addEventHandler ["Deleted", { - params ["_unit"]; - - (_unit getVariable ["BLWK_suicideBombs",[]]) apply { - deleteVehicle _unit; - }; - }]; - - - [_unit] spawn BLWK_fnc_suicideWave_bomberLoop; -}; - +[_bombers] remoteExecCall ["BLWK_fnc_suicideWave_makeBombers",BLWK_theAIHandlerOwnerID]; nil diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index b8d72861..dcad9516 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -483,6 +483,8 @@ class BLWK{ {}; class suicideWave_onWaveInit {}; + class suicideWave_makeBombers + {}; }; class ParatrooperWaveLib From 97d7461ade74c14241b0798d5b361dadbfb96975 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 22 Jul 2023 11:15:15 -0600 Subject: [PATCH 098/133] (#642): fixed deleted event running when sucide bombers were killed --- .../Queue/fn_spawnQueue_addManEventhandlers.sqf | 13 +++++++++++-- .../Queue/fn_spawnQueue_removeManEventhandlers.sqf | 1 - .../fn_suicideWave_explodeBomber.sqf | 3 --- .../Suicide Wave Lib/fn_suicideWave_makeBombers.sqf | 2 -- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf b/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf index 18941d2c..04de301a 100644 --- a/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf +++ b/Functions/Queue/fn_spawnQueue_addManEventhandlers.sqf @@ -47,7 +47,16 @@ private _killedEventId = _unit addEventHandler ["Killed", { [_killedUnit] remoteExecCall ["BLWK_fnc_event_killedEnemy",_instigator]; }; - [_killedUnit,true] call BLWK_fnc_spawnQueue_removeManEventhandlers; + // removing eventhandlers too quickly from within another eventhandler + // can sometimes cause undefined behaviour + [ + { + _this call BLWK_fnc_spawnQueue_removeManEventhandlers; + }, + [_killedUnit,true], + 0.5 + ] call CBAP_fnc_waitAndExecute; + if !(isNull _killedUnit) then { private _cleanUpGroup = localNamespace getVariable ["BLWK_spawnQueue_cleanUpGroup",grpNull]; if (isNull _cleanUpGroup) then { @@ -61,7 +70,7 @@ private _killedEventId = _unit addEventHandler ["Killed", { deleteGroup _previousGroup; }; }; - + [] remoteExecCall ["BLWK_fnc_spawnQueue_unitKilled",2]; }]; _unit setVariable ["BLWK_spawnQueue_killedEventId",_killedEventId]; diff --git a/Functions/Queue/fn_spawnQueue_removeManEventhandlers.sqf b/Functions/Queue/fn_spawnQueue_removeManEventhandlers.sqf index 08e58cc8..743eb282 100644 --- a/Functions/Queue/fn_spawnQueue_removeManEventhandlers.sqf +++ b/Functions/Queue/fn_spawnQueue_removeManEventhandlers.sqf @@ -28,7 +28,6 @@ params [ ["_calledFromKilledEventhandler",false,[true]] ]; -// TODO: this is causing delete eventhandler to run when bomber is killed????? private _deletedEventId = _unit getVariable ["BLWK_spawnQueue_deletedEventId",-1]; _unit removeEventHandler ["DELETED",_deletedEventId]; diff --git a/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_explodeBomber.sqf b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_explodeBomber.sqf index f5c29823..c81a251a 100644 --- a/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_explodeBomber.sqf +++ b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_explodeBomber.sqf @@ -22,8 +22,6 @@ scriptName "BLWK_fnc_suicideWave_explodeBomber"; params ["_bomber"]; -hint str "kaboom"; - if (isNull _bomber) exitWith {}; private _explosiveType = selectRandom [ @@ -34,7 +32,6 @@ private _explosiveType = selectRandom [ private _explosive = _explosiveType createVehicle (getPosATLVisual _bomber); _explosive setDamage 1; -hint str "no really"; // give time for BLWK_fnc_event_killedEnemy to execute [ { diff --git a/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_makeBombers.sqf b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_makeBombers.sqf index b8431929..a19bb080 100644 --- a/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_makeBombers.sqf +++ b/Functions/Wave Type Libraries/Suicide Wave Lib/fn_suicideWave_makeBombers.sqf @@ -87,13 +87,11 @@ _bombers apply { _unit addEventHandler ["KILLED",{ - hint "BOMBER - KILLED"; params ["_bomber"]; [_bomber] call BLWK_fnc_suicideWave_explodeBomber; }]; _unit addEventHandler ["Deleted", { - hint "BOMBER - DELETED"; params ["_unit"]; (_unit getVariable ["BLWK_suicideBombs",[]]) apply { From 2342d690f83b5a323345ccf7cfa5d692f59df95e Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 22 Jul 2023 11:15:39 -0600 Subject: [PATCH 099/133] (#642): fixed stalker and drone eventhandler removals --- .../fn_stalking_removeStalkedPlayer.sqf | 10 +- Functions/Stalking/fn_stalking_start.sqf | 2 - Functions/Stalking/fn_stalking_stop.sqf | 35 +++-- .../fn_droneWave_onWaveInit.sqf | 132 +++++++++++------- 4 files changed, 110 insertions(+), 69 deletions(-) diff --git a/Functions/Stalking/fn_stalking_removeStalkedPlayer.sqf b/Functions/Stalking/fn_stalking_removeStalkedPlayer.sqf index 3873f1b4..94f42105 100644 --- a/Functions/Stalking/fn_stalking_removeStalkedPlayer.sqf +++ b/Functions/Stalking/fn_stalking_removeStalkedPlayer.sqf @@ -24,16 +24,16 @@ params [ ["_stalkerGroup",grpNull,[grpNull]] ]; -if ((isNull _stalkerGroup) OR (isNull _playerToStalk)) exitWith { - [["Null argument passed, params are: ",_this]] call KISKA_fnc_log; +private _playerBeingStalked = _stalkerGroup getVariable ["BLWK_stalking_stalkedPlayer",objNull]; +if ((isNull _stalkerGroup) AND (isNull _playerBeingStalked)) exitWith { + ["Both _stalkerGroup AND _playerBeingStalked are null, exiting..."] call KISKA_fnc_log; nil }; -private _playerBeingStalked = _stalkerGroup getVariable ["BLWK_stalking_stalkedPlayer",objNull]; if !(isNull _playerBeingStalked) then { - private _numberOfStalkerGroups = _playerToStalk getVariable ["BLWK_stalking_numberOfStalkerGroups",0]; - _playerToStalk setVariable [ + private _numberOfStalkerGroups = _playerBeingStalked getVariable ["BLWK_stalking_numberOfStalkerGroups",0]; + _playerBeingStalked setVariable [ "BLWK_stalking_numberOfStalkerGroups", (_numberOfStalkerGroups - 1) max 0 ]; diff --git a/Functions/Stalking/fn_stalking_start.sqf b/Functions/Stalking/fn_stalking_start.sqf index 2eba37c8..3aff4311 100644 --- a/Functions/Stalking/fn_stalking_start.sqf +++ b/Functions/Stalking/fn_stalking_start.sqf @@ -59,14 +59,12 @@ _stalkerGroup setVariable ["BLWK_stalking_leaderChangedEventId",_leaderChangedEv private _deletedEventId = _stalkerGroup addEventHandler ["Deleted", { - params ["_group"]; _this call BLWK_fnc_stalking_stop; }]; _stalkerGroup setVariable ["BLWK_stalking_deletedEventId",_deletedEventId]; private _emptyEventId = _stalkerGroup addEventHandler ["Empty", { - params ["_group"]; _this call BLWK_fnc_stalking_stop; }]; _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; diff --git a/Functions/Stalking/fn_stalking_stop.sqf b/Functions/Stalking/fn_stalking_stop.sqf index 59a5f19c..bedfb0da 100644 --- a/Functions/Stalking/fn_stalking_stop.sqf +++ b/Functions/Stalking/fn_stalking_stop.sqf @@ -56,19 +56,30 @@ if (_hasStalkerWaypoint) then { /* ---------------------------------------------------------------------------- Group events ---------------------------------------------------------------------------- */ +// removing eventhandlers too quickly from within another eventhandler +// can sometimes cause undefined behaviour [ - ["BLWK_stalking_leaderChangedEventId","LeaderChanged"], - ["BLWK_stalking_deletedEventId","Deleted"], - ["BLWK_stalking_emptyEventId","Empty"] -] apply { - _x params ["_eventSaveId","_eventName"]; - - private _eventId = _stalkerGroup getVariable [ - _eventSaveId, - -1 - ]; - _stalkerGroup removeEventHandler [_eventName,_eventId]; -}; + { + params ["_stalkerGroup"]; + + [ + ["BLWK_stalking_leaderChangedEventId","LeaderChanged"], + ["BLWK_stalking_deletedEventId","Deleted"], + ["BLWK_stalking_emptyEventId","Empty"] + ] apply { + _x params ["_eventSaveId","_eventName"]; + + private _eventId = _stalkerGroup getVariable [ + _eventSaveId, + -1 + ]; + _stalkerGroup removeEventHandler [_eventName,_eventId]; + }; + }, + [_stalkerGroup], + 0.5 +] call CBAP_fnc_waitAndExecute; + nil diff --git a/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf index cda5d95d..1602b2df 100644 --- a/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf +++ b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf @@ -29,7 +29,85 @@ scriptName "BLWK_fnc_droneWave_onWaveInit"; localNamespace setVariable ["BLWK_droneWave_allDronesCreated",false]; -[] spawn { +private _fn_addEventHandlers = { + params [ + ["_drone",objNull,[objNull]] + ]; + + + /* -------------------------------------- + HIT + -------------------------------------- */ + private _hitEventId = _drone addEventHandler ["HIT", { + params ["_drone", "", "", "_instigator"]; + + if (isPlayer _instigator) then { + private _points = [_drone] call BLWK_fnc_getPointsForKill; + [_drone,_points] remoteExec ["BLWK_fnc_droneWave_onDroneKilled",_instigator]; + }; + + private _explosion = "DemoCharge_Remote_Ammo_Scripted" createVehicle (getPosATLVisual _drone); + _explosion setdamage 1; + _drone setDamage 1; + }]; + _drone setVariable ["BLWK_droneWave_droneHitEventId",_hitEventId]; + + + /* -------------------------------------- + Deleted + -------------------------------------- */ + private _deletedEventId = _drone addEventHandler ["DELETED", { + // deleted ai is not actually dead when deleted event runs + // need to wait before checking for wave clear + [ + { + if (call BLWK_fnc_waves_isCleared) then { + call BLWK_fnc_waves_end + }; + }, + [], + 0.5 + ] call CBAP_fnc_waitAndExecute; + }]; + _drone setVariable ["BLWK_droneWave_droneDeletedEventId",_deletedEventId]; + + + /* -------------------------------------- + Killed + -------------------------------------- */ + private _killedEventId = _drone addEventHandler [ + "KILLED", + { + // removing eventhandlers too quickly from within another eventhandler + // can sometimes cause undefined behaviour + [ + { + params ["_drone"]; + [ + ["BLWK_droneWave_droneHitEventId","HIT"], + ["BLWK_droneWave_droneDeletedEventId","DELETED"] + ] apply { + _x params ["_eventIdVarName","_eventType"]; + private _eventId = _drone getVariable [_eventIdVarName,-1]; + _drone removeEventHandler [_eventType,_eventId]; + }; + }, + _this, + 0.5 + ] call CBAP_fnc_waitAndExecute; + + if (call BLWK_fnc_waves_isCleared) then { + call BLWK_fnc_waves_end + }; + } + ]; + _drone setVariable ["BLWK_droneWave_droneKilledEventId",_killedEventId]; +}; + + +[_fn_addEventHandlers] spawn { + params ["_fn_addEventHandlers"]; + for "_i" from 1 to DRONE_NUMBER do { // Spawn position private _droneGroup = createGroup OPFOR; @@ -57,57 +135,11 @@ localNamespace setVariable ["BLWK_droneWave_allDronesCreated",false]; [_drone,_droneGroup,_spawnPosition] spawn BLWK_fnc_droneWave_attackLoop; - - private _hitEventId = _drone addEventHandler ["HIT", { - params ["_drone", "", "", "_instigator"]; - - if (isPlayer _instigator) then { - private _points = [_drone] call BLWK_fnc_getPointsForKill; - [_drone,_points] remoteExec ["BLWK_fnc_droneWave_onDroneKilled",_instigator]; - }; - - private _explosion = "DemoCharge_Remote_Ammo_Scripted" createVehicle (getPosATLVisual _drone); - _explosion setdamage 1; - _drone setDamage 1; - }]; - _drone setVariable ["BLWK_droneWave_droneHitEventId",_hitEventId]; - - private _deletedEventId = _drone addEventHandler ["DELETED", { - // deleted ai is not actually dead when deleted event runs - // need to wait before checking for wave clear - [ - { - if (call BLWK_fnc_waves_isCleared) then { - call BLWK_fnc_waves_end - }; - }, - [], - 0.5 - ] call CBAP_fnc_waitAndExecute; - }]; - _drone setVariable ["BLWK_droneWave_droneDeletedEventId",_deletedEventId]; - - private _killedEventId = _drone addEventHandler ["KILLED", { - params ["_drone"]; - [ - ["BLWK_droneWave_droneHitEventId","HIT"], - ["BLWK_droneWave_droneKilledEventId","KILLED"], - ["BLWK_droneWave_droneDeletedEventId","DELETED"] - ] apply { - _x params ["_eventIdVarName","_eventType"]; - private _eventId = _drone getVariable [_eventIdVarName,-1]; - _drone removeEventHandler [_eventType,_eventId]; - }; - - if (call BLWK_fnc_waves_isCleared) then { - call BLWK_fnc_waves_end - }; - }]; - _drone setVariable ["BLWK_droneWave_droneKilledEventId",_killedEventId]; - - + private _droneArray = [_drone]; + _droneArray call _fn_addEventHandlers; _droneArray call BLWK_fnc_addToMustKillList; + BLWK_zeus addCuratorEditableObjects [_droneArray, true]; // space out spawns so that you don't get spammed From a9c0e81900be13e456f98af457849bc18328d176 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 22 Jul 2023 11:58:14 -0600 Subject: [PATCH 100/133] (#642): updated KISKA_fnc_getPosRelativeSurface to latest --- Functions/Supports/fn_arsenalSupplyDrop.sqf | 4 ++-- Functions/Supports/fn_daisyCutter.sqf | 4 ++-- .../Drone Wave Lib/fn_droneWave_onWaveInit.sqf | 4 ++-- KISKA Systems/KISKA Utility Functions/fn_CAS.sqf | 4 ++-- .../fn_getPosRelativeSurface.sqf | 15 +++++++++++++-- .../KISKA Utility Functions/fn_paratroopers.sqf | 4 ++-- 6 files changed, 23 insertions(+), 12 deletions(-) diff --git a/Functions/Supports/fn_arsenalSupplyDrop.sqf b/Functions/Supports/fn_arsenalSupplyDrop.sqf index 623cf77c..6ed4cc32 100644 --- a/Functions/Supports/fn_arsenalSupplyDrop.sqf +++ b/Functions/Supports/fn_arsenalSupplyDrop.sqf @@ -37,9 +37,9 @@ private _flyFromDirection = [_flyDirection + 180] call CBAP_fnc_simplifyAngle; private _spawnPosition = [ _dropPosition, FLY_RADIUS, - _flyFromDirection + _flyFromDirection, + DROP_ALT ] call KISKA_fnc_getPosRelativeSurface; -_spawnPosition vectorAdd [0,0,DROP_ALT]; private _relativeDirection = _spawnPosition getDir _dropPosition; diff --git a/Functions/Supports/fn_daisyCutter.sqf b/Functions/Supports/fn_daisyCutter.sqf index 57ed067f..eff7dbaa 100644 --- a/Functions/Supports/fn_daisyCutter.sqf +++ b/Functions/Supports/fn_daisyCutter.sqf @@ -48,9 +48,9 @@ private _flyFromDirection = [_flyDirection + 180] call CBAP_fnc_simplifyAngle; private _spawnPosition = [ _dropPosition, FLY_RADIUS, - _flyFromDirection + _flyFromDirection, + DROP_ALT ] call KISKA_fnc_getPosRelativeSurface; -_spawnPosition vectorAdd [0,0,DROP_ALT]; private _relativeDirection = _spawnPosition getDir _dropPosition; diff --git a/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf index 1602b2df..9ebb613a 100644 --- a/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf +++ b/Functions/Wave Type Libraries/Drone Wave Lib/fn_droneWave_onWaveInit.sqf @@ -116,9 +116,9 @@ private _fn_addEventHandlers = { private _spawnPosition = [ BLWK_mainCrate, BLWK_playAreaRadius + (random [100,125,150]), - _flyFromDirection + _flyFromDirection, + FLY_HEIGHT ] call KISKA_fnc_getPosRelativeSurface; - _spawnPosition vectorAdd [0,0,FLY_HEIGHT]; // Create private _droneSpawnInfo = [ diff --git a/KISKA Systems/KISKA Utility Functions/fn_CAS.sqf b/KISKA Systems/KISKA Utility Functions/fn_CAS.sqf index e8f9c82a..97178566 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_CAS.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_CAS.sqf @@ -213,9 +213,9 @@ if (_exitToDefault) exitwith { private _planeSpawnPosition = [ _attackPosition, _spawnDistance, - (_attackDirection + 180) + (_attackDirection + 180), + _spawnHeight ] call KISKA_fnc_getPosRelativeSurface; -_planeSpawnPosition vectorAdd [0,0,_spawnHeight]; private _planeArray = [_planeSpawnPosition,_attackDirection,_planeClass,_side,false] call KISKA_fnc_spawnVehicle; private _plane = _planeArray select 0; diff --git a/KISKA Systems/KISKA Utility Functions/fn_getPosRelativeSurface.sqf b/KISKA Systems/KISKA Utility Functions/fn_getPosRelativeSurface.sqf index 5fb6dc4e..b0b6a882 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_getPosRelativeSurface.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_getPosRelativeSurface.sqf @@ -13,6 +13,7 @@ Parameters: relative position to. If a 2d position, height will be 0. 1: _distance - The distance away from the _centerPosition to get the position 2: _bearing - The direction relative to the position to find the new position + 3: _zOffSet - An offset to add to the Z-axis AFTER the surface position is found Returns: PositionATL[] - the new position @@ -26,6 +27,15 @@ Examples: ] call KISKA_fnc_getPosRelativeSurface; (end) + (begin example) + [ + player, + 100, + 180, + 10 // 10 meters above water surface or terrain + ] call KISKA_fnc_getPosRelativeSurface; + (end) + Author(s): Ansible2 ---------------------------------------------------------------------------- */ @@ -34,7 +44,8 @@ scriptName "KISKA_fnc_getPosRelativeSurface"; params [ ["_centerPosition",[],[objNull,[]],[2,3]], ["_distance",0,[123]], - ["_bearing",0,[123]] + ["_bearing",0,[123]], + ["_zOffSet",0,[123]] ]; @@ -47,4 +58,4 @@ if (_isUnderwater) then { }; -_relativePosition +_relativePosition vectorAdd [0,0,_zOffSet] diff --git a/KISKA Systems/KISKA Utility Functions/fn_paratroopers.sqf b/KISKA Systems/KISKA Utility Functions/fn_paratroopers.sqf index a9e88500..bec80960 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_paratroopers.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_paratroopers.sqf @@ -107,9 +107,9 @@ _dropZone set [2,_flyInHeight]; private _spawnPosition = [ _dropZone, _spawnDistance, - _flyFromDirection + _flyFromDirection, + _flyInHeight ] call KISKA_fnc_getPosRelativeSurface; -_spawnPosition vectorAdd [0,0,_flyInHeight]; /* ---------------------------------------------------------------------------- Create vehicle to drop units From ea3c613df557aef91101ba9f0e8eb3d7f10ea224 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 22 Jul 2023 12:06:15 -0600 Subject: [PATCH 101/133] (#642): added turret engagment loop to extraction helicopters --- Functions/Extraction/fn_extraction.sqf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Functions/Extraction/fn_extraction.sqf b/Functions/Extraction/fn_extraction.sqf index 5763137b..7bb8e6f7 100644 --- a/Functions/Extraction/fn_extraction.sqf +++ b/Functions/Extraction/fn_extraction.sqf @@ -312,6 +312,7 @@ private _fn_afterExtractionWaitTime = { // handle crew AI private _aircraft = _aircraftInfo select 0; + [BLWK_zeus, [[_aircraft],true]] remoteExecCall ["addCuratorEditableObjects",2]; BLWK_extractionAircraft pushBack _aircraft; _aircraft allowDamage false; _aircraft setCaptive true; @@ -357,9 +358,6 @@ private _fn_afterExtractionWaitTime = { }; private _aircraftGroup = _aircraftInfo select 2; - _aircraftGroup setBehaviour "CARELESS"; - _aircraftGroup setCombatBehaviour "CARELESS"; - _aircraftGroup setCombatMode "BLUE"; private _exfilPosition = [ [1,1,1], @@ -368,6 +366,8 @@ private _fn_afterExtractionWaitTime = { ] call CBAP_fnc_randPos; _aircraft setVariable ["BLWK_exfilPosition",_exfilPosition]; + [_aircraft,5,4,500] spawn KISKA_fnc_engageHeliTurretsLoop; + [ _aircraft, _x, From 9a4cb4a048b7968c47b568f326ce8084227b4fb9 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 29 Jul 2023 14:39:33 -0600 Subject: [PATCH 102/133] (#642): updated stalking script --- Functions/Stalking/fn_stalking_start.sqf | 167 ++++++++++------------- 1 file changed, 71 insertions(+), 96 deletions(-) diff --git a/Functions/Stalking/fn_stalking_start.sqf b/Functions/Stalking/fn_stalking_start.sqf index 3aff4311..2159fac2 100644 --- a/Functions/Stalking/fn_stalking_start.sqf +++ b/Functions/Stalking/fn_stalking_start.sqf @@ -21,7 +21,10 @@ Author(s): scriptName "BLWK_fnc_stalking_start"; #define DEFAULT_POSITION (getPosATL BLWK_mainCrate) -#define UPDATE_RATE 20 +// using random spread to help get a more evenly distributed work load +// for every group that is stalking, rather then them all needing to execute at about +// the same time +#define UPDATE_RATE (random [15,20,25]) #define SWITCH_TO_MOVE_DISTANCE 50 @@ -91,7 +94,6 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; /* ---------------------------------------------------------------------------- Main loop ---------------------------------------------------------------------------- */ -[_stalkerGroup] call KISKA_fnc_clearWaypoints; [_stalkerGroup] spawn { params ["_stalkerGroup"]; @@ -112,34 +114,43 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; // _group setVariable ["BLWK_stalkerIteration",_id + 1]; // }; - - while { !(isNull _stalkerGroup) AND (_stalkerGroup getVariable ["BLWK_stalking_doStalk",false]) } do { + + _stalkerGroup setBehaviourStrong "AWARE"; + _stalkerGroup setCombatMode "RED"; + + while { + !(isNull _stalkerGroup) AND + (_stalkerGroup getVariable ["BLWK_stalking_doStalk",false]) + } do { if !([_stalkerGroup] call KISKA_fnc_isGroupAlive) then { [_stalkerGroup] call BLWK_fnc_stalking_stop; break; }; - if ( - (leader _stalkerGroup) getVariable [ - "BLWK_isACEUnconscious", - false - ] - ) then { + + private _leaderIsIncapacitated = (leader _stalkerGroup) getVariable [ + "BLWK_isACEUnconscious", + false + ]; + if (_leaderIsIncapacitated) then { sleep 3; continue }; - private _currentPlayerBeingStalked = _stalkerGroup getVariable ["BLWK_stalking_stalkedPlayer",objNull]; + /* -------------------------------------- verify player to stalk -------------------------------------- */ + private _currentPlayerBeingStalked = _stalkerGroup getVariable ["BLWK_stalking_stalkedPlayer",objNull]; private _currentPlayerCanBeStalked = [_currentPlayerBeingStalked] call BLWK_fnc_stalking_canPlayerBeStalked; private _shouldRedistribute = _stalkerGroup getVariable ["BLWK_stalking_redistribute",false]; + if ((!_currentPlayerCanBeStalked) OR _shouldRedistribute) then { - private _playerToStalk = call BLWK_fnc_stalking_getPlayer; - if (isNull _playerToStalk) then { - + + private _newPlayerToStalk = call BLWK_fnc_stalking_getPlayer; + if (isNull _newPlayerToStalk) then { + private _groupIsPatrolling = _stalkerGroup getVariable ["BLWK_stalking_isPatrolling",false]; // [_stalkerGroup,["NULL player to stalk: ",_groupIsPatrolling] joinString ""] call _fn_add3dLog; if !(_groupIsPatrolling) then { @@ -152,111 +163,75 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; sleep UPDATE_RATE; continue; - } else { - [_stalkerGroup,_playerToStalk] call BLWK_fnc_stalking_setStalkedPlayer; - _currentPlayerBeingStalked = _playerToStalk; + [_stalkerGroup,_newPlayerToStalk] call BLWK_fnc_stalking_setStalkedPlayer; + _currentPlayerBeingStalked = _newPlayerToStalk; // [_stalkerGroup,"set new stalked player"] call _fn_add3dLog; }; + }; /* -------------------------------------- - Reset group if needed from `move` command + Determine move type -------------------------------------- */ + private _stalkerGroupIsUnderMoveOrders = _stalkerGroup getVariable ["BLWK_stalking_isUnderMove",false]; private _stalkerGroupShouldUseMove = ( (leader _stalkerGroup) distance2D _currentPlayerBeingStalked ) < SWITCH_TO_MOVE_DISTANCE; - private _stalkerGroupIsUnderMoveOrders = _stalkerGroup getVariable ["BLWK_stalking_isUnderMove",false]; - if (_stalkerGroupIsUnderMoveOrders AND (!_stalkerGroupShouldUseMove)) then { - private _stalkerGroupUnits = units _stalkerGroup; - doStop _stalkerGroupUnits; - sleep 1; - // regroup units - _stalkerGroupUnits doFollow (leader _stalkerGroup); - // [_stalkerGroup,"told to stop and then follow"] call _fn_add3dLog; - }; + if (_stalkerGroupShouldUseMove) then { - /* -------------------------------------- - clear previous waypoints, - Waypoints are not immediately deleted so need to wait - -------------------------------------- */ - private "_waypointCount"; - // tODO: maybe a problem??? - waitUntil { - _waypointCount = count (waypoints _stalkerGroup); - [ - _stalkerGroup, - (_waypointCount - 1) - ] call KISKA_fnc_clearWaypoints; - - private _stalkerGroupWaypointsDeleted = _waypointCount < 2; - if (_stalkerGroupWaypointsDeleted) exitWith {true}; - - sleep 1; - - // prevent infinte loop - (units _stalkerGroup) isEqualTo [] - }; - // [_stalkerGroup,"cleared waypoints"] call _fn_add3dLog; + if (!_stalkerGroupIsUnderMoveOrders) then { + _stalkerGroup setVariable ["BLWK_stalking_isUnderMove",true]; + [_stalkerGroup,-1,false] call KISKA_fnc_clearWaypoints; + }; + if ((formation _stalkerGroup) != "COLUMN") then { + _stalkerGroup setFormation "COLUMN"; + }; - /* -------------------------------------- - Choose between waypoint or `move` command - -------------------------------------- */ - private _hasWaypoint = _waypointCount isEqualTo 1; - if (_stalkerGroupShouldUseMove) then { - _stalkerGroup setVariable ["BLWK_stalking_isUnderMove",true]; - - private _playerPosition = getPosATL _currentPlayerBeingStalked; + private _playerPosition = getPosATL _currentPlayerBeingStalked; _stalkerGroup setVariable ["BLWK_stalking_currentMovePosition",_playerPosition]; - - // `move` does not work well against group, using it at a unit level - (units _stalkerGroup) apply { - _x move _playerPosition; - }; - _stalkerGroup setFormation "COLUMN"; - // [_stalkerGroup,["told to move ",_playerPosition] joinString ""] call _fn_add3dLog; - if (_hasWaypoint) then { - deleteWaypoint [_stalkerGroup,0]; - // [_stalkerGroup,"deleted waypoint"] call _fn_add3dLog; - }; + // // `move` does not work well against group, using it at a unit level + // (units _stalkerGroup) apply { + // _x move _playerPosition; + // }; + _stalkerGroup move _playerPosition; + [_stalkerGroup,["told to move ",_playerPosition] joinString ""] call _fn_add3dLog; + } else { - _stalkerGroup setVariable ["BLWK_stalking_isUnderMove",false]; - _stalkerGroup setVariable ["BLWK_stalking_currentMovePosition",nil]; - - private _hasStalkerWaypoint = waypointName [ - _stalkerGroup, - (currentWaypoint _stalkerGroup) - ] == "BLWK_stalking_waypoint"; - - private _hasWaypointThatIsNotStalkerWaypoint = _hasWaypoint AND (!_hasStalkerWaypoint); - if (_hasWaypointThatIsNotStalkerWaypoint) then { - [_stalkerGroup] call KISKA_fnc_clearWaypoints; - // [_stalkerGroup,"cleared WPs because excess"] call _fn_add3dLog; - }; - if (_hasStalkerWaypoint) then { - private _waypoint = [_stalkerGroup,0]; - _waypoint setWaypointBehaviour "AWARE"; - _waypoint setWaypointPosition [getPos _currentPlayerBeingStalked,5]; - // [_stalkerGroup,"updated stalker WP"] call _fn_add3dLog; + if (_stalkerGroupIsUnderMoveOrders) then { + // regroup units + private _stalkerGroupUnits = units _stalkerGroup; + doStop _stalkerGroupUnits; + // [_stalkerGroup,"doStop group units - during WP add"] call _fn_add3dLog; + + sleep 1; + + _stalkerGroupUnits doFollow (leader _stalkerGroup); + // [_stalkerGroup,"doFollow group units - during WP add"] call _fn_add3dLog; } else { - private _waypoint = [ - _stalkerGroup, - _currentPlayerBeingStalked, - 0, - "MOVE", - "AWARE", - "FULL" - ] call CBAP_fnc_addWaypoint; - _waypoint setWaypointName "BLWK_stalking_waypoint"; - // [_stalkerGroup,"Added new WP"] call _fn_add3dLog; + [_stalkerGroup,-1,true] call KISKA_fnc_clearWaypoints; + // [_stalkerGroup,"cleared waypoints - during WP add"] call _fn_add3dLog; + }; + + private _waypoint = [ + _stalkerGroup, + player, + 0, + "SAD", + "AWARE", + "RED", + "FULL" + ] call CBAP_fnc_addWaypoint; + // [_stalkerGroup,"added WP"] call _fn_add3dLog; + }; _stalkerGroup setFormation "STAG COLUMN"; From b533e471ba4cafc8aaaed418316c671707b087e4 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 29 Jul 2023 14:55:20 -0600 Subject: [PATCH 103/133] (#642): removed todo --- Functions/Stalking/fn_stalking_start.sqf | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Functions/Stalking/fn_stalking_start.sqf b/Functions/Stalking/fn_stalking_start.sqf index 2159fac2..f901ef44 100644 --- a/Functions/Stalking/fn_stalking_start.sqf +++ b/Functions/Stalking/fn_stalking_start.sqf @@ -243,8 +243,3 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; nil - -// TODO: units do not patrol when there is nobody to stalk, -// they just sit still after spawn or move to the main crate - -// user 3d log and aircraft gunner support to see what orders they are given \ No newline at end of file From 1748e6a704f9edcdcdad4f4333f77909c7fb7a6c Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 29 Jul 2023 15:31:53 -0600 Subject: [PATCH 104/133] (#642): removed outdated pathing functions and updted collision function --- .../fn_pathing_checkLeaderVelocity.sqf | 43 ----- .../AI Pathing/fn_pathing_collisionLoop.sqf | 176 ++++++++---------- .../fn_pathing_detailedStuckCheck.sqf | 78 -------- .../AI Pathing/fn_pathing_isGroupAlive.sqf | 48 ----- Functions/AI Pathing/fn_pathing_mainLoop.sqf | 107 ----------- .../Other/fn_handleUnconsciousAiEvent.sqf | 16 +- .../fn_standardWave_onGroupCreated.sqf | 1 - Headers/descriptionEXT/functions.hpp | 8 - 8 files changed, 81 insertions(+), 396 deletions(-) delete mode 100644 Functions/AI Pathing/fn_pathing_checkLeaderVelocity.sqf delete mode 100644 Functions/AI Pathing/fn_pathing_detailedStuckCheck.sqf delete mode 100644 Functions/AI Pathing/fn_pathing_isGroupAlive.sqf delete mode 100644 Functions/AI Pathing/fn_pathing_mainLoop.sqf diff --git a/Functions/AI Pathing/fn_pathing_checkLeaderVelocity.sqf b/Functions/AI Pathing/fn_pathing_checkLeaderVelocity.sqf deleted file mode 100644 index 65b5a7b0..00000000 --- a/Functions/AI Pathing/fn_pathing_checkLeaderVelocity.sqf +++ /dev/null @@ -1,43 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_pathing_checkLeaderVelocity - -Description: - Checks the velocity of a unit to see if they are currently moving. - -Parameters: - 0: _unit : - The group to check over - -Returns: - - true if any velocity is detected, otherwise false - -Examples: - (begin example) - _isActive = [_unit] call BLWK_fnc_pathing_checkLeaderVelocity; - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -scriptName "BLWK_fnc_pathing_checkLeaderVelocity"; - -params ["_unit"]; - -if (!alive _unit) exitWith { - false -}; - -// units seem to only get stuck in the standing position, otherwise, assume they are shooting and/or under fire -if (stance _unit != "STAND") exitWith { - true -}; - -// forward/backward velocity is the most telling of movement -private _leaderVelocity = (velocityModelSpace _unit) select 0; - -// if leader is stationary -if (_leaderVelocity isEqualTo 0) exitWith { - false -}; - - -true diff --git a/Functions/AI Pathing/fn_pathing_collisionLoop.sqf b/Functions/AI Pathing/fn_pathing_collisionLoop.sqf index a984f73b..1aa5f24a 100644 --- a/Functions/AI Pathing/fn_pathing_collisionLoop.sqf +++ b/Functions/AI Pathing/fn_pathing_collisionLoop.sqf @@ -2,130 +2,106 @@ Function: BLWK_fnc_pathing_collisionLoop Description: - Used to keep the AI from attempting to walk through a placed object. + Used to keep the AI from attempting to walk through a placed object. - Units on roads sometimes follow predetermined paths that can have them walk - through objects a user places down. + Units on roads sometimes follow predetermined paths that can have them walk + through objects a user places down. Parameters: - 0: _unit : - The unit to run the loop on + 0: _unit : - The unit to run the loop on Returns: - NOTHING + NOTHING Examples: (begin example) - - [myUnit] spawn BLWK_fnc_pathing_collisionLoop; - + [myUnit] spawn BLWK_fnc_pathing_collisionLoop; (end) Author(s): - Ansible2 // Cipher + Ansible2 ---------------------------------------------------------------------------- */ scriptName "BLWK_fnc_pathing_collisionLoop"; if (!BLWK_doDetectCollision) exitWith { - ["BLWK_doDetectCollision is set to be false, exiting...",false] call KISKA_fnc_log; + ["BLWK_doDetectCollision is set to be false, exiting...",false] call KISKA_fnc_log; }; if (!canSuspend) exitWith { - ["Needs to be run in scheduled, exting to run in scheduled",true] call KISKA_fnc_log; - _this spawn BLWK_fnc_pathing_collisionLoop; + ["Needs to be run in scheduled, exting to run in scheduled",true] call KISKA_fnc_log; + _this spawn BLWK_fnc_pathing_collisionLoop; }; -params ["_unit"]; + +params [ + ["_unit",objNull,[objNull]] +]; + sleep 5; if (isNull _unit) exitWith {}; -private _unitGroup = group _unit; - -private ["_objects","_position","_index","_moveToPosition"]; -while {BLWK_doDetectCollision AND {alive _unit}} do { - sleep 0.1; - - // don't run while a unit is in a vehicle - if (isNull (objectParent _unit)) then { - _position = getposASL _unit; - _objects = lineIntersectsObjs [_position,AGLToASL (_unit getRelPos [1,0]), objNull, _unit, false, 4]; - - if (_objects isNotEqualTo []) then { - - // check if any encountered object is a built one - _index = _objects findIf { - !(isNull _x) AND - {_x getVariable ["BLWK_collisionObject",false]} - }; - - if (_index != -1) then { - private _collisionObject = _objects select _index; - _moveToPosition = (_unit getRelPos [20,180]); - // push the unit back from the object - _unit setPosATL (_unit getRelPos [2,180]); - - _unitGroup setCombatMode "BLUE"; - _unitGroup setBehaviour "SAFE"; - _unitGroup setSpeedMode "FULL"; - _unit disableAI "TARGET"; - _unit disableAI "AUTOTARGET"; - - waitUntil { - if (isNull _unit OR {!alive _unit}) exitWith {true}; - if (_unit distance2D _collisionObject >= 10) exitWith {true}; - // tell the unit to move away - [_unit,_moveToPosition] remoteExec ["move", _unit]; - sleep 0.1; - false - }; - - // return unit state - if (!isNull _unit AND {alive _unit}) then { - _unitGroup setCombatMode "YELLOW"; - _unitGroup setBehaviour "AWARE"; - _unit enableAI "TARGET"; - _unit enableAI "AUTOTARGET"; - //_unit enableAI "AUTOCOMBAT"; - }; - }; - }; - }; -}; -// FSM testing -/* -private ["_objects","_position","_index","_moveToPosition"]; -while {BLWK_doDetectCollision AND {alive _unit}} do { - sleep 0.1; - - // don't run while a unit is in a vehicle - if (isNull (objectParent _unit)) then { - _position = getposASL _unit; - _objects = lineIntersectsObjs [_position,AGLToASL (_unit getRelPos [1,0]), objNull, _unit, false, 4]; - - if !(_objects isEqualTo []) then { - - // check if any encountered object is a built one - _index = _objects findIf {!(isNull _x) AND {_x getVariable ["BLWK_collisionObject",false]}}; - if (_index != -1) then { - private _collisionObject = _objects select _index; - _moveToPosition = (_unit getRelPos [20,180]); - // push the unit back from the object - _unit setPosATL (_unit getRelPos [2,180]); - - private _fsmHandle = [_unit,_moveToPosition,_collisionObject] execFSM "Functions\Other\testFSM.fsm"; - - waitUntil { - if (isNull _unit OR {completedFSM _fsmHandle}) exitWith { - diag_log "exited wait loop"; - true - }; - sleep 1; - false - }; - }; - }; - }; +while {BLWK_doDetectCollision AND (alive _unit)} do { + sleep 1; + + // don't run while a unit is in a vehicle + private _unitIsInVehicle = !(isNull (objectParent _unit)); + if (_unitIsInVehicle) then { continue }; + + + private _objects = lineIntersectsObjs [ + (getposASL _unit), + AGLToASL (_unit getRelPos [1,0]), + objNull, + _unit, + false, + 4 + ]; + private _notNearAnyObjects = _objects isEqualTo []; + if (_notNearAnyObjects) then { continue }; + + + // check if any encountered object is a built one + private _index = _objects findIf {_x getVariable ["BLWK_collisionObject",false]}; + private _notNearBuiltObject = _index == -1; + if (_notNearBuiltObject) then { continue }; + + + private _collisionObject = _objects select _index; + private _moveToPosition = (_unit getRelPos [20,180]); + // push the unit back from the object + _unit setPosATL (_unit getRelPos [2,180]); + + private _previousCombatBehaviour = combatBehaviour _unit; + private _previousCombatMode = unitCombatMode _unit; + _unit setUnitCombatMode "BLUE"; + _unit setCombatBehaviour "SAFE"; + _unit disableAI "TARGET"; + _unit disableAI "AUTOTARGET"; + + waitUntil { + if ( + !(alive _unit) OR + { + (_unit distance2D _collisionObject) >= 10 + } + ) exitWith {true}; + + // tell the unit to move away + [_unit,_moveToPosition] remoteExec ["move", _unit]; + + sleep 1; + + false + }; + + // return unit state + if (alive _unit) then { + _unit setUnitCombatMode _previousCombatMode; + _unit setCombatBehaviour _previousCombatBehaviour; + _unit enableAI "TARGET"; + _unit enableAI "AUTOTARGET"; + }; }; -*/ diff --git a/Functions/AI Pathing/fn_pathing_detailedStuckCheck.sqf b/Functions/AI Pathing/fn_pathing_detailedStuckCheck.sqf deleted file mode 100644 index 0c75adc8..00000000 --- a/Functions/AI Pathing/fn_pathing_detailedStuckCheck.sqf +++ /dev/null @@ -1,78 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_pathing_detailedStuckCheck - -Description: - If a units leader was detected as not moving in BLWK_fnc_pathing_checkLeaderVelocity - this will do further checks that make sure a unit actually should be teleported - to "unstick" them. - - Needs to be run in scheduled environment. - -Parameters: - 0: _group : - The group to check - -Returns: - - true if unit is stuck, false if not - -Examples: - (begin example) - _needsToBeReset = [_groupLeader] call BLWK_fnc_pathing_detailedStuckCheck; - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -scriptName "BLWK_fnc_pathing_detailedStuckCheck"; - -params ["_group"]; - - -private _groupLeader = leader _group; -// don't mess with vehicle units -if (!isNull (objectParent _groupLeader)) exitWith {false}; - -private _currentPosition = getPosWorld _groupLeader; -private _ammoOfLeader = _groupLeader ammo (currentMuzzle _groupLeader); - - -sleep 5; - - -// Check if leader was engaging targets -if (_groupLeader ammo (currentMuzzle _groupLeader) < _ammoOfLeader) exitWith { - [["Leader of group: ", _group, " appears to be firing at something; doesn't need reset..."],false] call KISKA_fnc_log; - false; -}; - - -// exit if all units are dead -if !([_group] call BLWK_fnc_pathing_isGroupAlive) exitWith { - [[_group," failed secondary group status check..."],false] call KISKA_fnc_log; - false -}; - -private _needsReset = true; -// if the leader fails the velocity check again -if !([_groupLeader] call BLWK_fnc_pathing_checkLeaderVelocity) then { - [[_group," failed secondary velocity status check..."],false] call KISKA_fnc_log; - - // check if there is enough difference in their position to justify not reseting them - private _positionDifference = (getPosWorld _groupLeader) vectorDiff _currentPosition; - [["Checking position differences for group ", _group,"... Position differences are: ",_positionDifference],false] call KISKA_fnc_log; - _positionDifference apply { - // check to make sure there was some significant movement in the unit on any axis - if ((abs _x) > 0.5) then { - [[_group," found a position axis that passed..."],false] call KISKA_fnc_log; - _needsReset = false; - break; - }; - }; - -} else { - [[_group," had immediate velocity check that passed."],false] call KISKA_fnc_log; - _needsReset = false; - -}; - - -_needsReset diff --git a/Functions/AI Pathing/fn_pathing_isGroupAlive.sqf b/Functions/AI Pathing/fn_pathing_isGroupAlive.sqf deleted file mode 100644 index 7296feb0..00000000 --- a/Functions/AI Pathing/fn_pathing_isGroupAlive.sqf +++ /dev/null @@ -1,48 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_pathing_isGroupAlive - -Description: - Checks if a group still has an alive group member. - -Parameters: - 0: _groupToCheck : - The group to check over - -Returns: - - true if active, false if not - -Examples: - (begin example) - _isAlive = [_group] call BLWK_fnc_pathing_isGroupAlive; - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -scriptName "BLWK_fnc_pathing_isGroupAlive"; - -params ["_groupToCheck"]; - - -// check if it was deleted -if (isNull _groupToCheck) exitWith { - ["Was given a null group",false] call KISKA_fnc_log; - false -}; - - -// check if anyone is in it -private _groupUnits = units _groupToCheck; -if (_groupUnits isEqualTo []) exitWith { - [["Found that ",_groupToCheck," is an empty group"],false] call KISKA_fnc_log; - false -}; - - -// check if anyone is alive -private _aliveIndex = _groupUnits findIf {alive _x}; -if (_aliveIndex isNotEqualTo -1) exitWith { - true -}; - - -false diff --git a/Functions/AI Pathing/fn_pathing_mainLoop.sqf b/Functions/AI Pathing/fn_pathing_mainLoop.sqf deleted file mode 100644 index 3df884cc..00000000 --- a/Functions/AI Pathing/fn_pathing_mainLoop.sqf +++ /dev/null @@ -1,107 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: BLWK_fnc_pathing_mainLoop - -Description: - AI enemies sometimes get stuck an refuse to move or just rotate while - decding how to proceed. Often in urban environments. - - During the main loop, if the leader has a velocity of zero, he will then - be given 10 seconds to have a meaningful movement on any axis before - being teleported to a random spawn location. - - Hopefully this resets his pathing. - -Parameters: - 0: _groupToCheck : - The unit or group to add to check over - 1: _timeBetweenChecks : - How often to check the unit leader's velocity - -Returns: - NOTHING - -Examples: - (begin example) - [myGroup,25] spawn BLWK_fnc_pathing_mainLoop; - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -#define RESET_POSITION \ - [["Reset ", _groupLeader],false] call KISKA_fnc_log; \ - [_groupLeader,[BLWK_mainCrate, 5] call CBAP_fnc_randPos] remoteExecCall ["move",_groupLeader]; \ - - -#define LOOP_VAR_NAME "BLWK_runPathingLoop" -scriptName "BLWK_fnc_pathing_mainLoop"; - - -if (!canSuspend) exitWith { - ["Should be run in scheduled environment, exiting to scheduled...",true] call KISKA_fnc_log; - _this spawn BLWK_fnc_pathing_mainLoop; -}; - -params [ - ["_groupToCheck",objNull,[grpNull,objNull]], - ["_timeBetweenChecks",25,[123]] -]; - - -if (isNull _groupToCheck) exitWith { - ["_groupToCheck is null. Exiting...",true] call KISKA_fnc_log; - nil -}; - -// follower units won't likely get stuck as their primary goal is to join the formation at all cost -if (_groupToCheck isEqualType objNull) then { - _groupToCheck = group _groupToCheck; -}; - - -_groupToCheck setVariable [LOOP_VAR_NAME,true]; -while {sleep _timeBetweenChecks; true} do { - - if ( - !(isNull _groupToCheck) AND - { !(_groupToCheck getVariable [LOOP_VAR_NAME,false]) } - - ) then { - [["Loop var for group ",_groupToCheck," was set to false. Exiting..."],false] call KISKA_fnc_log; - - break; - }; - - - if !([_groupToCheck] call BLWK_fnc_pathing_isGroupAlive) then { - [["Found that ",_groupToCheck," failed group alive check. Exiting..."],false] call KISKA_fnc_log; - _groupToCheck setVariable [LOOP_VAR_NAME,nil]; - - break; - }; - - - _groupLeader = leader _groupToCheck; - // checks for units that walk away from play area - if ( - !(_groupLeader getVariable ["BLWK_isACEUnconscious",true]) AND - {isNull (objectParent _groupLeader)} AND - { (_groupLeader distance2D BLWK_playAreaCenter) >= BLWK_maxDistanceFromPlayArea } - - ) then { - [["_groupLeader ",_groupLeader," appears to have walked too far from the play area and will be reset"],true] call KISKA_fnc_log; - RESET_POSITION - - } else { - if !([_groupLeader] call BLWK_fnc_pathing_checkLeaderVelocity) then { - [["_groupLeader ",_groupLeader," failed velocity check at point 1"],false] call KISKA_fnc_log; - - if ([_groupToCheck] call BLWK_fnc_pathing_detailedStuckCheck) then { - [["_groupLeader ",_groupLeader," failed detailted stuck check at point 1"],false] call KISKA_fnc_log; - RESET_POSITION - - }; - }; - }; -}; - - -nil diff --git a/Functions/Other/fn_handleUnconsciousAiEvent.sqf b/Functions/Other/fn_handleUnconsciousAiEvent.sqf index 34a92076..766a2c45 100644 --- a/Functions/Other/fn_handleUnconsciousAiEvent.sqf +++ b/Functions/Other/fn_handleUnconsciousAiEvent.sqf @@ -17,7 +17,7 @@ Examples: (end) Author(s): - Ansible2 // Cipher + Ansible2 ---------------------------------------------------------------------------- */ scriptName "BLWK_fnc_handleUnconsciousAiEvent"; @@ -28,12 +28,14 @@ if !(canSuspend) exitWith { }; waitUntil {!isNil "BLWK_ACELoaded"}; + if !(BLWK_ACELoaded) exitWith { ["ACE is not loaded. Exiting..."] call KISKA_fnc_log; nil }; waitUntil {!isNil "BLWK_theAIHandlerOwnerID"}; + if (clientOwner isNotEqualTo BLWK_theAIHandlerOwnerID) exitWith { ["Not AI handler. Exiting..."] call KISKA_fnc_log; nil @@ -42,18 +44,10 @@ if (clientOwner isNotEqualTo BLWK_theAIHandlerOwnerID) exitWith { [ "ace_unconscious", { - params ["_unit","_unconscious"]; + params ["_unit","_isUnconscious"]; if !(isPlayer _unit) then { - _unit setVariable ["BLWK_isACEUnconscious",true]; - - private _group = group _unit; - if (_unconscious) then { - _group setVariable ["BLWK_runPathingLoop",false]; - } else { // if waking up - [_group] spawn BLWK_fnc_pathing_mainLoop; - }; - + _unit setVariable ["BLWK_isACEUnconscious",_isUnconscious]; }; } ] call CBA_fnc_addEventhandler; diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onGroupCreated.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onGroupCreated.sqf index 29e0db7f..540540b9 100644 --- a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onGroupCreated.sqf +++ b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onGroupCreated.sqf @@ -24,7 +24,6 @@ params [ ["_group",grpNull,[grpNull]] ]; -// [_group] spawn BLWK_fnc_pathing_mainLoop; [_group] spawn BLWK_fnc_stalking_start; diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index dcad9516..2ab5e924 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -2,16 +2,8 @@ class BLWK{ class AiPathing { file = "functions\AI Pathing"; - class pathing_isGroupAlive - {}; - class pathing_checkLeaderVelocity - {}; class pathing_collisionLoop {}; - class pathing_detailedStuckCheck - {}; - class pathing_mainLoop - {}; }; class Build From 4ab30020ba12aa8fc5d3f61abec54c179b176b9a Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 6 Aug 2023 16:10:12 -0600 Subject: [PATCH 105/133] (#642): fixed stalking only working on a single player --- Functions/Stalking/fn_stalking_start.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Functions/Stalking/fn_stalking_start.sqf b/Functions/Stalking/fn_stalking_start.sqf index f901ef44..662e6a27 100644 --- a/Functions/Stalking/fn_stalking_start.sqf +++ b/Functions/Stalking/fn_stalking_start.sqf @@ -223,7 +223,7 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; private _waypoint = [ _stalkerGroup, - player, + _currentPlayerBeingStalked, 0, "SAD", "AWARE", From 7dcc19e3e62c18864ea249b176bcbfbb260b0e31 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 6 Aug 2023 16:14:05 -0600 Subject: [PATCH 106/133] (#642): adjusted behaviour of aircraft gunners to careless in order to fix odd flying --- Functions/Supports/fn_startAircraftGunner.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Functions/Supports/fn_startAircraftGunner.sqf b/Functions/Supports/fn_startAircraftGunner.sqf index cc0f5a0a..2e9d1b5e 100644 --- a/Functions/Supports/fn_startAircraftGunner.sqf +++ b/Functions/Supports/fn_startAircraftGunner.sqf @@ -121,7 +121,7 @@ if ((count _mainTurretWeaponsArray) > 0) then { private _vehicleGroup = _vehicleArray select 2; -_vehicleGroup setBehaviour "SAFE"; +_vehicleGroup setBehaviourStrong "CARELESS"; _vehicleGroup setCombatMode "BLUE"; private _loiterWaypoint = _vehicleGroup addWaypoint [BLWK_playAreaCenter,0]; _loiterWaypoint setWaypointType "LOITER"; From 5ae58ae6e82c6b9ea185828ce8d0e88c29cd80c6 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 6 Aug 2023 16:17:47 -0600 Subject: [PATCH 107/133] (#642): fixed extraction helicopter spawning in water --- Functions/Extraction/fn_extraction.sqf | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Functions/Extraction/fn_extraction.sqf b/Functions/Extraction/fn_extraction.sqf index 7bb8e6f7..3255d3c0 100644 --- a/Functions/Extraction/fn_extraction.sqf +++ b/Functions/Extraction/fn_extraction.sqf @@ -300,7 +300,12 @@ private _fn_afterExtractionWaitTime = { BLWK_extractionAircraft = []; BLWK_playersInExtractAircraft = []; _landingPositions apply { - private _spawnPosition = [_centerPosition,3000,random 360] call CBAP_fnc_randPos; + private _spawnPosition = [ + _centerPosition, + 3000, + random 360, + 50 + ] call KISKA_fnc_getPosRelativeSurface; private _aircraftInfo = [ _spawnPosition, From 815907b5250a08c06b5300b43d8b9e28d5333797 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 6 Aug 2023 22:03:36 -0600 Subject: [PATCH 108/133] (#642): fixed arsenal drop not having arsenal on it --- Functions/Supports/fn_arsenalSupplyDrop.sqf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Functions/Supports/fn_arsenalSupplyDrop.sqf b/Functions/Supports/fn_arsenalSupplyDrop.sqf index 6ed4cc32..6529ada5 100644 --- a/Functions/Supports/fn_arsenalSupplyDrop.sqf +++ b/Functions/Supports/fn_arsenalSupplyDrop.sqf @@ -122,6 +122,8 @@ private _flyToPosition = _dropPosition getPos [FLY_RADIUS,_relativeDirection]; missionNamespace setVariable ["BLWK_arsenalOut",false,true]; }]; + [[_arsenalBox]] call KISKA_fnc_addArsenal; + private _timeBetweenMessages = ARSENAL_LIFETIME / 5; private ["_increment","_timeLeft","_message"]; for "_i" from 1 to 5 do { // give out five messages From c5e0811b2cfca640345e9582234fbeb0ea51317a Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 6 Aug 2023 22:05:02 -0600 Subject: [PATCH 109/133] (#642): adjusted collision loop detection frequency --- Functions/AI Pathing/fn_pathing_collisionLoop.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Functions/AI Pathing/fn_pathing_collisionLoop.sqf b/Functions/AI Pathing/fn_pathing_collisionLoop.sqf index 1aa5f24a..1f193380 100644 --- a/Functions/AI Pathing/fn_pathing_collisionLoop.sqf +++ b/Functions/AI Pathing/fn_pathing_collisionLoop.sqf @@ -44,7 +44,7 @@ if (isNull _unit) exitWith {}; while {BLWK_doDetectCollision AND (alive _unit)} do { - sleep 1; + sleep 0.2; // don't run while a unit is in a vehicle private _unitIsInVehicle = !(isNull (objectParent _unit)); From 0a9e495fe866a32b26659db830e6fd8ea8c2bca8 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sun, 6 Aug 2023 22:10:16 -0600 Subject: [PATCH 110/133] (#642): fixed extraction wave having vehicles spawn --- Functions/Extraction/fn_extraction.sqf | 1 + .../Standard Wave Lib/fn_standardWave_onWaveInit.sqf | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Functions/Extraction/fn_extraction.sqf b/Functions/Extraction/fn_extraction.sqf index 3255d3c0..7a89ceee 100644 --- a/Functions/Extraction/fn_extraction.sqf +++ b/Functions/Extraction/fn_extraction.sqf @@ -407,6 +407,7 @@ private _fn_afterExtractionWaitTime = { /* ---------------------------------------------------------------------------- Main Function ---------------------------------------------------------------------------- */ +missionNamespace setVariable ["BLWK_isExtractionWave",true]; /* ------------------------------------- Get Heli Data diff --git a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveInit.sqf b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveInit.sqf index 9b91d0b2..63c43d9d 100644 --- a/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveInit.sqf +++ b/Functions/Wave Type Libraries/Standard Wave Lib/fn_standardWave_onWaveInit.sqf @@ -20,8 +20,10 @@ Author(s): ---------------------------------------------------------------------------- */ scriptName "BLWK_fnc_standardWave_onWaveInit"; -private _startingWaveUnits = call BLWK_fnc_getMustKillList; -[_startingWaveUnits] call BLWK_fnc_standardWave_vehicles; +if !(missionNamespace getVariable ["BLWK_isExtractionWave",false]) then { + private _startingWaveUnits = call BLWK_fnc_getMustKillList; + [_startingWaveUnits] call BLWK_fnc_standardWave_vehicles; +}; nil From 09847491e22391ff1b595493f62a4ff1053225aa Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Wed, 20 Sep 2023 18:46:12 -0600 Subject: [PATCH 111/133] (#642): fixed managed run kiska function not working with secondary runs --- .../KISKA Utility Functions/fn_managedRun_execute.sqf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/KISKA Systems/KISKA Utility Functions/fn_managedRun_execute.sqf b/KISKA Systems/KISKA Utility Functions/fn_managedRun_execute.sqf index 30c79bfe..b067479b 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_managedRun_execute.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_managedRun_execute.sqf @@ -116,9 +116,9 @@ if !(_nameOfCode in _codeMap) exitWith { private _isNewManagement = _idToRunAgainst isEqualTo -1; private _currentAdjustmentId = _idNamespace getVariable ["KISKA_managedRun_latestId",-1]; private _idToAdjustIsCurrent = _currentAdjustmentId isEqualTo _idToRunAgainst; - +private _newAdjustmentIdExists = (!_isNewManagement) AND (!_idToAdjustIsCurrent) AND (_currentAdjustmentId isNotEqualTo -1); // new id was made, don't run code -if ((!_isNewManagement) AND (!_idToAdjustIsCurrent)) exitWith { -1 }; +if (_newAdjustmentIdExists) exitWith { -1 }; private _idOfRun = -1; if (_isNewManagement) then { From c09579cffb891c8105382fd48ab7cd0307b419b0 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 18 Jan 2025 15:46:38 -0700 Subject: [PATCH 112/133] Updated kiska music functions --- .../Headers/Music Common Defines.hpp | 2 - .../Random Music/fn_randomMusic.sqf | 42 +++++++++++++------ .../fn_musicEventHandlers.sqf | 5 +++ .../KISKA Music Functions/fn_playMusic.sqf | 5 +-- 4 files changed, 36 insertions(+), 18 deletions(-) diff --git a/KISKA Systems/KISKA Music Functions/Headers/Music Common Defines.hpp b/KISKA Systems/KISKA Music Functions/Headers/Music Common Defines.hpp index 27c62082..e1da58bf 100644 --- a/KISKA Systems/KISKA Music Functions/Headers/Music Common Defines.hpp +++ b/KISKA Systems/KISKA Music Functions/Headers/Music Common Defines.hpp @@ -1,5 +1,3 @@ -//#include "Headers\Music Common Defines.hpp" - #define MUSIC_TICK_ACCURACY 10 #define MUSIC_VAR_SPACE localNamespace diff --git a/KISKA Systems/KISKA Music Functions/Random Music/fn_randomMusic.sqf b/KISKA Systems/KISKA Music Functions/Random Music/fn_randomMusic.sqf index 5d02e34a..7b0b670d 100644 --- a/KISKA Systems/KISKA Music Functions/Random Music/fn_randomMusic.sqf +++ b/KISKA Systems/KISKA Music Functions/Random Music/fn_randomMusic.sqf @@ -13,12 +13,13 @@ Description: You can define quiet time space between tracks. Parameters: - 0: _tickId - Used to superceed another random music loop, passs -1 to start a new one - 1: _musicTracks - An array of strings (music tracks) to use - 2: _interval - A random or set time between tracks. - Formats are [min,mid,max] & [max] for random numbers and + 0: _musicTracks - An array of classnames for music defined in `CfgMusic` + 1: _interval - A random or set time between tracks. Formats are `[min,mid,max]` & `[max]` for random numbers and just a single number for a set time between (see example) - 3: _usedMusicTracks - An array of already used music tracks, don't bother manually entering anyhting, this is for looping purposes + 2: _canInterrupt - If this is a new random music set, will the initial song + be able to interrupt any playing music. + 3: _tickId - Used to superceed another random music loop, passs -1 to start a new one + 4: _usedMusicTracks - An array of already used music tracks, don't bother manually entering anyhting, this is for looping purposes Returns: NOTHING @@ -27,12 +28,12 @@ Examples: (begin example) // space tracks by 20 seconds exactly each [-1,arrayOfTracks,20] call KISKA_fnc_randomMusic; - (end) + (end) (begin example) // space tracks by UP TO 20 seconds each [-1,arrayOfTracks,[20]] call KISKA_fnc_randomMusic; - (end) + (end) Author: Ansible2 @@ -50,15 +51,16 @@ if !(isServer) exitWith { Params ---------------------------------------------------------------------------- */ params [ - ["_tickId",-1,[123]], ["_musicTracks",call KISKA_fnc_randomMusic_getUnusedTracks,[[]]], ["_interval",call KISKA_fnc_randomMusic_getTrackInterval,[[],123]], + ["_canInterrupt",true,[true]], + ["_tickId",-1,[123]], ["_usedMusicTracks",call KISKA_fnc_randomMusic_getUsedTracks,[[]]] ]; private _latestTickID = GET_MUSIC_RANDOM_START_TIME; -private _isNewLoop = _tickId isEqualTo -1; -if ((!_isNewLoop) AND (_tickId < _latestTickID)) exitWith { +private _isNewRandomMusicSet = _tickId isEqualTo -1; +if ((!_isNewRandomMusicSet) AND (_tickId < _latestTickID)) exitWith { [["Tick ID: ",_tickId," was thrown out in favor of ID: ",_latestTickID],false] call KISKA_fnc_log; nil }; @@ -87,7 +89,15 @@ if (_musicTracks isEqualTo []) then { private _selectedTrack = [_musicTracks] call KISKA_fnc_deleteRandomIndex; // get defined volume for random music system private _volume = call KISKA_fnc_randomMusic_getVolume; -[_selectedTrack,0,false,_volume,3,true] remoteExec ["KISKA_fnc_playMusic",[0,-2] select isDedicated]; +_canInterrupt = _canInterrupt AND _isNewRandomMusicSet; +[ + _selectedTrack, + 0, + _canInterrupt, + _volume, + 3, + true +] remoteExec ["KISKA_fnc_playMusic",[0,-2] select isDedicated]; if !(call KISKA_fnc_randomMusic_isSystemRunning) then { @@ -144,7 +154,7 @@ private _waitTime = _durationOfTrack + _randomWaitTime; not continue their own loops */ -if (_isNewLoop) then { +if (_isNewRandomMusicSet) then { _tickId = diag_tickTime; SET_MUSIC_VAR(MUSIC_RANDOM_START_TIME_VAR_STR,_tickId); }; @@ -153,7 +163,13 @@ if (_isNewLoop) then { { _this call KISKA_fnc_randomMusic; }, - [_tickId], + [ + _musicTracks, + _interval, + false, + _tickId, + _usedMusicTracks + ], _waitTime ] call CBAP_fnc_waitAndExecute; diff --git a/KISKA Systems/KISKA Music Functions/fn_musicEventHandlers.sqf b/KISKA Systems/KISKA Music Functions/fn_musicEventHandlers.sqf index 937e8acd..048435aa 100644 --- a/KISKA Systems/KISKA Music Functions/fn_musicEventHandlers.sqf +++ b/KISKA Systems/KISKA Music Functions/fn_musicEventHandlers.sqf @@ -23,6 +23,11 @@ scriptName "KISKA_fnc_musicEventHandlers"; if (!hasInterface) exitWith {}; +if (call KISKA_fnc_isMainMenu) exitWith { + ["Main menu detected, will not init",false] call KISKA_fnc_log; + nil +}; + ["Added KISKA music event handlers",false] call KISKA_fnc_log; addMusicEventHandler ["MusicStart", { diff --git a/KISKA Systems/KISKA Music Functions/fn_playMusic.sqf b/KISKA Systems/KISKA Music Functions/fn_playMusic.sqf index 4688747f..a07d28e2 100644 --- a/KISKA Systems/KISKA Music Functions/fn_playMusic.sqf +++ b/KISKA Systems/KISKA Music Functions/fn_playMusic.sqf @@ -51,7 +51,6 @@ params [ ["_isRandomTrack",false,[true]] ]; - private _trackConfig = [["cfgMusic",_track]] call KISKA_fnc_findConfigAny; if (isNull _trackConfig) exitWith { [[_track," is not a defined track in any CfgMusic"],true] call KISKA_fnc_log; @@ -64,8 +63,8 @@ private _exit = false; private _fadeDown = false; if (_musicPlaying) then { if (_isRandomTrack) then { - // if the current playing track is also random - if ((call KISKA_fnc_randomMusic_getCurrentTrack) isNotEqualTo "") then { + private _playingMusicIsRandom = (call KISKA_fnc_randomMusic_getCurrentTrack) isNotEqualTo ""; + if (_playingMusicIsRandom OR _canInterrupt) then { _fadeDown = true; } else { From b5277d69902885924312a3f7f74de600c3902c1b Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 18 Jan 2025 15:46:50 -0700 Subject: [PATCH 113/133] Commented out debug log --- Functions/Stalking/fn_stalking_start.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Functions/Stalking/fn_stalking_start.sqf b/Functions/Stalking/fn_stalking_start.sqf index 662e6a27..f11290f0 100644 --- a/Functions/Stalking/fn_stalking_start.sqf +++ b/Functions/Stalking/fn_stalking_start.sqf @@ -200,7 +200,7 @@ _stalkerGroup setVariable ["BLWK_stalking_emptyEventId",_emptyEventId]; // _x move _playerPosition; // }; _stalkerGroup move _playerPosition; - [_stalkerGroup,["told to move ",_playerPosition] joinString ""] call _fn_add3dLog; + // [_stalkerGroup,["told to move ",_playerPosition] joinString ""] call _fn_add3dLog; } else { From ea4f94b3bad5b788b20c0f28f7e23bba8a37d388 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 18 Jan 2025 19:55:32 -0700 Subject: [PATCH 114/133] Added CBA function imitations for add and remove per frame handlers --- Functions/CBAP/fn_addPerFrameHandler.sqf | 64 +++++++++++++++++++++ Functions/CBAP/fn_removePerFrameHandler.sqf | 41 +++++++++++++ Headers/descriptionEXT/functions.hpp | 7 ++- 3 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 Functions/CBAP/fn_addPerFrameHandler.sqf create mode 100644 Functions/CBAP/fn_removePerFrameHandler.sqf diff --git a/Functions/CBAP/fn_addPerFrameHandler.sqf b/Functions/CBAP/fn_addPerFrameHandler.sqf new file mode 100644 index 00000000..7762a993 --- /dev/null +++ b/Functions/CBAP/fn_addPerFrameHandler.sqf @@ -0,0 +1,64 @@ +/* ---------------------------------------------------------------------------- +Function: CBAP_fnc_addPerFrameHandler + +Description: + A cheap imitation of CBAP_fnc_addPerFrameHandler that uses scheduled environment. + + The actual code to run (_function) will be executed in an unscheduled environment. + + Avoid using this. + +Parameters: + 0: _function - The function you wish to execute. + 1: _delay - The amount of time in seconds between executions, 0 for every frame. (optional, default: 0) + 2: _args - Parameters passed to the function executing. This will be the same array every execution. (optional) + +Returns: + _handle - A number representing the handle of the function. Use this to remove the handler. + +Example: + (begin example) + _handle = [ + {player sideChat format ["every frame! _this: %1", _this];}, + 0, + ["some","params",1,2,3] + ] call CBAP_fnc_addPerFrameHandler; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +if (["cba_common"] call KISKA_fnc_isPatchLoaded) exitWith { + _this call CBA_fnc_addPerFrameHandler; +}; + +params [ + ["_function", {}, [{}]], + ["_delay", 0, [0]], + ["_args", []] +]; + +if (_function isEqualTo {}) exitWith {-1}; + +private _id = localNamespace getVariable ['CBAP_perFrameHandlerIdCount',0]; +localNamespace setVariable ['CBAP_perFrameHandlerIdCount',_id + 1]; +localNamespace setVariable ['CBAP_runPerFrameHandler_' + (str _id),true]; + +[_function,_delay,_args,_id] spawn { + private _runVar = 'CBAP_runPerFrameHandler_' + (str _id); + waitUntil { + [ + _function, + _args + ] call CBAP_fnc_directCall; + + if (_delay > 0) then { + sleep _delay; + }; + + localNamespace getVariable [_runVar,false] + }; +}; + + +_id diff --git a/Functions/CBAP/fn_removePerFrameHandler.sqf b/Functions/CBAP/fn_removePerFrameHandler.sqf new file mode 100644 index 00000000..1cbd809e --- /dev/null +++ b/Functions/CBAP/fn_removePerFrameHandler.sqf @@ -0,0 +1,41 @@ +/* ---------------------------------------------------------------------------- +Function: CBAP_fnc_removePerFrameHandler + +Description: + A cheap imitation of CBAP_fnc_removePerFrameHandler that uses scheduled environment. + + Remove a handler that you have added using CBAP_fnc_addPerFrameHandler. + +Parameters: + _handle - The function handle you wish to remove. + +Returns: + true if removed successful, false otherwise + +Examples: + (begin example) + _handle = [{player sideChat format["every frame! _this: %1", _this];}, 0, ["some","params",1,2,3]] call CBA_fnc_addPerFrameHandler; + sleep 10; + [_handle] call CBA_fnc_removePerFrameHandler; + (end) + +Author: + Nou & Jaynus, donated from ACRE project code for use by the community; commy2 +---------------------------------------------------------------------------- */ +params [ + ["_handle", -1, [0]] +]; + +[ + { + params ["_handle"]; + + private _runningVar = 'CBAP_runPerFrameHandler_' + (str _handle); + private _isRunning = localNamespace getVariable [_runningVar,false]; + if (!_isRunning) exitWith { false }; + + localNamespace setVariable [_runningVar,nil]; + true + }, + _handle +] call CBAP_fnc_directCall \ No newline at end of file diff --git a/Headers/descriptionEXT/functions.hpp b/Headers/descriptionEXT/functions.hpp index 2ab5e924..3006462c 100644 --- a/Headers/descriptionEXT/functions.hpp +++ b/Headers/descriptionEXT/functions.hpp @@ -1,4 +1,5 @@ -class BLWK{ +class BLWK +{ class AiPathing { file = "functions\AI Pathing"; @@ -568,6 +569,8 @@ class CBAP //ported CBA functions file = "functions\CBAP"; class addWaypoint {}; + class addPerFrameHandler + {}; class directCall {}; class getArea @@ -586,6 +589,8 @@ class CBAP //ported CBA functions {}; class randPosArea {}; + class removePerFrameHandler + {}; class shuffle {}; class simplifyAngle From 68a544a63a83cc2a2c4eba71ee7ad16fb949c69b Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 18 Jan 2025 19:55:41 -0700 Subject: [PATCH 115/133] Formatting --- Functions/CBAP/fn_waitUntilAndExecute.sqf | 61 +++++++++++------------ 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/Functions/CBAP/fn_waitUntilAndExecute.sqf b/Functions/CBAP/fn_waitUntilAndExecute.sqf index 628bff91..c9b3a764 100644 --- a/Functions/CBAP/fn_waitUntilAndExecute.sqf +++ b/Functions/CBAP/fn_waitUntilAndExecute.sqf @@ -4,40 +4,39 @@ Function: CBAP_fnc_waitUntilAndExecute Description: A cheap imitation of CBA_fnc_waitUntilAndExecute that uses scheduled environment. - The actual code to run (_function) will be executed in an unscheduled environment. + The actual code to run (_function) will be executed in an unscheduled environment. - Avoid using this. + Avoid using this. Parameters: 0: _condition - The function to evaluate as condition 1: _statement - The function to run once the condition is true - 2: _args - Parameters passed to the functions (statement and condition) executing - 3: _timeout - If >= 0, timeout for the condition in seconds. If < 0, no timeout. - Exactly 0 means timeout immediately on the next iteration - 4: _timeoutCode - Will execute instead of _statement if the condition times out + 2: _args - Parameters passed to the functions (statement and condition) executing + 3: _timeout - If >= 0, timeout for the condition in seconds. If < 0, no timeout. + Exactly 0 means timeout immediately on the next iteration + 4: _timeoutCode - Will execute instead of _statement if the condition times out Returns: NOTHING Example: (begin example) - [ - { - (_this select 0) == vehicle (_this select 0) - }, - { - (_this select 0) setDamage 1; - }, - [player] - ] call CBAP_fnc_waitUntilAndExecute; + [ + { + (_this select 0) == vehicle (_this select 0) + }, + { + (_this select 0) setDamage 1; + }, + [player] + ] call CBAP_fnc_waitUntilAndExecute; (end) Author(s): Ansible2 ---------------------------------------------------------------------------- */ - if (["cba_common"] call KISKA_fnc_isPatchLoaded) exitWith { - _this call CBA_fnc_waitUntilAndExecute; + _this call CBA_fnc_waitUntilAndExecute; }; params [ @@ -49,23 +48,23 @@ params [ ]; _this spawn { - params ["_condition","_statement","_args","_timeout","_timeoutCode"]; + params ["_condition","_statement","_args","_timeout","_timeoutCode"]; - private _hasTimeout = _timeout >= 0; - private _timeoutTime = time + _timeout; - waitUntil { - if (_args call _condition) exitWith { - [_statement, _args] call CBAP_fnc_directCall; - true - }; + private _hasTimeout = _timeout >= 0; + private _timeoutTime = time + _timeout; + waitUntil { + if (_args call _condition) exitWith { + [_statement, _args] call CBAP_fnc_directCall; + true + }; - if (_hasTimeout AND (time >= _timeoutTime)) exitWith { - [_timeoutCode, _args] call CBAP_fnc_directCall; - true - }; + if (_hasTimeout AND (time >= _timeoutTime)) exitWith { + [_timeoutCode, _args] call CBAP_fnc_directCall; + true + }; - false - }; + false + }; }; From 460c4bf97d0f1a8749bfa4726592d33f78f1a8cf Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 18 Jan 2025 19:56:17 -0700 Subject: [PATCH 116/133] Updated kiska CAS functions --- .../KISKA Utility Functions/fn_CAS.sqf | 352 +++++++++++------- .../KISKA Utility Functions/fn_CASAttack.sqf | 316 +++++++++------- 2 files changed, 393 insertions(+), 275 deletions(-) diff --git a/KISKA Systems/KISKA Utility Functions/fn_CAS.sqf b/KISKA Systems/KISKA Utility Functions/fn_CAS.sqf index 97178566..1f21fc2b 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_CAS.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_CAS.sqf @@ -6,7 +6,7 @@ Description: Completes either a gun run, bomb run, rockets, or rocket and gun strike. Parameters: - 0: _attackPosition : - ASL position or object to attack + 0: _attackPosition : - ASL position or object to attack 1: _attackTypeID : - See CAS Type IDs.hpp . If an array, format needs to be [attackTypeId,pylonMagazineClass]. Custom mag classes, when used for napalm or UGB ids, will drop the ENTIRE payload @@ -29,7 +29,7 @@ Returns: Examples: (begin example) - [myTarget] spawn KISKA_fnc_CAS; + [myTarget] call KISKA_fnc_CAS; (end) Author(s): @@ -38,11 +38,6 @@ Author(s): ---------------------------------------------------------------------------- */ scriptName "KISKA_fnc_CAS"; -if !(canSuspend) exitWith { - ["Needs to be run in scheduled, exiting to scheduled...",false] call KISKA_fnc_log; - _this spawn KISKA_fnc_CAS; -}; - #define DEFAULT_CANNON_CLASS "Twin_Cannon_20mm" #define DEFAULT_CANNON_MAG_CLASS "PylonWeapon_300Rnd_20mm_shells" @@ -53,6 +48,10 @@ if !(canSuspend) exitWith { #define CUSTOM_OR_DEFAULT_MAG(defaultClass) [_customMagClass,defaultClass] select (_customMagClass isEqualTo "") +#define STRAFE_INCREMENT 0.1 +#define FLARE_COUNT 4 +#define TIME_TILL_DELETE 64 + params [ ["_attackPosition",objNull,[[],objNull]], ["_attackTypeID",0,[123,[]]], @@ -67,7 +66,12 @@ params [ ["_allowDamage",false,[true]] ]; -if (_attackPosition isEqualType objNull AND {isNull _attackPosition} OR {_attackPosition isEqualTo []}) exitWith { + +if ( + (_attackPosition isEqualType objNull) AND + {isNull _attackPosition} OR + {_attackPosition isEqualTo []} +) exitWith { [[_attackPosition," is an invalid target"],true] call KISKA_fnc_log; nil }; @@ -76,7 +80,7 @@ private _planeCfg = configfile >> "cfgvehicles" >> _planeClass; if !(isclass _planeCfg) exitwith { [[_planeClass," Vehicle class not found, moving to default aircraft..."],true] call KISKA_fnc_log; _this set [3,DEFAULT_AIRCRAFT]; - _this spawn KISKA_fnc_CAS; + _this call KISKA_fnc_CAS; }; @@ -96,28 +100,34 @@ _attackMagazines = switch _attackTypeID do { [CANNON_TYPE] }; case GUNS_AND_ROCKETS_ARMOR_PIERCING_ID: { - [CANNON_TYPE,[ROCKETS_AP_TYPE,CUSTOM_OR_DEFAULT_MAG("PylonRack_7Rnd_Rocket_04_AP_F")]] + [ + CANNON_TYPE, + [ROCKETS_AP_TYPE, CUSTOM_OR_DEFAULT_MAG("PylonRack_7Rnd_Rocket_04_AP_F")] + ] }; case GUNS_AND_ROCKETS_HE_ID: { - [CANNON_TYPE,[ROCKETS_HE_TYPE,CUSTOM_OR_DEFAULT_MAG("PylonRack_7Rnd_Rocket_04_HE_F")]] + [ + CANNON_TYPE, + [ROCKETS_HE_TYPE, CUSTOM_OR_DEFAULT_MAG("PylonRack_7Rnd_Rocket_04_HE_F")] + ] }; case ROCKETS_ARMOR_PIERCING_ID: { - [[ROCKETS_AP_TYPE,CUSTOM_OR_DEFAULT_MAG("PylonRack_7Rnd_Rocket_04_AP_F")]] + [[ROCKETS_AP_TYPE, CUSTOM_OR_DEFAULT_MAG("PylonRack_7Rnd_Rocket_04_AP_F")]] }; case ROCKETS_HE_ID: { - [[ROCKETS_HE_TYPE,CUSTOM_OR_DEFAULT_MAG("PylonRack_7Rnd_Rocket_04_HE_F")]] + [[ROCKETS_HE_TYPE, CUSTOM_OR_DEFAULT_MAG("PylonRack_7Rnd_Rocket_04_HE_F")]] }; case AGM_ID: { - [[AGM_TYPE,CUSTOM_OR_DEFAULT_MAG("PylonRack_1Rnd_Missile_AGM_02_F")]] + [[AGM_TYPE, CUSTOM_OR_DEFAULT_MAG("PylonRack_1Rnd_Missile_AGM_02_F")]] }; case BOMB_LGB_ID: { - [[BOMB_LGB_TYPE,CUSTOM_OR_DEFAULT_MAG("PylonMissile_1Rnd_Bomb_04_F")]] + [[BOMB_LGB_TYPE, CUSTOM_OR_DEFAULT_MAG("PylonMissile_1Rnd_Bomb_04_F")]] }; case BOMB_CLUSTER_ID: { - [[BOMB_UGB_TYPE,CUSTOM_OR_DEFAULT_MAG("PylonMissile_1Rnd_BombCluster_01_F")]] + [[BOMB_UGB_TYPE, CUSTOM_OR_DEFAULT_MAG("PylonMissile_1Rnd_BombCluster_01_F")]] }; case BOMB_NAPALM_ID: { - [[BOMB_UGB_TYPE,CUSTOM_OR_DEFAULT_MAG("vn_bomb_f4_out_500_blu1b_fb_mag_x1")]] + [[BOMB_UGB_TYPE, CUSTOM_OR_DEFAULT_MAG("vn_bomb_f4_out_500_blu1b_fb_mag_x1")]] }; }; @@ -175,16 +185,20 @@ if (isClass _pylonConfig) then { }; // if there was more then just the cannon in the _attackMagazines array - if !(_attackMagazines isEqualTo []) then { - private ["_attackTypeString","_attackMagazineClass","_attackWeaponClass"]; + if (_attackMagazines isNotEqualTo []) then { { - [["attackMag is: ",_x],false] call KISKA_fnc_log; - _attackMagazineClass = _x select 1; - _attackWeaponClass = [configFile >> "cfgMagazines" >> _attackMagazineClass >> "pylonWeapon"] call BIS_fnc_getCfgData; + _x params ["_attackTypeString","_attackMagazineClass"]; + private _attackWeaponClass = [ + configFile >> "cfgMagazines" >> _attackMagazineClass >> "pylonWeapon" + ] call BIS_fnc_getCfgData; - _attackTypeString = _x select 0; // pushBack string for attack type, the weapon used, the mag for adding a pylon, and what pylon to add it to - _weaponsToUse pushBack [_attackTypeString,_attackWeaponClass,[_attackMagazineClass,_allVehiclePylons deleteAt 0]]; + private _nextPylon = _allVehiclePylons deleteAt 0; + _weaponsToUse pushBack [ + _attackTypeString, + _attackWeaponClass, + [_attackMagazineClass, _nextPylon] + ]; } forEach _attackMagazines; }; @@ -195,17 +209,23 @@ if (isClass _pylonConfig) then { if (_exitToDefault) exitwith { - [["Weapon types of ",_attackMagazines," for plane class: ",_planeClass," not entirely found, moving to default Aircraft..."],true] call KISKA_fnc_log; + [ + [ + "Weapon types of ", + _attackMagazines, + " for plane class: ", + _planeClass, + " not entirely found, moving to default Aircraft..." + ], + true + ] call KISKA_fnc_log; + // exit to default aircraft type _this set [3,DEFAULT_AIRCRAFT]; - _this spawn KISKA_fnc_CAS; + _this call KISKA_fnc_CAS; }; -/* ---------------------------------------------------------------------------- - Define attack function ----------------------------------------------------------------------------- */ - /* ---------------------------------------------------------------------------- Position plane towards target @@ -213,13 +233,19 @@ if (_exitToDefault) exitwith { private _planeSpawnPosition = [ _attackPosition, _spawnDistance, - (_attackDirection + 180), - _spawnHeight + (_attackDirection + 180) ] call KISKA_fnc_getPosRelativeSurface; -private _planeArray = [_planeSpawnPosition,_attackDirection,_planeClass,_side,false] call KISKA_fnc_spawnVehicle; -private _plane = _planeArray select 0; -private _crew = _planeArray select 1; +_planeSpawnPosition = _planeSpawnPosition vectorAdd [0,0,_spawnHeight]; +private _planeArray = [ + _planeSpawnPosition, + _attackDirection, + _planeClass, + _side, + false +] call KISKA_fnc_spawnVehicle; +_planeArray params ["_plane","_crew","_planeGroup"]; +[_planeGroup,true] call KISKA_fnc_ACEX_setHCTransfer; if !(_allowDamage) then { _plane allowDamage false; @@ -243,8 +269,6 @@ _weaponsToUse apply { _plane setPosASL _planeSpawnPosition; _plane setDir _attackDirection; - - _plane disableAi "autotarget"; _plane setCombatMode "blue"; @@ -260,12 +284,7 @@ if (_attackPosition isEqualType objNull) then { private _planePositionASL = getPosASLVisual _plane; private _vectors = [_planePositionASL,_attackPosition] call KISKA_fnc_getVectorToTarget; _plane setVectorDirAndUp _vectors; -private _planeVectorDirTo = _vectors select 0; -private _planeVectorUp = _vectors select 1; - -// set plane's speed to 200 km/h -_plane setVelocityModelSpace PLANE_VELOCITY(PLANE_SPEED); - +_vectors params ["_planeVectorDirTo","_planeVectorUp"]; /* ---------------------------------------------------------------------------- Fix planes velocity towards the target @@ -276,105 +295,154 @@ private _flightTime = (_vectorDistanceToTarget - _breakOffDistance) / PLANE_SPEE private _startTime = time; private _timeAfterFlight = time + _flightTime; - -private "_interval"; - -waitUntil { - _planePositionASL = getPosASLVisual _plane; - _vectorDistanceToTarget = _attackPosition vectorDistance _planePositionASL; - - if ( - isNull _plane OR - {_plane getVariable ["KISKA_completedFiring",false]} OR - {_vectorDistanceToTarget <= _breakOffDistance} - ) - exitWith {true}; - - //--- Set the plane approach vector - _interval = linearConversion [_startTime,_timeAfterFlight,time,0,1]; - - _plane setVelocityTransformation [ - _planeSpawnPosition, _attackPosition, - PLANE_VELOCITY(PLANE_SPEED), PLANE_VELOCITY(PLANE_SPEED), - _planeVectorDirTo,_planeVectorDirTo, - _planeVectorUp, _planeVectorUp, - _interval - ]; - - _plane setVelocityModelSpace PLANE_VELOCITY(PLANE_SPEED); - - - // start firing - // check if plane is from target and hasn't already started shooting - if (_vectorDistanceToTarget <= _attackDistance) then { - - if !(_plane getVariable ["KISKA_startedFiring",false]) then { - _plane setVariable ["KISKA_startedFiring",true]; - // create a target to shoot at - private _dummyTargetClass = ["LaserTargetE","LaserTargetW"] select (_side getfriend west > 0.6); - private _dummyTarget = createvehicle [_dummyTargetClass,[0,0,0],[],0,"NONE"]; - _plane setVariable ["KISKA_casDummyTarget",_dummyTarget]; - _dummyTarget setPosASL _attackPosition; - _plane reveal laserTarget _dummyTarget; - _plane dowatch laserTarget _dummyTarget; - _plane dotarget laserTarget _dummyTarget; - - [_plane,_dummyTarget,_weaponsToUse,_attackTypeID,_attackPosition,_breakOffDistance] spawn KISKA_fnc_casAttack; - - } else { - // ensures strafing effect with the above setVelocityTransformation - /// for some reason, private variables outside the main if here do not work - /// had to use this method of storing the target instead - private _dummyTarget = _plane getVariable "KISKA_casDummyTarget"; - _attackPosition = AGLToASL(_dummyTarget getPos [0.1,(getDirVisual _plane)]); - _dummyTarget setPosASL _attackPosition; - - }; - }; - - sleep 0.01; - - false -}; - -/* ---------------------------------------------------------------------------- - Handle After CAS complete ----------------------------------------------------------------------------- */ -// forces plane to keep flying in the general direction they currently are -// if not, once the setVelocityTransformation loop is done, it can rapidly change course -_plane setVelocityModelSpace PLANE_VELOCITY(PLANE_SPEED); - -// telling the plane to ultimately fly past the target after we're done controlling it -_plane move (_attackPosition getPos [5000,_attackDirection]); - -// after fire is complete -_plane flyInHeight (_spawnHeight * 2); - - -// pop flares -for "_i" from 1 to 4 do { - currentPilot _plane forceweaponfire ["CMFlareLauncher","Burst"]; - sleep 1 -}; - -// give the plane some time to get out of audible distance before deletion -sleep 60; - -// delete -_crew apply { - if (!isNull _x) then { - _plane deleteVehicleCrew _x; - }; -}; - -if (alive _plane) then { - deleteVehicle _plane; -}; - -private _group = _planeArray select 2; -if (!isNull _group) then { - deleteGroup _group; -}; +[ + { + params ["_args","_id"]; + _args params [ + "_plane", + "_originalAttackPosition", + "_attackDirection", + "_breakOffDistance", + "_planeSpawnPosition", + "_startTime", + "_timeAfterFlight", + "_planeSpawnPosition", + "_planeArray", + "_weaponsToUse", + "_attackTypeID", + "_planeVectorDirTo", + "_planeVectorUp", + "_side", + "_attackDistance", + "_spawnHeight" + ]; + + private _attackPosition = _plane getVariable ["KISKA_CAS_attackPosition",_originalAttackPosition]; + private _planePositionASL = getPosASLVisual _plane; + private _vectorDistanceToTarget = _attackPosition vectorDistance _planePositionASL; + + if ( + isNull _plane OR + {_plane getVariable ["KISKA_CAS_completedFiring",false]} OR + {_vectorDistanceToTarget <= _breakOffDistance} + ) + exitWith { + /* ---------------------------------------------------------------------------- + Handle After CAS complete + ---------------------------------------------------------------------------- */ + // telling the plane to ultimately fly past the target after we're done controlling it + _plane move (_attackPosition getPos [5000,_attackDirection]); + + // after fire is complete + _plane flyInHeight (_spawnHeight * 2); + + // pop flares + private _pilot = currentPilot _plane; + for "_i" from 1 to FLARE_COUNT do { + [ + { + params ["_pilot"]; + _pilot forceweaponfire ["CMFlareLauncher","Burst"]; + }, + [_pilot], + _i + ] call CBAP_fnc_waitAndExecute; + }; + + // give the plane some time to get out of audible distance before deletion + [ + { + params ["_plane","_crew","_group"]; + + _crew apply { + if (!isNull _x) then { + _plane deleteVehicleCrew _x; + }; + }; + + if (alive _plane) then { + deleteVehicle _plane; + }; + + if (!isNull _group) then { + deleteGroup _group; + }; + }, + _planeArray, + TIME_TILL_DELETE + ] call CBAP_fnc_waitAndExecute; + + [_id] call CBAP_fnc_removePerFrameHandler; + }; + + //--- Set the plane approach vector + private _interval = linearConversion [_startTime,_timeAfterFlight,time,0,1]; + private _velocity = (vectorNormalized (_attackPosition vectorDiff _planePositionASL)) vectorMultiply PLANE_SPEED; + _plane setVelocityTransformation [ + _planeSpawnPosition, _attackPosition, + _velocity, _velocity, + _planeVectorDirTo, _planeVectorDirTo, + _planeVectorUp, _planeVectorUp, + _interval + ]; + + // start firing + // check if plane is from target and hasn't already started shooting + if (_vectorDistanceToTarget > _attackDistance) exitWith {}; + + if !(_plane getVariable ["KISKA_CAS_startedFiring",false]) then { + _plane setVariable ["KISKA_CAS_startedFiring",true]; + // create a target to shoot at + private _dummyTargetClass = ["LaserTargetE","LaserTargetW"] select ((_side getfriend west) > 0.6); + private _dummyTarget = createvehicle [_dummyTargetClass,[0,0,0],[],0,"NONE"]; + _plane setVariable ["KISKA_CAS_dummyTarget",_dummyTarget]; + _dummyTarget setPosASL _attackPosition; + private _laserTarget = laserTarget _dummyTarget; + _plane reveal _laserTarget; + _plane dowatch _laserTarget; + _plane dotarget _laserTarget; + + [ + _plane, + _dummyTarget, + _weaponsToUse, + _attackTypeID, + _attackPosition, + _breakOffDistance + ] spawn KISKA_fnc_CASAttack; + + } else { + // ensures strafing effect with the above setVelocityTransformation + private _dummyTarget = _plane getVariable "KISKA_CAS_dummyTarget"; + private _nextAttackPostition = _dummyTarget getPos [STRAFE_INCREMENT,(getDirVisual _plane)]; + // did this here for readability + _nextAttackPostition = AGLToASL _nextAttackPostition; + + _plane setVariable ["KISKA_CAS_attackPosition",_nextAttackPostition]; + _dummyTarget setPosASL _nextAttackPostition; + }; + + }, + 0.01, + [ + _plane, + _attackPosition, + _attackDirection, + _breakOffDistance, + _planeSpawnPosition, + _startTime, + _timeAfterFlight, + _planeSpawnPosition, + _planeArray, + _weaponsToUse, + _attackTypeID, + _planeVectorDirTo, + _planeVectorUp, + _side, + _attackDistance, + _spawnHeight + ] +] call CBAP_fnc_addPerframeHandler; nil diff --git a/KISKA Systems/KISKA Utility Functions/fn_CASAttack.sqf b/KISKA Systems/KISKA Utility Functions/fn_CASAttack.sqf index 89a0fe10..78262bc0 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_CASAttack.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_CASAttack.sqf @@ -26,179 +26,229 @@ Author(s): ---------------------------------------------------------------------------- */ scriptName "KISKA_fnc_CASAttack"; -if !(canSuspend) exitWith { - ["Needs to be run in scheduled, exiting to scheduled...",true] call KISKA_fnc_log; - _this spawn KISKA_fnc_CASAttack; -}; - - -params ["_plane","_dummyTarget","_weaponsToUse","_attackTypeID","_attackPosition","_breakOffDistance"]; - - -private ["_weaponClass_temp","_weaponArray_temp","_magClass_temp"]; -private _pilot = currentPilot _plane; -_plane setVariable ["KISKA_CAS_guidedWeapon",""]; - +#define FIRE_GUN_INTERVAL 0.03 +#define FIRE_ROCKET_INTERVAL 0.5 +#define FIRE_BOMB_INTERVAL 0.5 +#define GUIDE_WEAPON_INTERVAL 0.05 + +params [ + "_plane", + "_dummyTarget", + "_weaponsToUse", + "_attackTypeID", + "_attackPosition", + "_breakOffDistance" +]; + +_plane setVariable ["KISKA_CAS_guidedFireEvent",{ + params ["_plane","_projectile"]; + + private _projectileStartPosASL = getPosASLVisual _projectile; + private _dummyTarget = _plane getVariable ["KISKA_CAS_dummyTarget",objNull]; + private _attackPosition = getPosASLVisual _dummyTarget; + private _vectors = [_projectileStartPosASL,_attackPosition] call KISKA_fnc_getVectorToTarget; + + private _speed = speed _projectile; + _projectile setVectorDirAndUp _vectors; + _projectile setVelocityModelSpace [0,_speed,0]; + + _vectors params ["_vectorDir","_vectorUp"]; + private _vectorDistanceToTarget = _attackPosition vectorDistance _projectileStartPosASL; + private _flightTime = _vectorDistanceToTarget / _speed; + private _startTime = time; + private _timeAfterFlight = time + _flightTime; + + [ + { + params ["_args","_id"]; + + if (isNull _projectile) exitWith { + [_id] call CBAP_fnc_removePerFrameHandler; + }; -private _fn_setWeaponTemp = { - params ["_type",["_setAsGuided",false]]; - _weaponArray_temp = _weaponsToUse select (_weaponsToUse findIf {(_x select 0) == _type}); - _weaponClass_temp = _weaponArray_temp select 1; - if (_setAsGuided) then { - _plane setVariable ["KISKA_CAS_guidedWeapon",_weaponClass_temp]; - }; - //_plane setVariable ["KISKA_CAS_tempWeapon",_weaponClass_temp]; - _magClass_temp = (_weaponArray_temp select 2) select 0; - //[["Setting weapon class temp to: ", _weaponClass_temp]] call KISKA_fnc_log; -}; + _args params [ + "_projectile", + "_projectileStartPosASL", + "_vectorDir", + "_vectorUp", + "_startTime", + "_timeAfterFlight", + "_attackPosition" + ]; + + private _interval = linearConversion [_startTime,_timeAfterFlight,time,0,1]; + private _velocity = velocity _projectile; + _projectile setVelocityTransformation [ + _projectileStartPosASL, _attackPosition, + _velocity, _velocity, + _vectorDir,_vectorDir, + _vectorUp, _vectorUp, + _interval + ]; + }, + GUIDE_WEAPON_INTERVAL, + [ + _projectile, + _projectileStartPosASL, + _vectorDir, + _vectorUp, + _startTime, + _timeAfterFlight, + _attackPosition + ] + ] call CBAP_fnc_addPerFrameHandler; +}]; // CUP planes in particular have an issue with rocket fire not being accurate +// This will guide projectiles to where they should go _plane addEventHandler ["Fired", { - params ["_plane", "_weapon", "", "", "", "", "_projectile", ""]; - - if (_weapon == (_plane getVariable "KISKA_CAS_guidedWeapon")) then { - - [_plane,_projectile] spawn { - params ["_plane","_projectile"]; - - private _projectileStartPosASL = getPosASLVisual _projectile; - private _dummyTarget = _plane getVariable ["KISKA_casDummyTarget",objNull]; - private _attackPosition = getPosASLVisual _dummyTarget; - private _vectors = [_projectileStartPosASL,_attackPosition] call KISKA_fnc_getVectorToTarget; - - sleep 0.1; // allow the projectile to get some speed - - private _speed = speed _projectile; - _projectile setVectorDirAndUp _vectors; - _projectile setVelocityModelSpace [0,_speed,0]; - - private _vectorDir = _vectors select 0; - private _vectorUp = _vectors select 1; - private _vectorDistanceToTarget = _attackPosition vectorDistance _projectileStartPosASL; - private _flightTime = _vectorDistanceToTarget / _speed; - private _startTime = time; - private _timeAfterFlight = time + _flightTime; - - private "_interval"; - - waitUntil { - _interval = linearConversion [_startTime,_timeAfterFlight,time,0,1]; - _attackPosition = getPosASLVisual _dummyTarget; - - _projectile setVelocityTransformation [ - _projectileStartPosASL, _attackPosition, - velocity _projectile, velocity _projectile, - _vectorDir,_vectorDir, - _vectorUp, _vectorUp, - _interval - ]; - - sleep 0.01; - - isNull _projectile; - }; - }; - + params ["_plane", "_weapon", "", "", "", "", "_projectile"]; + + private _isGuidedWeapon = _weapon == (_plane getVariable "KISKA_CAS_guidedWeapon"); + if (_isGuidedWeapon) then { + [ + _plane getVariable ["KISKA_CAS_guidedFireEvent",{}], + [_plane, _projectile], + 0.1 // allow the projectile to get some speed + ] call CBAP_fnc_waitAndExecute; }; }]; -private _fn_fireGun = { - params ["_numRounds"]; - // set _weaponClass_temp to gun - [CANNON_TYPE] call _fn_setWeaponTemp; - - private _didFireAtTarget = false; - private _forceFire = false; - private _weaponMode = ""; +private _fn_generateQueuedFireItems = { + params [ + ["_numberOfRounds",-1,[123]], + ["_weaponType","",[""]], + ["_fireInterval",0.5,[123]], + ["_isGuided",false,[false]] + ]; - for "_i" from 1 to _numRounds do { - if ((_plane distance _attackPosition) < _breakOffDistance) exitWith {}; - - if !(_forceFire) then { - _didFireAtTarget = _pilot fireAtTarget [_dummyTarget,_weaponClass_temp]; - if !(_didFireAtTarget) then { - _forceFire = true; - _weaponMode = (getArray(configFile >> "CfgWeapons" >> _weaponClass_temp >> "modes")) select 0; - }; + private _indexOfWeaponInfoForType = _weaponsToUse findIf {(_x select 0) == _weaponType}; + private _weaponArray = _weaponsToUse select _indexOfWeaponInfoForType; + _weaponArray params ["","_weaponClass","_pylonInfo"]; + private _weaponMagClass = _pylonInfo select 0; + if (_numberOfRounds < 1) then { + private _configedNumberOfRoundsInMag = getNumber(configFile >> "CfgMagazines" >> _weaponMagClass >> "count"); + if (_configedNumberOfRoundsInMag isEqualTo 0) then { + _numberOfRounds = 1; } else { - // certain vehicles seem to not work with fireAtTarget on the cannon ("vn_b_air_f4c_cas" from CDLC SOGPF) - _pilot forceWeaponFire [_weaponClass_temp,_weaponMode]; - + _numberOfRounds = _configedNumberOfRoundsInMag; }; - - sleep 0.03; - }; -}; - - -private _fn_fireRockets = { - params ["_numRounds","_type"]; - // find rocket launcher - [_type,true] call _fn_setWeaponTemp; - - for "_i" from 1 to _numRounds do { - if ((_plane distance _attackPosition) < _breakOffDistance) then {break;}; - _pilot fireAtTarget [_dummyTarget,_weaponClass_temp]; - sleep 0.5; }; -}; - -private _fn_fireSimple = { - params ["_numRounds","_type",["_guideToTarget",false]]; + private _fireModes = getArray(configFile >> "CfgWeapons" >> _weaponClass >> "modes"); + private _primaryFireMode = _fireModes param [0,""]; - [_type,_guideToTarget] call _fn_setWeaponTemp; + private _fireWeaponArgs = [ + _fireInterval, + [_weaponClass, _primaryFireMode, _isGuided] + ]; + private _queuedFireItems = []; + for "_i" from 1 to _numberOfRounds do { _queuedFireItems pushBack _fireWeaponArgs }; - if (_numRounds isEqualTo -1) then { - _numRounds = getNumber(configFile >> "CfgMagazines" >> _magClass_temp >> "count"); - if (_numRounds isEqualTo 0) then { - _numRounds = 1; - }; - }; - for "_i" from 1 to _numRounds do { - _pilot fireAtTarget [_dummyTarget,_weaponClass_temp]; - sleep 0.5; - }; + _queuedFireItems }; + +private "_fireQueue"; // decide how to fire switch (_attackTypeID) do { case GUN_RUN_ID: { - [200] call _fn_fireGun; + _fireQueue = [200, CANNON_TYPE, FIRE_GUN_INTERVAL] call _fn_generateQueuedFireItems; }; case GUNS_AND_ROCKETS_ARMOR_PIERCING_ID: { - [100] call _fn_fireGun; - [6,ROCKETS_AP_TYPE] call _fn_fireRockets; + _fireQueue = [100, CANNON_TYPE, FIRE_GUN_INTERVAL] call _fn_generateQueuedFireItems; + _fireQueue append ([6, ROCKETS_AP_TYPE, FIRE_ROCKET_INTERVAL, true] call _fn_generateQueuedFireItems); }; case GUNS_AND_ROCKETS_HE_ID: { - [100] call _fn_fireGun; - [6,ROCKETS_HE_TYPE] call _fn_fireRockets; + _fireQueue = [100, CANNON_TYPE, FIRE_GUN_INTERVAL] call _fn_generateQueuedFireItems; + _fireQueue append ([6, ROCKETS_HE_TYPE, FIRE_ROCKET_INTERVAL, true] call _fn_generateQueuedFireItems); }; case ROCKETS_ARMOR_PIERCING_ID: { - [8,ROCKETS_AP_TYPE] call _fn_fireRockets; + _fireQueue = [8, ROCKETS_AP_TYPE, FIRE_ROCKET_INTERVAL, true] call _fn_generateQueuedFireItems; }; case ROCKETS_HE_ID: { - [8,ROCKETS_HE_TYPE] call _fn_fireRockets; + _fireQueue = [8, ROCKETS_HE_TYPE, FIRE_ROCKET_INTERVAL, true] call _fn_generateQueuedFireItems; }; case AGM_ID: { - [1,AGM_TYPE] call _fn_fireRockets; + _fireQueue = [1, AGM_TYPE, 0, true] call _fn_generateQueuedFireItems; }; case BOMB_LGB_ID: { - [1,BOMB_LGB_TYPE] call _fn_fireSimple; + _fireQueue = [1, BOMB_LGB_TYPE, 0] call _fn_generateQueuedFireItems; }; + case BOMB_NAPALM_ID; case BOMB_CLUSTER_ID: { - [-1,BOMB_UGB_TYPE] call _fn_fireSimple; - }; - case BOMB_NAPALM_ID: { - [-1,BOMB_UGB_TYPE,true] call _fn_fireSimple; + _fireQueue = [-1, BOMB_UGB_TYPE, FIRE_BOMB_INTERVAL] call _fn_generateQueuedFireItems; }; }; -_plane setVariable ["KISKA_completedFiring",true]; +private _fireIntervalTotal = 0; +private _maxFireQueueIndex = (count _fireQueue) - 1; +private _planeInfo = [ + _plane, + _attackPosition, + _breakOffDistance, + _dummyTarget, + currentPilot _plane +]; + +_plane setVariable ["KISKA_CAS_completedFiring",false]; + + +{ + _x params ["_fireInterval","_fireInfo"]; + + private _isFinal = _forEachIndex isEqualTo _maxFireQueueIndex; + [ + { + // split in two so that constant info (_planeInfo) can remain the same array + // and only the dynamic info (_fireInfo) will be new arrays for each fire + params [ + ["_planeInfo",[],[[]],5], + ["_fireInfo",[],[[]],3], + ["_isFinal",false,[false]] + ]; + + _planeInfo params [ + ["_plane",objNull,[objNull]], + ["_attackPosition",[],[[]],3], + ["_breakOffDistance",1,[123]], + ["_dummyTarget",objNull,[objNull]], + ["_pilot",objNull,[objNull]] + ]; + + if (_plane getVariable ["KISKA_CAS_completedFiring",true]) exitWith {}; + + + _fireInfo params [ + ["_weaponClass","",[""]], + ["_primaryFireMode","",[""]], + ["_isGuided",false,[false]] + ]; + + if (_isGuided) then { + _plane setVariable ["KISKA_CAS_guidedWeapon",_weaponClass]; + }; + + // certain vehicles seem to not work with fireAtTarget on the cannon ("vn_b_air_f4c_cas" from CDLC SOGPF) + private _canFireAtTarget = _pilot fireAtTarget [_dummyTarget,_weaponClass]; + if (!_canFireAtTarget) then { + _pilot forceWeaponFire [_weaponClass,_primaryFireMode]; + }; + + if (_isFinal OR ((_plane distance _attackPosition) < _breakOffDistance)) exitWith { + _plane setVariable ["KISKA_CAS_completedFiring",true]; + }; + }, + [_planeInfo, _fireInfo, _isFinal], + _fireIntervalTotal + ] call CBAP_fnc_waitAndExecute; + + _fireIntervalTotal = _fireIntervalTotal + _fireInterval; +} forEach _fireQueue; nil From 08d9034ec27eee4bcb96dd2cd9b81609c8a2f7fc Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 18 Jan 2025 20:54:43 -0700 Subject: [PATCH 117/133] Updated KISKA_fnc_classTurretsWithGuns --- .../fn_classTurretsWithGuns.sqf | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/KISKA Systems/KISKA Utility Functions/fn_classTurretsWithGuns.sqf b/KISKA Systems/KISKA Utility Functions/fn_classTurretsWithGuns.sqf index e8e61164..2c7d4905 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_classTurretsWithGuns.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_classTurretsWithGuns.sqf @@ -9,7 +9,7 @@ Parameters: 0: _classToCheck - The vehicle class to check Returns: - - The turret paths + - The turret paths Examples: (begin example) @@ -40,24 +40,25 @@ if !(isClass(configFile >> "CfgVehicles" >> _classToCheck)) exitWith { // excludes fire from vehicle turrets private _allVehicleTurrets = [_classToCheck, false] call BIS_fnc_allTurrets; -// just turrets with weapons private _turretsWithWeapons = []; -private ["_turretWeapons_temp","_return_temp","_turretPath_temp"]; + _allVehicleTurrets apply { - _turretPath_temp = _x; - _turretWeapons_temp = getArray([_classToCheck,_turretPath_temp] call BIS_fnc_turretConfig >> "weapons"); - // if turrets are found - if (_turretWeapons_temp isNotEqualTo []) then { - // some turrets are just optics, need to see they actually have ammo to shoot - _return_temp = _turretWeapons_temp findIf { - private _mags = [_x] call BIS_fnc_compatibleMagazines; - // some turrets are just laser designators, hence checking that there are no laserbatteries - (_mags isNotEqualTo []) AND {!((_mags select 0) == "laserbatteries")} - }; - - if (_return_temp isNotEqualTo -1) then { - _turretsWithWeapons pushBack _turretPath_temp; - }; + private _turretPath = _x; + private _turretWeapons = getArray([_classToCheck,_turretPath] call BIS_fnc_turretConfig >> "weapons"); + private _noTurretWeaponsFound = _turretWeapons isEqualTo []; + + if (_noTurretWeaponsFound) then { continue }; + + // some turrets are just optics, need to see they actually have ammo to shoot + private _indexOfValidMagazine = _turretWeapons findIf { + private _mags = [_x,true] call BIS_fnc_compatibleMagazines; + // some turrets are just laser designators, hence checking that there are no laserbatteries + (_mags isNotEqualTo []) AND {!((_mags select 0) == "laserbatteries")} + }; + + private _validTurretMagazineFound = _indexOfValidMagazine isNotEqualTo -1; + if (_validTurretMagazineFound) then { + _turretsWithWeapons pushBack _turretPath; }; }; From 30d0150234096acdcc6a6165ff1ce1edc6e09807 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 18 Jan 2025 23:29:31 -0700 Subject: [PATCH 118/133] Updated KISKA_fnc_clearWaypoints --- .../KISKA Utility Functions/fn_clearWaypoints.sqf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/KISKA Systems/KISKA Utility Functions/fn_clearWaypoints.sqf b/KISKA Systems/KISKA Utility Functions/fn_clearWaypoints.sqf index 1c20598a..082590ff 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_clearWaypoints.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_clearWaypoints.sqf @@ -19,27 +19,27 @@ Example: Author(s): SilentSpike, - Modified By: Ansible2 + Modified By: Ansible2 ---------------------------------------------------------------------------- */ params [ - ["_group", grpNull, [grpNull, objNull]], + ["_group", grpNull, [grpNull, objNull]], ["_numberToRemove",-1,[123]], - ["_stopUnits", false, [true]] + ["_stopUnits", false, [true]] ]; if (_group isEqualType objNull) then { - _group = group _group; + _group = group _group; }; private _numberOfCurrentWaypoints = count (waypoints _group); if (_numberOfCurrentWaypoints isEqualTo 0) exitWith {}; -if (_numberToRemove < 0) then { +if (_numberToRemove isEqualTo -1) then { _numberToRemove = _numberOfCurrentWaypoints; }; for "_i" from (_numberToRemove - 1) to 0 step -1 do { - deleteWaypoint [_group, _i]; + deleteWaypoint [_group, _i]; }; private _removedAllWaypoints = _numberToRemove isEqualTo _numberOfCurrentWaypoints; From cc29da912001bc8fc75bb57f3133158f409c2172 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 18 Jan 2025 23:30:16 -0700 Subject: [PATCH 119/133] Updated KISKA_fnc_countdown --- .../KISKA Utility Functions/fn_countdown.sqf | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/KISKA Systems/KISKA Utility Functions/fn_countdown.sqf b/KISKA Systems/KISKA Utility Functions/fn_countdown.sqf index c6bcfb2d..743f4d37 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_countdown.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_countdown.sqf @@ -43,12 +43,28 @@ params [ ]; if (_countDownTotal < _shownCountDown) then { - [["_shownCountDown: ",_shownCountDown ," should be less then _countDownTotal: ", _countDownTotal],false] call KISKA_fnc_log; + [ + [ + "_shownCountDown: ", + _shownCountDown , + " should be less then _countDownTotal: ", + _countDownTotal + ], + false + ] call KISKA_fnc_log; _shownCountDown = _countDownTotal; }; if (_soundedCountDown > _shownCountDown) then { - [["_soundedCountDown: ",_soundedCountDown ," should be less then _shownCountDown: ", _shownCountDown],false] call KISKA_fnc_log; + [ + [ + "_soundedCountDown: ", + _soundedCountDown , + " should be less then _shownCountDown: ", + _shownCountDown + ], + false + ] call KISKA_fnc_log; _soundedCountDown = _shownCountDown; }; From e061ebe3a809eccb48d226f0812728665ccdb7b7 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 18 Jan 2025 23:37:53 -0700 Subject: [PATCH 120/133] Updated KISKA_fnc_spawnVehicle --- .../fn_spawnVehicle.sqf | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/KISKA Systems/KISKA Utility Functions/fn_spawnVehicle.sqf b/KISKA Systems/KISKA Utility Functions/fn_spawnVehicle.sqf index 8f9c88ff..5522a203 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_spawnVehicle.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_spawnVehicle.sqf @@ -6,7 +6,7 @@ Description: Has support for CUP aircraft to spawn at velocity. Parameters: - 0: _spawnPosition - 3D array in the format of PositionATL + 0: _spawnPosition - 3D array in the format of PositionATL (PositionAGL if boat or amphibious). Objects can be used, however, this 1: _spawnDirection - The direction the vehicle is facing when created (relative to north) if _spawnPosition is an object and _spawnDirection == -1, _spawnDirection will be set to the @@ -16,15 +16,15 @@ Parameters: already existing group to add the units to 4: _forcePosition - Force vehicle to spawn at exact coordinates Does nothing when _spawnPosition is an object - 5: _crewInstructions - An array of classnames of unit types and/or man objects + 5: _crewInstructions <(STRING | OBJECT)[]> - An array of classnames of unit types and/or man objects for the crew. Units are moved into the vehicle using moveInAny in the order provided 6: _deleteOverflow - Delete any units from _crewInstructions that prexisted if they don't fit in the vehicle Returns: - - - 0: - The created vehicle - 1: - The vehicle crew (if soldier type, it will be the same as created vehicle) - 2: - The group the crew is a part of + <[OBJECT,OBJECT[],GROUP]> - + - 0: - The created vehicle + - 1: - The vehicle crew (if soldier type, it will be the same as created vehicle) + - 2: - The group the crew is a part of Examples: (begin example) @@ -149,7 +149,17 @@ if (_simulationType != "soldier") then { _movedIn = _unit moveInAny _createdVehicle; if (!_movedIn) then { - [["Unit ",_unit," could not be moved into the vehicle ",_createdVehicle," as there was no room in the vehicle"],true] call KISKA_fnc_log; + [ + [ + "Unit ", + _unit, + " could not be moved into the vehicle ", + _createdVehicle, + " as there was no room in the vehicle" + ], + true + ] call KISKA_fnc_log; + if (_deleteOverflow) then { deleteVehicle _unit; }; From 5194585eb3a1fd2a2e550a1eae78aa0e56a8089b Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 18 Jan 2025 23:38:05 -0700 Subject: [PATCH 121/133] KISKA_fnc_selectRandom --- .../KISKA Utility Functions/fn_selectRandom.sqf | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/KISKA Systems/KISKA Utility Functions/fn_selectRandom.sqf b/KISKA Systems/KISKA Utility Functions/fn_selectRandom.sqf index 956f306c..951ca08b 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_selectRandom.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_selectRandom.sqf @@ -5,8 +5,8 @@ Description: Selects randomly an entry from an array be it weighted or unweighted. Parameters: - 0: _array - An array either formatted as [value, weight (number)], or - just values ([value1,value2]) + 0: _array - An array either formatted as `[value, weight (number)]`, `[[array_of_values],[array_of_weights]]`, or + just values (`[value1,value2]`) 1: _valueType - A variable that should have the same type as the value entries in the array e.g. "" for string, [] for array (only needed for possibly weighted arrays) @@ -65,7 +65,12 @@ if (isNil "_valueType") exitWith { selectRandom _array; }; -private _isWeightedArray_syntaxOne = (_array isEqualTypeParams [[],[]]) AND ((count _array) isEqualTo 2); +private _isWeightedArray_syntaxOne = (_array isEqualTypeParams [[],[]]) AND + ((count _array) isEqualTo 2) AND + { + (WEIGHTS isEqualTypeParams [123]) AND + (VALUES_TO_SELECT isEqualTypeParams [_valueType]) + }; if (_isWeightedArray_syntaxOne) exitWith { VALUES_TO_SELECT selectRandomWeighted WEIGHTS; }; From 01acf5b28d64a034091e5f4361c7293b57730b72 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 18 Jan 2025 23:39:24 -0700 Subject: [PATCH 122/133] Updated KISKA_fnc_paratroopers --- KISKA Systems/KISKA Utility Functions/fn_paratroopers.sqf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/KISKA Systems/KISKA Utility Functions/fn_paratroopers.sqf b/KISKA Systems/KISKA Utility Functions/fn_paratroopers.sqf index bec80960..a9e88500 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_paratroopers.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_paratroopers.sqf @@ -107,9 +107,9 @@ _dropZone set [2,_flyInHeight]; private _spawnPosition = [ _dropZone, _spawnDistance, - _flyFromDirection, - _flyInHeight + _flyFromDirection ] call KISKA_fnc_getPosRelativeSurface; +_spawnPosition vectorAdd [0,0,_flyInHeight]; /* ---------------------------------------------------------------------------- Create vehicle to drop units From 8de01a29372f89501df3faa39c829e7398bcaa86 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 18 Jan 2025 23:39:49 -0700 Subject: [PATCH 123/133] Updated KISKA_fnc_notify --- KISKA Systems/KISKA Utility Functions/fn_notify.sqf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/KISKA Systems/KISKA Utility Functions/fn_notify.sqf b/KISKA Systems/KISKA Utility Functions/fn_notify.sqf index 63bb4bd1..0010e935 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_notify.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_notify.sqf @@ -8,12 +8,12 @@ Description: Parameters: 0: _titleLine : - If string, the message to display as title. + If array: - - 0. _text : - Text to display or path to .paa or .jpg - image (may be passed directly if only text is required) - 1. _size : - Scale of text - 2. _color : - RGB or RGBA color (range 0-1). (optional, default: [1, 1, 1, 1]) + - 0. _text : - Text to display or path to .paa or .jpg + image (may be passed directly if only text is required) + - 1. _size : - Scale of text + - 2. _color : - RGB or RGBA color (range 0-1). (optional, default: [1, 1, 1, 1]) 1: _subLine : - Formatted the same as _titleLine 2: _lifetime : - How long the notification lasts in seconds (at least 2) From 230e692a186af654ef95a23b466b1dc789fd4313 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 18 Jan 2025 23:40:00 -0700 Subject: [PATCH 124/133] Updated KISKA_fnc_managedRun_updateCode --- .../KISKA Utility Functions/fn_managedRun_updateCode.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KISKA Systems/KISKA Utility Functions/fn_managedRun_updateCode.sqf b/KISKA Systems/KISKA Utility Functions/fn_managedRun_updateCode.sqf index 7306bbca..5b6d8f5f 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_managedRun_updateCode.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_managedRun_updateCode.sqf @@ -8,7 +8,7 @@ Description: Parameters: 0: _nameOfCode : - The name of the code to update 1: _code : - The code to run when ID is called - (see KISKA_fnc_callBack). Use `{}` + (see KISKA_fnc_callBack). Use `{}` to remove the handler all together. Returns: NOTHING From 8bdb2f97269e4bba42bed999e14d88e9794e3034 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 18 Jan 2025 23:40:12 -0700 Subject: [PATCH 125/133] Updated KISKA_fnc_managedRun_isDefined --- .../KISKA Utility Functions/fn_managedRun_isDefined.sqf | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/KISKA Systems/KISKA Utility Functions/fn_managedRun_isDefined.sqf b/KISKA Systems/KISKA Utility Functions/fn_managedRun_isDefined.sqf index 331e0d9e..7c3b6259 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_managedRun_isDefined.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_managedRun_isDefined.sqf @@ -6,11 +6,9 @@ Description: Parameters: 0: _nameOfCode : - The name of the code to update - 1: _code : - The code to run when ID is called - (see KISKA_fnc_callBack). Use `{}` Returns: - NOTHING + - Whether or not the managed run code is defined Examples: (begin example) From 9377608cc38c34b3e8a30ef010be1c81d09142b8 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 18 Jan 2025 23:40:27 -0700 Subject: [PATCH 126/133] Updated KISKA_fnc_heliLand --- KISKA Systems/KISKA Utility Functions/fn_heliLand.sqf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/KISKA Systems/KISKA Utility Functions/fn_heliLand.sqf b/KISKA Systems/KISKA Utility Functions/fn_heliLand.sqf index 5cf589ce..9c789865 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_heliLand.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_heliLand.sqf @@ -7,9 +7,9 @@ Description: Parameters: 0: _aircraft - The helicopter 1: _landingPosition - Where to land. If object, position ATL is used. - 2: _landMode - Options are "LAND", "GET IN", and "GET OUT" + 2: _landMode - Options are `"LAND"`, `"GET IN"`, and `"GET OUT"` 3: _createHelipad - If true, and invisible helipad will be created. Helipads strongly encourage where a unit will land. - 4: _afterLandCode - Code to spawn after the helicopter has landed. See KISKA_fnc_callBack + 4: _afterLandCode - Code to `spawn` after the helicopter has landed. See `KISKA_fnc_callBack`. Parameters: - 0: - The helicopter @@ -90,7 +90,7 @@ if (_landMode isNotEqualTo "LAND") then { [_aircraft,_landingPosition,_landMode,_afterLandCode,_keepEngineOn,_landedHeight] spawn { params ["_aircraft","_landingPosition","_landMode","_afterLandCode","_keepEngineOn","_landedHeight"]; - _aircraft move _landingPosition; + [_aircraft,_landingPosition] remoteExecCall ["move",_aircraft]; _aircraft setVariable ["KISKA_isLanding",true]; private _landed = false; From 4567bfb490fae93667d6cfe584446d69545b4588 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 18 Jan 2025 23:40:36 -0700 Subject: [PATCH 127/133] Updated KISKA_fnc_helicopterGunner --- .../KISKA Utility Functions/fn_helicopterGunner.sqf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/KISKA Systems/KISKA Utility Functions/fn_helicopterGunner.sqf b/KISKA Systems/KISKA Utility Functions/fn_helicopterGunner.sqf index fe729b27..a92421e0 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_helicopterGunner.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_helicopterGunner.sqf @@ -22,12 +22,12 @@ Parameters: its complete crew and self to be deleted. The _postSupportCode should return a `BOOL` that if `false` will NOT perform the default behaviour in addition to the callback. - Parameters: - - 0: - The helicopter confucting support - - 1: - The group the pilot belongs to - - 2: - The full vehicle crew - - 3: - The unit that *should* be the pilot of the helicopter - - 4: - The position the helicopter was supporting + Parameters: + - 0: - The helicopter confucting support + - 1: - The group the pilot belongs to + - 2: - The full vehicle crew + - 3: - The unit that *should* be the pilot of the helicopter + - 4: - The position the helicopter was supporting Returns: ARRAY - The vehicle info From c602940c38434ffd895a8563479f7dc7f6d61a52 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 18 Jan 2025 23:41:06 -0700 Subject: [PATCH 128/133] Updated KISKA_fnc_getVariableTarget --- .../fn_getVariableTarget.sqf | 44 +++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/KISKA Systems/KISKA Utility Functions/fn_getVariableTarget.sqf b/KISKA Systems/KISKA Utility Functions/fn_getVariableTarget.sqf index bef5aa07..ddfe1ebe 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_getVariableTarget.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_getVariableTarget.sqf @@ -12,6 +12,13 @@ Parameters: 2: _defaultValue : - If the variable does not exist for the target, what should be returned instead 3: _target : - Where the _target is local will be where the variable is taken from (the machine to get the variable from) + 4: _awaitParams : <[NUMBER,NUMBER,BOOL]> - How the get from the target should be awaited + + Parameters: + - 0: - The sleep time between each check for the variable being received + - 1: - The max time to wait for (this is not total game time but time slept) + - 2: - Whether or not the sleep time should be exponential (double every iteration) + Returns: - Whatever the variable is, nil otherwise @@ -43,7 +50,8 @@ params [ ["_variableName","",[""]], ["_namespace",missionNamespace,[missionNamespace,objNull,"",controlNull,locationNull,grpNull]], ["_defaultValue",nil], - ["_target",2,[123,objNull,""]] + ["_target",2,[123,objNull,""]], + ["_awaitParams",[],[[]]] ]; if ((_target isEqualType objNull) AND {isNull _target}) exitWith { @@ -89,6 +97,11 @@ if (_variableName isEqualTo "") exitWith { _defaultValue }; +_awaitParams params [ + ["_awaitTime",0.05,[123]], + ["_maxWaitTime",2,[123]], + ["_exponentialBackOff",false,[true]] +]; // create a unique variable ID for network tranfer private _messageNumber = missionNamespace getVariable ["KISKA_getVarTargetQueue_count",0]; @@ -99,17 +112,42 @@ private _saveVariable = ["KISKA_GVT",clientOwner,"_",_messageNumber] joinString [_namespace,_variableName,_saveVariable,_defaultValue,clientOwner] remoteExecCall ["KISKA_fnc_getVariableTarget_sendBack",_target]; +private _timeWaited = 0; waitUntil { + if (_timeWaited >= _maxWaitTime) then { + [ + [ + "Max wait time of: ", + _maxWaitTime, + " for variable ", + _saveVariable, + " from target ", + _target, + " was exceeded. Exiting with default value: ", + _defaultValue + ], + false + ] call KISKA_fnc_log; + breakWith true; + }; + if (!isNil _saveVariable) exitWith { [["Got variable ",_saveVariable," from target ",_target],false] call KISKA_fnc_log; true }; - sleep 0.05; + + sleep _awaitTime; + _timeWaited = _timeWaited + _awaitTime; + + if (_exponentialBackOff) then { + _awaitTime = _awaitTime * 2; + }; + [["Waiting for variable from target: ",_target],false] call KISKA_fnc_log; false }; -private _return = missionNamespace getVariable _saveVariable; +private _return = missionNamespace getVariable [_saveVariable,_defaultValue]; missionNamespace setVariable [_saveVariable,nil]; From b39a0bfac2a54ab9c9de0f48acf02d3648e82587 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 18 Jan 2025 23:41:28 -0700 Subject: [PATCH 129/133] Updated KISKA_fnc_deleteRandomIndex --- KISKA Systems/KISKA Utility Functions/fn_deleteRandomIndex.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KISKA Systems/KISKA Utility Functions/fn_deleteRandomIndex.sqf b/KISKA Systems/KISKA Utility Functions/fn_deleteRandomIndex.sqf index c4979e2d..63445619 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_deleteRandomIndex.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_deleteRandomIndex.sqf @@ -5,7 +5,7 @@ Description: Removes and returns a random item from an array Parameters: - 0: _radio - The array to find a random index of. + 0: _array - The array to find a random index of. Returns: - The random item removed from the array From d3f7d6e23f724f5038e5b4e01f4aa3ceb7af46d7 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Wed, 22 Jan 2025 22:55:48 -0700 Subject: [PATCH 130/133] #642: upgraded view distance limiter --- Headers/descriptionEXT/GUI/imports.hpp | 5 + KISKA Systems/KISKA Functions.hpp | 27 +- .../KISKA Headers/GUI/KISKA GUI Classes.hpp | 28 ++ .../KISKA Headers/GUI/KISKA GUI Colors.hpp | 15 + .../KISKA Headers/GUI/KISKA GUI Grid.hpp | 17 + .../KISKA Headers/GUI/KISKA GUI Styles.hpp | 53 +++ .../Headers/params menu.hpp | 16 - .../Functions/fn_VDL_addOpenGuiDiaryEntry.sqf | 49 +++ .../Functions/fn_VDL_controlsGroup_onLoad.sqf | 117 +++++++ .../Functions/fn_VDL_onLoad.sqf | 136 ++++++++ .../Functions/fn_VDL_openDialog.sqf | 35 ++ .../Functions/fn_viewDistanceLimiter.sqf | 119 +++++++ .../View Distance Limiter Common Defines.hpp | 20 ++ .../Headers/View Distance Limiter Dialog.hpp | 316 +++++++++++++++++ .../View Distance Limiter Functions.hpp | 16 + .../Functions/fn_addOpenVdlGuiDiary.sqf | 37 -- .../Functions/fn_adjustVdlControls.sqf | 51 --- .../Functions/fn_findVdlPartnerControl.sqf | 65 ---- .../Functions/fn_handleVdlDialogOpen.sqf | 86 ----- .../Functions/fn_handleVdlGuiCheckbox.sqf | 44 --- .../Functions/fn_isVdlSystemRunning.sqf | 29 -- .../Functions/fn_openVdlDialog.sqf | 26 -- .../Functions/fn_setAllVdlButton.sqf | 32 -- .../Functions/fn_setVdlValue.sqf | 62 ---- .../Functions/fn_viewDistanceLimiter.sqf | 90 ----- .../ViewDistanceLimiterDialog.hpp | 320 ------------------ .../View Distance Limiter/controlTypes.hpp | 38 --- .../View Distance Limiter/dikCodes.hpp | 189 ----------- .../viewDistanceLimiterBases.hpp | 300 ---------------- .../viewDistanceLimiterCommonDefines.hpp | 90 ----- description.ext | 4 +- mission.sqm | 152 ++------- 32 files changed, 953 insertions(+), 1631 deletions(-) create mode 100644 KISKA Systems/KISKA Headers/GUI/KISKA GUI Classes.hpp create mode 100644 KISKA Systems/KISKA Headers/GUI/KISKA GUI Colors.hpp create mode 100644 KISKA Systems/KISKA Headers/GUI/KISKA GUI Grid.hpp create mode 100644 KISKA Systems/KISKA Headers/GUI/KISKA GUI Styles.hpp create mode 100644 KISKA Systems/KISKA View DIstance Limiter/Functions/fn_VDL_addOpenGuiDiaryEntry.sqf create mode 100644 KISKA Systems/KISKA View DIstance Limiter/Functions/fn_VDL_controlsGroup_onLoad.sqf create mode 100644 KISKA Systems/KISKA View DIstance Limiter/Functions/fn_VDL_onLoad.sqf create mode 100644 KISKA Systems/KISKA View DIstance Limiter/Functions/fn_VDL_openDialog.sqf create mode 100644 KISKA Systems/KISKA View DIstance Limiter/Functions/fn_viewDistanceLimiter.sqf create mode 100644 KISKA Systems/KISKA View DIstance Limiter/Headers/View Distance Limiter Common Defines.hpp create mode 100644 KISKA Systems/KISKA View DIstance Limiter/Headers/View Distance Limiter Dialog.hpp create mode 100644 KISKA Systems/KISKA View DIstance Limiter/Headers/View Distance Limiter Functions.hpp delete mode 100644 KISKA Systems/View Distance Limiter/Functions/fn_addOpenVdlGuiDiary.sqf delete mode 100644 KISKA Systems/View Distance Limiter/Functions/fn_adjustVdlControls.sqf delete mode 100644 KISKA Systems/View Distance Limiter/Functions/fn_findVdlPartnerControl.sqf delete mode 100644 KISKA Systems/View Distance Limiter/Functions/fn_handleVdlDialogOpen.sqf delete mode 100644 KISKA Systems/View Distance Limiter/Functions/fn_handleVdlGuiCheckbox.sqf delete mode 100644 KISKA Systems/View Distance Limiter/Functions/fn_isVdlSystemRunning.sqf delete mode 100644 KISKA Systems/View Distance Limiter/Functions/fn_openVdlDialog.sqf delete mode 100644 KISKA Systems/View Distance Limiter/Functions/fn_setAllVdlButton.sqf delete mode 100644 KISKA Systems/View Distance Limiter/Functions/fn_setVdlValue.sqf delete mode 100644 KISKA Systems/View Distance Limiter/Functions/fn_viewDistanceLimiter.sqf delete mode 100644 KISKA Systems/View Distance Limiter/ViewDistanceLimiterDialog.hpp delete mode 100644 KISKA Systems/View Distance Limiter/controlTypes.hpp delete mode 100644 KISKA Systems/View Distance Limiter/dikCodes.hpp delete mode 100644 KISKA Systems/View Distance Limiter/viewDistanceLimiterBases.hpp delete mode 100644 KISKA Systems/View Distance Limiter/viewDistanceLimiterCommonDefines.hpp diff --git a/Headers/descriptionEXT/GUI/imports.hpp b/Headers/descriptionEXT/GUI/imports.hpp index 0160d571..7c700d94 100644 --- a/Headers/descriptionEXT/GUI/imports.hpp +++ b/Headers/descriptionEXT/GUI/imports.hpp @@ -10,6 +10,11 @@ import RscButtonMenu; import RscCheckBox; import RscPicture; import ctrlListNBox; +import RscListbox; +import RscControlsGroupNoHScrollbars; +import RscControlsGroupNoScrollbars; +import ctrlButtonPicture; +import ctrlButton; // import RscControlsGroup; // import RscControlsGroupNoScrollbars; diff --git a/KISKA Systems/KISKA Functions.hpp b/KISKA Systems/KISKA Functions.hpp index ffaba214..924e0c52 100644 --- a/KISKA Systems/KISKA Functions.hpp +++ b/KISKA Systems/KISKA Functions.hpp @@ -1,33 +1,8 @@ class KISKA { #include "KISKA Parameter Menu\Headers\param menu functions.hpp" + #include "KISKA View DIstance Limiter\Headers\View Distance Limiter Functions.hpp" - class DynamicViewDistance - { - file = "KISKA Systems\View Distance Limiter\Functions"; - class addOpenVdlGuiDiary - { - postInit = 1; - }; - class adjustVdlControls - {}; - class findVdlPartnerControl - {}; - class handleVdlDialogOpen - {}; - class handleVdlGuiCheckbox - {}; - class isVdlSystemRunning - {}; - class openVdlDialog - {}; - class setAllVdlButton - {}; - class setVdlValue - {}; - class viewDistanceLimiter - {}; - }; class KISKA_RandomMusic { file = "KISKA Systems\KISKA Music Functions\Random Music"; diff --git a/KISKA Systems/KISKA Headers/GUI/KISKA GUI Classes.hpp b/KISKA Systems/KISKA Headers/GUI/KISKA GUI Classes.hpp new file mode 100644 index 00000000..a611d32d --- /dev/null +++ b/KISKA Systems/KISKA Headers/GUI/KISKA GUI Classes.hpp @@ -0,0 +1,28 @@ +#include "KISKA GUI Colors.hpp" +#include "KISKA GUI Grid.hpp" + +class KISKA_RscCloseButton : RscButtonMenu +{ + idc = -1; + text = ""; + x = KISKA_POS_X(7.5); + y = KISKA_POS_Y(-10); + w = KISKA_POS_W(1); + h = KISKA_POS_H(1); + colorText[] = KISKA_GREY_COLOR(0,1); + colorActive[] = KISKA_GREY_COLOR(0,1); + textureNoShortcut = "\A3\3den\Data\Displays\Display3DEN\search_END_ca.paa"; + class ShortcutPos + { + left = 0; + top = 0; + w = KISKA_POS_W(1); + h = KISKA_POS_H(1); + }; + animTextureNormal = "#(argb,8,8,3)color(1,0,0,0.57)"; + animTextureDisabled = ""; + animTextureOver = "#(argb,8,8,3)color(1,0,0,0.57)"; + animTextureFocused = ""; + animTexturePressed = "#(argb,8,8,3)color(1,0,0,0.57)"; + animTextureDefault = ""; +}; diff --git a/KISKA Systems/KISKA Headers/GUI/KISKA GUI Colors.hpp b/KISKA Systems/KISKA Headers/GUI/KISKA GUI Colors.hpp new file mode 100644 index 00000000..40caa06e --- /dev/null +++ b/KISKA Systems/KISKA Headers/GUI/KISKA GUI Colors.hpp @@ -0,0 +1,15 @@ +#ifndef KISKA_COLORS + + #define KISKA_COLORS 1 + + #define KISKA_PROFILE_BACKGROUND_COLOR(ALPHA)\ + {\ + "(profilenamespace getvariable ['GUI_BCG_RGB_R',0.13])",\ + "(profilenamespace getvariable ['GUI_BCG_RGB_G',0.54])",\ + "(profilenamespace getvariable ['GUI_BCG_RGB_B',0.21])",\ + ALPHA\ + } + + #define KISKA_GREY_COLOR(PERCENT,ALPHA) {PERCENT,PERCENT,PERCENT,ALPHA} + +#endif diff --git a/KISKA Systems/KISKA Headers/GUI/KISKA GUI Grid.hpp b/KISKA Systems/KISKA Headers/GUI/KISKA GUI Grid.hpp new file mode 100644 index 00000000..216234ef --- /dev/null +++ b/KISKA Systems/KISKA Headers/GUI/KISKA GUI Grid.hpp @@ -0,0 +1,17 @@ +#ifndef KISKA_GUI_GRID + + #define KISKA_GUI_GRID 1 + + #define KISKA_UI_GRID_X (0.5) + #define KISKA_UI_GRID_Y (0.5) + #define KISKA_UI_GRID_W (2.5 * pixelW * pixelGrid) + #define KISKA_UI_GRID_H (2.5 * pixelH * pixelGrid) + + #define KISKA_POS_X(N) N * KISKA_UI_GRID_W + KISKA_UI_GRID_X + #define KISKA_POS_Y(N) N * KISKA_UI_GRID_H + KISKA_UI_GRID_Y + #define KISKA_POS_W(N) N * KISKA_UI_GRID_W + #define KISKA_POS_H(N) N * KISKA_UI_GRID_H + + #define KISKA_GUI_TEXT_SIZE(MULTIPLIER) (pixelH * pixelGrid) * MULTIPLIER + +#endif diff --git a/KISKA Systems/KISKA Headers/GUI/KISKA GUI Styles.hpp b/KISKA Systems/KISKA Headers/GUI/KISKA GUI Styles.hpp new file mode 100644 index 00000000..814e163e --- /dev/null +++ b/KISKA Systems/KISKA Headers/GUI/KISKA GUI Styles.hpp @@ -0,0 +1,53 @@ +#ifndef KISKA_styles + #define KISKA_styles 1 + + // Static styles + #define KISKA_ST_POS 0x0F + #define KISKA_ST_HPOS 0x03 + #define KISKA_ST_VPOS 0x0C + #define KISKA_ST_LEFT 0x00 + #define KISKA_ST_RIGHT 0x01 + #define KISKA_ST_CENTER 0x02 + #define KISKA_ST_DOWN 0x04 + #define KISKA_ST_UP 0x08 + #define KISKA_ST_VCENTER 0x0C + + #define KISKA_ST_TYPE 0xF0 + #define KISKA_ST_SINGLE 0x00 + #define KISKA_ST_MULTI 0x10 + #define KISKA_ST_TITLE_BAR 0x20 + #define KISKA_ST_PICTURE 0x30 + #define KISKA_ST_FRAME 0x40 + #define KISKA_ST_BACKGROUND 0x50 + #define KISKA_ST_GROUP_BOX 0x60 + #define KISKA_ST_GROUP_BOX2 0x70 + #define KISKA_ST_HUD_BACKGROUND 0x80 + #define KISKA_ST_TILE_PICTURE 0x90 + #define KISKA_ST_WITH_RECT 0xA0 + #define KISKA_ST_LINE 0xB0 + #define KISKA_ST_UPPERCASE 0xC0 + #define KISKA_ST_LOWERCASE 0xD0 + + #define KISKA_ST_SHADOW 0x100 + #define KISKA_ST_NO_RECT 0x200 + #define KISKA_ST_KEEP_ASPECT_RATIO 0x800 + + // Slider styles + #define KISKA_SL_DIR 0x400 + #define KISKA_SL_VERT 0 + #define KISKA_SL_HORZ 0x400 + + #define KISKA_SL_TEXTURES 0x10 + + // progress bar + #define KISKA_ST_VERTICAL 0x01 + #define KISKA_ST_HORIZONTAL 0 + + // Listbox styles + #define KISKA_LB_TEXTURES 0x10 + #define KISKA_LB_MULTI 0x20 + + // Tree styles + #define KISKA_TR_SHOWROOT 1 + #define KISKA_TR_AUTOCOLLAPSE 2 +#endif \ No newline at end of file diff --git a/KISKA Systems/KISKA Parameter Menu/Headers/params menu.hpp b/KISKA Systems/KISKA Parameter Menu/Headers/params menu.hpp index eeb5722d..e33556ef 100644 --- a/KISKA Systems/KISKA Parameter Menu/Headers/params menu.hpp +++ b/KISKA Systems/KISKA Parameter Menu/Headers/params menu.hpp @@ -1,21 +1,5 @@ #include "params menu common defines.hpp" -/* -import RscText; -import RscButtonMenu; -import RscButton; -import RscCombo; -import RscEdit; -import RscToolbox; -import RscXSliderH; -*/ -import RscListbox; -import RscControlsGroupNoHScrollbars; -import RscControlsGroupNoScrollbars; -import ctrlButtonPicture; -import ctrlButton; - - /* ---------------------------------------------------------------------------- Main Dialog ---------------------------------------------------------------------------- */ diff --git a/KISKA Systems/KISKA View DIstance Limiter/Functions/fn_VDL_addOpenGuiDiaryEntry.sqf b/KISKA Systems/KISKA View DIstance Limiter/Functions/fn_VDL_addOpenGuiDiaryEntry.sqf new file mode 100644 index 00000000..fd0c894f --- /dev/null +++ b/KISKA Systems/KISKA View DIstance Limiter/Functions/fn_VDL_addOpenGuiDiaryEntry.sqf @@ -0,0 +1,49 @@ +/* ---------------------------------------------------------------------------- +Function: KISKA_fnc_VDL_addOpenGuiDiaryEntry + +Description: + Creates a diary entry to open the VDL dialog. + +Parameters: + NONE + +Returns: + NOTHING + +Examples: + (begin example) + PRE-INIT function + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "KISKA_fnc_VDL_addOpenGuiDiaryEntry"; + +if (!hasInterface) exitWith {}; + +if (call KISKA_fnc_isMainMenu) exitWith { + ["Main menu detected, will not init",false] call KISKA_fnc_log; + nil +}; + +if (!canSuspend) exitWith { + ["Must be run in scheduled",false] call KISKA_fnc_log; + [] spawn KISKA_fnc_VDL_addOpenGuiDiaryEntry; +}; + +waitUntil { + if !(isNull player) exitWith {true}; + sleep 0.1; + false +}; + +[ + [ + "View Distance Limiter", + "View Distance Limiter" + ] +] call KISKA_fnc_addKiskaDiaryEntry; + + +nil diff --git a/KISKA Systems/KISKA View DIstance Limiter/Functions/fn_VDL_controlsGroup_onLoad.sqf b/KISKA Systems/KISKA View DIstance Limiter/Functions/fn_VDL_controlsGroup_onLoad.sqf new file mode 100644 index 00000000..689334c4 --- /dev/null +++ b/KISKA Systems/KISKA View DIstance Limiter/Functions/fn_VDL_controlsGroup_onLoad.sqf @@ -0,0 +1,117 @@ +#include "..\Headers\View Distance Limiter Common Defines.hpp" +/* ---------------------------------------------------------------------------- +Function: KISKA_fnc_VDL_controlsGroup_onLoad + +Description: + Acts as the onload event for the KISKA View Distance Limiter Dialog + +Parameters: + 0: _controlsGroup - The controls group for the particular setting + 1: _varName - The name of the profileNamespace variable in which this + setting will be saved when changed + +Returns: + NOTHING + +Examples: + (begin example) + [controlsGroup,"someName"] call KISKA_fnc_VDL_controlsGroup_onLoad; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "KISKA_fnc_VDL_controlsGroup_onLoad"; + +if (!hasInterface) exitWith {}; + +disableSerialization; + +params ["_controlsGroup","_varName"]; + + +_controlsGroup setVariable [CTRL_GRP_VAR_STR,_varName]; + +/* ---------------------------------------------------------------------------- + Slider +---------------------------------------------------------------------------- */ +private _slider_ctrl = _controlsGroup controlsGroupCtrl VDL_SLIDER_IDC; +_controlsGroup setVariable [CTRL_GRP_SLIDER_CTRL_VAR_STR,_slider_ctrl]; +_slider_ctrl ctrlAddEventHandler ["SliderPosChanged",{ + params ["_slider_ctrl", "_newValue"]; + + private _settingControlGroup = ctrlParentControlsGroup _slider_ctrl; + private _editBox_ctrl = _settingControlGroup getVariable CTRL_GRP_EDIT_CTRL_VAR_STR; + + private _strValue = str _newValue; + _editBox_ctrl ctrlSetText _strValue; + _slider_ctrl ctrlSetTooltip _strValue; +}]; + + +/* ---------------------------------------------------------------------------- + Set Button +---------------------------------------------------------------------------- */ +private _setButton_ctrl = _controlsGroup controlsGroupCtrl VDL_SET_BUTTON_IDC; +_setButton_ctrl ctrlAddEventHandler ["ButtonClick",{ + params ["_setButton_ctrl"]; + + private _settingControlGroup = ctrlParentControlsGroup _setButton_ctrl; + private _slider_ctrl = _settingControlGroup getVariable [CTRL_GRP_SLIDER_CTRL_VAR_STR,controlNull]; + + private _varName = _settingControlGroup getVariable CTRL_GRP_VAR_STR; + private _value = sliderPosition _slider_ctrl; + + profileNamespace setVariable [_varName,_value]; + localNamespace setVariable [_varName,_value]; + + saveProfileNamespace; + ["Saved changes"] call KISKA_fnc_notification; +}]; + + +/* ---------------------------------------------------------------------------- + Edit Box +---------------------------------------------------------------------------- */ +private _editBox_ctrl = _controlsGroup controlsGroupCtrl VDL_EDIT_BUTTON_IDC; +_controlsGroup setVariable [CTRL_GRP_EDIT_CTRL_VAR_STR,_editBox_ctrl]; +_editBox_ctrl ctrlAddEventHandler ["KeyUp",{ + params ["_editBox_ctrl"]; + + private _text = ctrlText _editBox_ctrl; + private _number = _text call BIS_fnc_parseNumberSafe; + // if we don't check that an actual number is present, we can't start with a blank edit box if say doing negative numbers + if (str _number == _text) then { + private _settingControlGroup = ctrlParentControlsGroup _editBox_ctrl; + private _slider_ctrl = _settingControlGroup getVariable CTRL_GRP_SLIDER_CTRL_VAR_STR; + + private _sliderRange = sliderRange _slider_ctrl; + private _sliderMin = _sliderRange select 0; + private _sliderMax = _sliderRange select 1; + // check to see if entered number fits inside slider range + if ((_number >= _sliderMin) AND {_number <= _sliderMax}) then { + _slider_ctrl ctrlSetTooltip (str _number); + _slider_ctrl sliderSetPosition _number; + }; + }; +}]; + + + +private _defaultValue = getNumber( + configFile >> + "KISKA_viewDistanceLimiter_dialog" >> + "controls" >> + ctrlClassName _controlsGroup >> + "controls" >> + "settingSlider" >> + "sliderPosition" +); +private _profileValue = profileNamespace getVariable [_varName,_defaultValue]; +private _currentValue = localNamespace getVariable [_varName,_profileValue]; + +_editBox_ctrl ctrlSetText (str _currentValue); +_slider_ctrl sliderSetPosition _currentValue; + + +nil diff --git a/KISKA Systems/KISKA View DIstance Limiter/Functions/fn_VDL_onLoad.sqf b/KISKA Systems/KISKA View DIstance Limiter/Functions/fn_VDL_onLoad.sqf new file mode 100644 index 00000000..611cc3b1 --- /dev/null +++ b/KISKA Systems/KISKA View DIstance Limiter/Functions/fn_VDL_onLoad.sqf @@ -0,0 +1,136 @@ +#include "..\Headers\View Distance Limiter Common Defines.hpp" +/* ---------------------------------------------------------------------------- +Function: KISKA_fnc_VDL_onLoad + +Description: + Acts as the onload event for the KISKA View Distance Limiter Dialog + +Parameters: + 0: _display - The display of the dialog + +Returns: + NOTHING + +Examples: + (begin example) + [display] call KISKA_fnc_VDL_onLoad; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "KISKA_fnc_VDL_onLoad"; + +if (!hasInterface) exitWith {}; + +disableSerialization; + +params ["_display"]; + + +/* ---------------------------------------------------------------------------- + unload event +---------------------------------------------------------------------------- */ +localNamespace setVariable ["KISKA_VDL_display",_display]; +_display displayAddEventHandler ["Unload", { + //params ["_display"]; + localNamespace setVariable ["KISKA_VDL_display",nil]; +}]; + + +/* ---------------------------------------------------------------------------- + System On Check box +---------------------------------------------------------------------------- */ +private _systemOnCheckox = _display displayCtrl VDL_SYSTEM_ON_CHECKBOX_IDC; +if (localNamespace getVariable ["KISKA_VDL_isRunning",false]) then { + _systemOnCheckox cbSetChecked true; +}; + +_systemOnCheckox ctrlAddEventHandler ["CheckedChanged",{ + params ["_control", "_checked"]; + _checked = [false,true] select _checked; + + localNamespace setVariable ["KISKA_VDL_run",_checked]; + private _vdlIsRunning = localNamespace getVariable ["KISKA_VDL_isRunning",false]; + if (_checked AND !_vdlIsRunning) then { + #define GET_SLIDER_POS_FOR_CTRLGRP(idc) sliderPosition (((ctrlParent _control) displayCtrl idc) controlsGroupCtrl VDL_SLIDER_IDC) + [ + GET_SLIDER_POS_FOR_CTRLGRP( VDL_TARGET_FPS_CTRL_GRP_IDC ), + GET_SLIDER_POS_FOR_CTRLGRP( VDL_CHECK_FREQ_CTRL_GRP_IDC ), + GET_SLIDER_POS_FOR_CTRLGRP( VDL_MIN_OBJECT_DIST_CTRL_GRP_IDC ), + GET_SLIDER_POS_FOR_CTRLGRP( VDL_MAX_OBJECT_DIST_CTRL_GRP_IDC ), + GET_SLIDER_POS_FOR_CTRLGRP( VDL_INCRIMENT_CTRL_GRP_IDC ), + GET_SLIDER_POS_FOR_CTRLGRP( VDL_TERRAIN_DIST_CTRL_GRP_IDC ) + ] spawn KISKA_fnc_viewDistanceLimiter; + }; + +}]; + + +/* ---------------------------------------------------------------------------- + Tie View Distance Check box +---------------------------------------------------------------------------- */ +private _tieViewDist_checkBox = _display displayCtrl VDL_TIED_DISTANCE_CHECKBOX_IDC; +if (localNamespace getVariable ["KISKA_VDL_tiedViewDistance",false]) then { + _tieViewDist_checkBox cbSetChecked true; +}; + +_tieViewDist_checkBox ctrlAddEventHandler ["CheckedChanged",{ + params ["", "_checked"]; + _checked = [false,true] select _checked; + localNamespace setVariable ["KISKA_VDL_tiedViewDistance",_checked]; +}]; + + +/* ---------------------------------------------------------------------------- + Close button +---------------------------------------------------------------------------- */ +(_display displayCtrl VDL_CLOSE_BUTTON_IDC) ctrlAddEventHandler ["ButtonClick",{ + (localNamespace getVariable ["KISKA_VDL_display",displayNull]) closeDisplay 2; +}]; + + +/* ---------------------------------------------------------------------------- + Set all button +---------------------------------------------------------------------------- */ +(_display displayCtrl VDL_SET_ALL_BUTTON_IDC) ctrlAddEventHandler ["ButtonClick",{ + params ["_setButton_ctrl"]; + + private _display = localNamespace getVariable ["KISKA_VDL_display",displayNull]; + (_display getVariable "KISKA_VDL_controlGroups") apply { + private _slider_ctrl = _x getVariable [CTRL_GRP_SLIDER_CTRL_VAR_STR,controlNull]; + + private _varName = _x getVariable [CTRL_GRP_VAR_STR,""]; + private _value = sliderPosition _slider_ctrl; + profileNamespace setVariable [_varName,_value]; + localNamespace setVariable [_varName,_value]; + }; + + saveProfileNamespace; + ["Saved All changes"] call KISKA_fnc_notification; +}]; + + +/* ---------------------------------------------------------------------------- + Control groups +---------------------------------------------------------------------------- */ +private _controlGroups = []; +[ + [VDL_TARGET_FPS_CTRL_GRP_IDC, "KISKA_VDL_fps"], + [VDL_MIN_OBJECT_DIST_CTRL_GRP_IDC, "KISKA_VDL_minDist"], + [VDL_MAX_OBJECT_DIST_CTRL_GRP_IDC, "KISKA_VDL_maxDist"], + [VDL_TERRAIN_DIST_CTRL_GRP_IDC, "KISKA_VDL_viewDist"], + [VDL_CHECK_FREQ_CTRL_GRP_IDC, "KISKA_VDL_freq"], + [VDL_INCRIMENT_CTRL_GRP_IDC, "KISKA_VDL_increment"] +] apply { + private _controlIdc = _x select 0; + private _control = _display displayCtrl _controlIdc; + private _settingVariableName = _x select 1; + [_control,_settingVariableName] call KISKA_fnc_VDL_controlsGroup_onLoad; + _controlGroups pushBack _control; +}; + +_display setVariable ["KISKA_VDL_controlGroups",_controlGroups]; + + +nil diff --git a/KISKA Systems/KISKA View DIstance Limiter/Functions/fn_VDL_openDialog.sqf b/KISKA Systems/KISKA View DIstance Limiter/Functions/fn_VDL_openDialog.sqf new file mode 100644 index 00000000..5c4b08b8 --- /dev/null +++ b/KISKA Systems/KISKA View DIstance Limiter/Functions/fn_VDL_openDialog.sqf @@ -0,0 +1,35 @@ +/* ---------------------------------------------------------------------------- +Function: KISKA_fnc_VDL_openDialog + +Description: + Opens the GUI for the VDL system. + +Parameters: + NONE + +Returns: + BOOL + +Examples: + (begin example) + call KISKA_fnc_VDL_openDialog; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "KISKA_fnc_VDL_openDialog"; + +if (!hasInterface) exitWith {false}; + +if !(missionNamespace getVariable ["KISKA_CBA_VDL_available",true]) exitWith { + ["The View Distance Limiter Dialog is not available"] call KISKA_fnc_notification; + false +}; + +if (missionNamespace getVariable ["KISKA_CBA_VDL_closeMap",true]) then { + openMap false; +}; + + +createDialog "KISKA_viewDistanceLimiter_dialog"; diff --git a/KISKA Systems/KISKA View DIstance Limiter/Functions/fn_viewDistanceLimiter.sqf b/KISKA Systems/KISKA View DIstance Limiter/Functions/fn_viewDistanceLimiter.sqf new file mode 100644 index 00000000..865e6231 --- /dev/null +++ b/KISKA Systems/KISKA View DIstance Limiter/Functions/fn_viewDistanceLimiter.sqf @@ -0,0 +1,119 @@ +#include "..\Headers\View Distance Limiter Common Defines.hpp" +/* ---------------------------------------------------------------------------- +Function: KISKA_fnc_viewDistanceLimiter + +Description: + Starts a looping function for limiting a player's viewDistance. + Loop can be stopped by setting mission variable "KISKA_VDL_run" to false. + All other values have global vars that can be edited while it is in use. + + See each param for associated global var. + +Parameters: + 0: _targetFPS - The desired FPS (lower) limit (KISKA_VDL_fps) + 1: _checkFreq - The frequency of checks for FPS (KISKA_VDL_freq) + 2: _minObjectDistance - The minimum the objectViewDistance, can be set by (KISKA_VDL_minDist) + 3: _maxObjectDistance - The max the objectViewDistance, can be set by (KISKA_VDL_maxDist) + 4: _increment - The amount the viewDistance can incriment up or down each cycle (KISKA_VDL_inc) + 5: _viewDistance - This is the static overall viewDistance, can be set by (KISKA_VDL_viewDist) + This is static because it doesn't affect FPS too much. + +Returns: + NOTHING + +Examples: + (begin example) + Every 3 seconds, check + [45,3,500,1700,25,3000] spawn KISKA_fnc_viewDistanceLimiter; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "KISKA_fnc_viewDistanceLimiter"; + +#define DEFAULT_TARGET_FPS 60 +#define DEFAULT_FREQ 0.5 +#define DEFAULT_MIN_DIST 500 +#define DEFAULT_MAX_DIST 1200 +#define DEFAULT_INCREMENT 25 +#define DEFAULT_VIEW_DIST 3000 + +if (!hasInterface) exitWith {}; + +if (!canSuspend) exitWith { + ["Must be run in a scheduled environment. Exiting to scheduled...",true] call KISKA_fnc_log; + _this spawn KISKA_fnc_viewDistanceLimiter +}; + +params [ + ["_targetFPS",localNamespace getVariable ["KISKA_VDL_fps",DEFAULT_TARGET_FPS],[123]], + ["_checkFreq",localNamespace getVariable ["KISKA_VDL_freq",DEFAULT_FREQ],[123]], + ["_minObjectDistance",localNamespace getVariable ["KISKA_VDL_minDist",DEFAULT_MIN_DIST],[123]], + ["_maxObjectDistance",localNamespace getVariable ["KISKA_VDL_maxDist",DEFAULT_MAX_DIST],[123]], + ["_increment",localNamespace getVariable ["KISKA_VDL_increment",DEFAULT_INCREMENT],[123]], + ["_viewDistance",localNamespace getVariable ["KISKA_VDL_viewDist",DEFAULT_VIEW_DIST],[123]] +]; + + +localNamespace setVariable ["KISKA_VDL_run",true]; +localNamespace setVariable ["KISKA_VDL_fps",_targetFPS]; +localNamespace setVariable ["KISKA_VDL_freq",_checkFreq]; +localNamespace setVariable ["KISKA_VDL_increment",_increment]; +if (_minObjectDistance > _maxObjectDistance) then { + _minObjectDistance = _maxObjectDistance; +}; +localNamespace setVariable ["KISKA_VDL_minDist",_minObjectDistance]; +localNamespace setVariable ["KISKA_VDL_maxDist",_maxObjectDistance]; +if (_viewDistance < _maxObjectDistance) then { + _viewDistance = _maxObjectDistance; +}; +localNamespace setVariable ["KISKA_VDL_viewDist",_viewDistance]; + +localNamespace setVariable ["KISKA_VDL_isRunning",true]; +while { + private _adjustmentFrequency = localNamespace getVariable ["KISKA_VDL_freq",DEFAULT_FREQ]; + sleep _adjustmentFrequency; + + localNamespace getVariable ["KISKA_VDL_run",false] +} do { + private _currentObjectViewDistance = getObjectViewDistance select 0; + private _isViewDistanceTied = localNamespace getVariable ["KISKA_VDL_tiedViewDistance",false]; + private _viewDistance = localNamespace getVariable ["KISKA_VDL_viewDist",DEFAULT_VIEW_DIST]; + if ( + (!_isViewDistanceTied) AND + (_viewDistance isNotEqualTo viewDistance) + ) then { + setViewDistance _viewDistance; + }; + + private _targetFPS = localNamespace getVariable ["KISKA_VDL_fps",DEFAULT_TARGET_FPS]; + private _adjustmentIncrement = localNamespace getVariable ["KISKA_VDL_increment",DEFAULT_INCREMENT]; + private _fpsIsHigherThanTarget = diag_fps > _targetFPS; + private "_newViewDistance"; + if (_fpsIsHigherThanTarget) then { + private _maxDistance = localNamespace getVariable ["KISKA_VDL_maxDist",DEFAULT_MAX_DIST]; + _newViewDistance = _currentObjectViewDistance + _adjustmentIncrement; + if (_newViewDistance > _maxDistance) then { + _newViewDistance = _maxDistance; + }; + + } else { + private _minDistance = localNamespace getVariable ["KISKA_VDL_minDist",DEFAULT_MIN_DIST]; + _newViewDistance = _currentObjectViewDistance - _adjustmentIncrement; + if (_newViewDistance < _minDistance) then { + _newViewDistance = _minDistance; + }; + + }; + + if (_newViewDistance == _currentObjectViewDistance) then { continue; }; + if (_isViewDistanceTied) then { + setViewDistance _newViewDistance; + }; + setObjectViewDistance _newViewDistance; +}; + +localNamespace setVariable ["KISKA_VDL_isRunning",false]; +setViewDistance -1; +setObjectViewDistance -1; diff --git a/KISKA Systems/KISKA View DIstance Limiter/Headers/View Distance Limiter Common Defines.hpp b/KISKA Systems/KISKA View DIstance Limiter/Headers/View Distance Limiter Common Defines.hpp new file mode 100644 index 00000000..bf61ebbd --- /dev/null +++ b/KISKA Systems/KISKA View DIstance Limiter/Headers/View Distance Limiter Common Defines.hpp @@ -0,0 +1,20 @@ +#define VDL_SLIDER_IDC 562701 +#define CTRL_GRP_SLIDER_CTRL_VAR_STR "KISKA_VDL_ctrlGrp_slider" + +#define VDL_EDIT_BUTTON_IDC 562702 +#define CTRL_GRP_EDIT_CTRL_VAR_STR "KISKA_VDL_ctrlGrp_editBox" + +#define VDL_SET_BUTTON_IDC 562700 +#define CTRL_GRP_VAR_STR "KISKA_VDL_varName" + +#define VDL_IDD 2154 +#define VDL_CLOSE_BUTTON_IDC 21541 +#define VDL_SET_ALL_BUTTON_IDC 21542 +#define VDL_SYSTEM_ON_CHECKBOX_IDC 21543 +#define VDL_TIED_DISTANCE_CHECKBOX_IDC 21544 +#define VDL_TARGET_FPS_CTRL_GRP_IDC 21545 +#define VDL_MIN_OBJECT_DIST_CTRL_GRP_IDC 21546 +#define VDL_MAX_OBJECT_DIST_CTRL_GRP_IDC 21547 +#define VDL_TERRAIN_DIST_CTRL_GRP_IDC 21548 +#define VDL_CHECK_FREQ_CTRL_GRP_IDC 21549 +#define VDL_INCRIMENT_CTRL_GRP_IDC 215410 diff --git a/KISKA Systems/KISKA View DIstance Limiter/Headers/View Distance Limiter Dialog.hpp b/KISKA Systems/KISKA View DIstance Limiter/Headers/View Distance Limiter Dialog.hpp new file mode 100644 index 00000000..1b1489dc --- /dev/null +++ b/KISKA Systems/KISKA View DIstance Limiter/Headers/View Distance Limiter Dialog.hpp @@ -0,0 +1,316 @@ +#include "View Distance Limiter Common Defines.hpp" +#include "..\..\KISKA Headers\GUI\KISKA GUI Classes.hpp" +#include "..\..\KISKA Headers\GUI\KISKA GUI Grid.hpp" +#include "..\..\KISKA Headers\GUI\KISKA GUI Colors.hpp" +#include "..\..\KISKA Headers\GUI\KISKA GUI Styles.hpp" + +class KISKA_VDL_setting_ctrlGrp: RscControlsGroupNoScrollbars +{ + idc = -1; + + x = KISKA_POS_X(-7.75); + y = KISKA_POS_Y(1); + w = KISKA_POS_W(15.5); + h = KISKA_POS_H(2.5); + class controls + { + class setButton : ctrlButton + { + idc = VDL_SET_BUTTON_IDC; + text = "Button"; + x = KISKA_POS_W(0.75); + y = KISKA_POS_H(0); + w = KISKA_POS_W(10.75); + h = KISKA_POS_H(1); + }; + class settingEditBox: RscEdit + { + idc = VDL_EDIT_BUTTON_IDC; + text = "123"; + x = KISKA_POS_W(11.5); + y = KISKA_POS_H(0); + w = KISKA_POS_W(4); + h = KISKA_POS_H(1); + }; + class settingSlider: RscXSliderH + { + idc = VDL_SLIDER_IDC; + x = KISKA_POS_W(0.75); + y = KISKA_POS_H(1); + w = KISKA_POS_W(14.75); + h = KISKA_POS_H(1); + }; + + }; +}; + + +class KISKA_viewDistanceLimiter_dialog +{ + idd = VDL_IDD; + movingEnabled = 1; + enableSimulation = 1; + onLoad = "[_this select 0] call KISKA_fnc_VDL_onLoad"; + + class controlsBackground + { + class KISKA_VDL_mainFrame: Rsctext + { + idc = -1; + + x = KISKA_POS_X(-7.5); + y = KISKA_POS_Y(-8); + w = KISKA_POS_W(16); + h = KISKA_POS_H(18.5); + colorBackground[] = KISKA_GREY_COLOR(0,0.25); + }; + class KISKA_VDL_mainHeaderText: Rsctext + { + idc = -1; + + moving = 1; + text = "View Distance Limiter"; + x = KISKA_POS_X(-7.5); + y = KISKA_POS_Y(-10); + w = KISKA_POS_W(15); + h = KISKA_POS_H(1); + colorBackground[] = KISKA_PROFILE_BACKGROUND_COLOR(0.65); + style = KISKA_ST_CENTER; + }; + class KISKA_VDL_systemOn_headerText: RscText + { + idc = -1; + + text = "System On:"; + x = KISKA_POS_X(-7.5); + y = KISKA_POS_Y(-9); + w = KISKA_POS_W(3); + h = KISKA_POS_H(1); + colorBackground[] = KISKA_GREY_COLOR(0,1); + sizeEx = KISKA_GUI_TEXT_SIZE(2); + }; + class KISKA_VDL_tiedViewDistance_headerText: RscText + { + idc = -1; + + text = "Tied View Distance:"; + x = KISKA_POS_X(2.5); + y = KISKA_POS_Y(-9); + w = KISKA_POS_W(5); + h = KISKA_POS_H(1); + colorBackground[] = KISKA_GREY_COLOR(0,1); + sizeEx = KISKA_GUI_TEXT_SIZE(2); + }; + }; + + class controls + { + /* ------------------------------------------------------------------------- + General Controls + ------------------------------------------------------------------------- */ + class KISKA_VDL_close_button: KISKA_RscCloseButton + { + idc = VDL_CLOSE_BUTTON_IDC; + x = KISKA_POS_X(7.5); + y = KISKA_POS_Y(-10); + w = KISKA_POS_W(1); + h = KISKA_POS_H(1); + }; + class KISKA_VDL_setAll_button: ctrlButton + { + idc = VDL_SET_ALL_BUTTON_IDC; + + text = "Set All Changes"; + x = KISKA_POS_X(-3.5); + y = KISKA_POS_Y(-9); + w = KISKA_POS_W(6); + h = KISKA_POS_H(1); + sizeEx = KISKA_GUI_TEXT_SIZE(2); + }; + class KISKA_VDL_systemOn_checkBox: RscCheckBox + { + idc = VDL_SYSTEM_ON_CHECKBOX_IDC; + + x = KISKA_POS_X(-4.5); + y = KISKA_POS_Y(-9); + w = KISKA_POS_W(1); + h = KISKA_POS_H(1); + colorText[] = KISKA_GREY_COLOR(0,1); + colorActive[] = KISKA_GREY_COLOR(0,1); + }; + class KISKA_VDL_tiedViewDistance_checkBox: RscCheckBox + { + idc = VDL_TIED_DISTANCE_CHECKBOX_IDC; + + x = KISKA_POS_X(7.5); + y = KISKA_POS_Y(-9); + w = KISKA_POS_W(1); + h = KISKA_POS_H(1); + colorText[] = KISKA_GREY_COLOR(0,1); + colorActive[] = KISKA_GREY_COLOR(0,1); + + tooltip = "A tied view distance will make the terrain view distance be the same as and follow the dynamic adjustments of the object view distance"; + }; + + /* ------------------------------------------------------------------------- + Target FPS + ------------------------------------------------------------------------- */ + class KISKA_VDL_targetFPS_ctrlGrp: KISKA_VDL_setting_ctrlGrp + { + idc = VDL_TARGET_FPS_CTRL_GRP_IDC; + y = KISKA_POS_Y(-7.5); + + class controls : controls + { + class setButton: setButton + { + text = "Set Target FPS"; + tooltip = "The FPS that you want to achieve to have while the system is running"; + }; + class settingSlider: settingSlider + { + sliderPosition = 60; + sliderRange[] = {15,300}; + sliderStep = 1; + lineSize = 1; + }; + class settingEditBox: settingEditBox + { + }; + }; + }; + + /* ------------------------------------------------------------------------- + Min Obj View Distance + ------------------------------------------------------------------------- */ + class KISKA_VDL_minObjectDist_ctrlGrp: KISKA_VDL_setting_ctrlGrp + { + idc = VDL_MIN_OBJECT_DIST_CTRL_GRP_IDC; + + y = KISKA_POS_Y(-4.5); + + class controls : controls + { + class setButton: setButton + { + text = "Set Min Object Distance"; + tooltip = "The minimum distance your Object View Distance can be set to"; + }; + class settingSlider: settingSlider + { + sliderPosition = 500; + sliderRange[] = {100,3000}; + sliderStep = 1; + lineSize = 10; + }; + class settingEditBox: settingEditBox + { + }; + }; + }; + + /* ------------------------------------------------------------------------- + Max Obj View Distance + ------------------------------------------------------------------------- */ + class KISKA_VDL_maxObjectDist_ctrlGrp: KISKA_VDL_minObjectDist_ctrlGrp + { + idc = VDL_MAX_OBJECT_DIST_CTRL_GRP_IDC; + y = KISKA_POS_Y(-1.5); + + class controls : controls + { + class setButton: setButton + { + text = "Set Max Object Distance"; + tooltip = "The maximum distance your Object View Distance can be set to"; + }; + class settingSlider: settingSlider + { + }; + class settingEditBox: settingEditBox + { + }; + }; + }; + + /* ------------------------------------------------------------------------- + Terrain View Distance + ------------------------------------------------------------------------- */ + class KISKA_VDL_terrainDist_ctrlGrp: KISKA_VDL_minObjectDist_ctrlGrp + { + idc = VDL_TERRAIN_DIST_CTRL_GRP_IDC; + + y = KISKA_POS_Y(1.5); + class controls : controls + { + class setButton: setButton + { + text = "Set Terrain View Distance"; + tooltip = "The overall (static) view distance; this can be rather high without an issue."; + }; + class settingSlider: settingSlider + { + }; + class settingEditBox: settingEditBox + { + }; + }; + }; + + /* ------------------------------------------------------------------------- + Check Frequency + ------------------------------------------------------------------------- */ + class KISKA_VDL_checkFreq_ctrlGrp: KISKA_VDL_setting_ctrlGrp + { + idc = VDL_CHECK_FREQ_CTRL_GRP_IDC; + y = KISKA_POS_Y(4.5); + class controls : controls + { + class setButton: setButton + { + text = "Set Check Frequency"; + tooltip = "This is how often the view distance will be adjusted in seconds"; + }; + class settingSlider: settingSlider + { + sliderPosition = 1; + sliderRange[] = {0.01,10}; + sliderStep = 0.01; + lineSize = 0.05; + }; + class settingEditBox: settingEditBox + { + }; + }; + }; + + /* ------------------------------------------------------------------------- + Increment Size + ------------------------------------------------------------------------- */ + class KISKA_VDL_incriment_ctrlGrp: KISKA_VDL_setting_ctrlGrp + { + idc = VDL_INCRIMENT_CTRL_GRP_IDC; + y = KISKA_POS_Y(7.5); + + class controls : controls + { + class setButton: setButton + { + text = "Set Increment Size"; + tooltip = "By how much will the view distance be adjusted in meters to achieve the target FPS each check frequency?"; + }; + class settingSlider: settingSlider + { + sliderPosition = 25; + sliderRange[] = {1,500}; + sliderStep = 5; + lineSize = 10; + }; + class settingEditBox: settingEditBox + { + }; + }; + }; + + }; +}; diff --git a/KISKA Systems/KISKA View DIstance Limiter/Headers/View Distance Limiter Functions.hpp b/KISKA Systems/KISKA View DIstance Limiter/Headers/View Distance Limiter Functions.hpp new file mode 100644 index 00000000..c937666f --- /dev/null +++ b/KISKA Systems/KISKA View DIstance Limiter/Headers/View Distance Limiter Functions.hpp @@ -0,0 +1,16 @@ +class KISKA_ViewDistanceLimiter +{ + file="KISKA Systems\KISKA View Distance Limiter\Functions"; + class VDL_addOpenGuiDiaryEntry + { + preinit = 1; + }; + class VDL_controlsGroup_onLoad + {}; + class VDL_onLoad + {}; + class VDL_openDialog + {}; + class viewDistanceLimiter + {}; +}; \ No newline at end of file diff --git a/KISKA Systems/View Distance Limiter/Functions/fn_addOpenVdlGuiDiary.sqf b/KISKA Systems/View Distance Limiter/Functions/fn_addOpenVdlGuiDiary.sqf deleted file mode 100644 index bab459f9..00000000 --- a/KISKA Systems/View Distance Limiter/Functions/fn_addOpenVdlGuiDiary.sqf +++ /dev/null @@ -1,37 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: KISKA_fnc_addOpenVdlGuiDiary - -Description: - Creates a diary entry to open the VDL dialog. - -Parameters: - NONE - -Returns: - NOTHING - -Examples: - (begin example) - Postinit function - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -if (!hasInterface) exitWith {}; - -waitUntil { - if !(isNull player) exitWith {true}; - sleep 0.1; - false -}; - -[ - [ - "View Distance Limiter", - "OPEN VDL DIALOG" - ] -] call BLWK_fnc_addSurvivalDiaryEntry; - - -nil diff --git a/KISKA Systems/View Distance Limiter/Functions/fn_adjustVdlControls.sqf b/KISKA Systems/View Distance Limiter/Functions/fn_adjustVdlControls.sqf deleted file mode 100644 index 150669fe..00000000 --- a/KISKA Systems/View Distance Limiter/Functions/fn_adjustVdlControls.sqf +++ /dev/null @@ -1,51 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: KISKA_fnc_adjustVdlControls - -Description: - Used to adjust the partnered field for the GUI. - e.g. if you change a value with the slider, it adjusts the edit box's' number - and vice-versa - -Parameters: - 0: _control - The control that triggered the event - 1: _value - Slider position value used to set the text inside an edit box - -Returns: - NOTHING - -Examples: - (begin example) - - [myControl,20] call KISKA_fnc_adjustVdlControls; - - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -disableSerialization; -if (!hasInterface) exitWith {}; - -#include "..\controlTypes.hpp" - -params ["_control","_value"]; - -private _controlType = ctrlType _control; - -if (_controlType isEqualTo CT_EDIT) exitWith { - private _text = ctrlText _control; - private _number = ([_text] call BIS_fnc_parseNumberSafe) select 0; - if !(_number isEqualTo 0) then { - private _partnerControl = [_control] call KISKA_fnc_findVDLPartnerControl; - - // check to see if entered number fits inside slider range - private _sliderRange = sliderRange _partnerControl; - if ((_number >= (_sliderRange select 0)) AND {_number <= (_sliderRange select 1)}) then { - _partnerControl sliderSetPosition _number; - }; - }; -}; -if (_controlType isEqualTo CT_SLIDER OR {_controlType isEqualTo CT_XSLIDER}) exitWith { - private _partnerControl = [_control] call KISKA_fnc_findVDLPartnerControl; - _partnerControl ctrlSetText (str _value); -}; \ No newline at end of file diff --git a/KISKA Systems/View Distance Limiter/Functions/fn_findVdlPartnerControl.sqf b/KISKA Systems/View Distance Limiter/Functions/fn_findVdlPartnerControl.sqf deleted file mode 100644 index 8bfe7065..00000000 --- a/KISKA Systems/View Distance Limiter/Functions/fn_findVdlPartnerControl.sqf +++ /dev/null @@ -1,65 +0,0 @@ -#include "..\ViewDistanceLimiterCommonDefines.hpp" -/* ---------------------------------------------------------------------------- -Function: KISKA_fnc_findVdlPartnerControl - -Description: - Used to find tied together constants for controls so that they can be adjust simaltaneously. - -Parameters: - 0: _controlIDC - The control with which you are searching for its partner - -Returns: - - -Examples: - (begin example) - _partnerControl = [myControl] call KISKA_fnc_adjustVdlControls; - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -disableSerialization; -if (!hasInterface) exitWith {}; - -#define CONTROL(IDC) (findDisplay VIEW_DISTANCE_LIMITER_DIALOG_IDD) displayCtrl IDC - -params [ - ["_controlIDC",controlNull,[controlNull,123]] -]; -if (_controlIDC isEqualType controlNull) then { - _controlIDC = ctrlIDC _controlIDC; -}; - -// FPS -if (_controlIDC isEqualTo VDL_FPS_SLIDER_IDC) exitWith {CONTROL(VDL_FPS_TEXT_EDIT_IDC)}; -if (_controlIDC isEqualTo VDL_FPS_TEXT_EDIT_IDC OR {_controlIDC isEqualTo VDL_SET_FPS_BUTTON_IDC}) exitWith {CONTROL(VDL_FPS_SLIDER_IDC)}; -// Freq -if (_controlIDC isEqualTo VDL_FREQ_SLIDER_IDC) exitWith {CONTROL(VDL_FREQ_TEXT_EDIT_IDC)}; -if (_controlIDC isEqualTo VDL_FREQ_TEXT_EDIT_IDC OR {_controlIDC isEqualTo VDL_SET_FREQ_BUTTON_IDC}) exitWith {CONTROL(VDL_FREQ_SLIDER_IDC)}; -// Min Obj Dist -if (_controlIDC isEqualTo VDL_MIN_OBJ_DIST_SLIDER_IDC) exitWith {CONTROL(VDL_MIN_OBJ_DIST_TEXT_EDIT_IDC)}; -if (_controlIDC isEqualTo VDL_MIN_OBJ_DIST_TEXT_EDIT_IDC OR {_controlIDC isEqualTo VDL_MIN_OBJ_DIST_BUTTON_IDC}) exitWith {CONTROL(VDL_MIN_OBJ_DIST_SLIDER_IDC)}; -// Max Obj Dist -if (_controlIDC isEqualTo VDL_MAX_OBJ_DIST_SLIDER_IDC) exitWith {CONTROL(VDL_MAX_OBJ_DIST_TEXT_EDIT_IDC)}; -if (_controlIDC isEqualTo VDL_MAX_OBJ_DIST_TEXT_EDIT_IDC OR {_controlIDC isEqualTo VDL_MAX_OBJ_DIST_BUTTON_IDC}) exitWith {CONTROL(VDL_MAX_OBJ_DIST_SLIDER_IDC)}; -// Increment -if (_controlIDC isEqualTo VDL_INCREMENT_SLIDER_IDC) exitWith {CONTROL(VDL_INCREMENT_TEXT_EDIT_IDC)}; -if (_controlIDC isEqualTo VDL_INCREMENT_TEXT_EDIT_IDC OR {_controlIDC isEqualTo VDL_INCREMENT_BUTTON_IDC}) exitWith {CONTROL(VDL_INCREMENT_SLIDER_IDC)}; -// Terrain -if (_controlIDC isEqualTo VDL_TERRAIN_SLIDER_IDC) exitWith {CONTROL(VDL_TERRAIN_TEXT_EDIT_IDC)}; -if (_controlIDC isEqualTo VDL_TERRAIN_TEXT_EDIT_IDC OR {_controlIDC isEqualTo VDL_TERRAIN_BUTTON_IDC}) exitWith {CONTROL(VDL_TERRAIN_SLIDER_IDC)}; - -// set all -if (_controlIDC isEqualTo VDL_SET_ALL_BUTTON_IDC) exitWith { - [ - CONTROL(VDL_TERRAIN_SLIDER_IDC), - CONTROL(VDL_INCREMENT_SLIDER_IDC), - CONTROL(VDL_MAX_OBJ_DIST_SLIDER_IDC), - CONTROL(VDL_MIN_OBJ_DIST_SLIDER_IDC), - CONTROL(VDL_FREQ_SLIDER_IDC), - CONTROL(VDL_FPS_SLIDER_IDC) - ] -}; - -controlNull \ No newline at end of file diff --git a/KISKA Systems/View Distance Limiter/Functions/fn_handleVdlDialogOpen.sqf b/KISKA Systems/View Distance Limiter/Functions/fn_handleVdlDialogOpen.sqf deleted file mode 100644 index 436ac494..00000000 --- a/KISKA Systems/View Distance Limiter/Functions/fn_handleVdlDialogOpen.sqf +++ /dev/null @@ -1,86 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: KISKA_fnc_handleVdlDialogOpen - -Description: - Handles the openning of the View Distance Limiter dialog to maker sure that - all the values shown are up to date with the globals. - - It is executed from the dialog's onLoad eventhandler in config. - -Parameters: - 0: _display - The display to the GUI - -Returns: - NOTHING - -Examples: - (begin example) - [displayNumber] call KISKA_fnc_handleVdlDialogOpen; - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -disableSerialization; -if (!hasInterface) exitWith {}; - -#include "..\ViewDistanceLimiterCommonDefines.hpp" - -params ["_display"]; - -private _controls = allControls _display; -private _fn_checkControl = { - private _controlIDCTemp = ctrlIDC _controlTemp; - - if (_controlIDCTemp isEqualTo VDL_SYSTEM_ON_CHECKBOX_IDC) exitWith { - if (call KISKA_fnc_isVDLSystemRunning) then {_controlTemp cbSetChecked true}; - }; - // fps - if (_controlIDCTemp isEqualTo VDL_FPS_TEXT_EDIT_IDC) exitWith { - _controlTemp ctrlSetText str (missionNamespace getVariable [VDL_GLOBAL_FPS_STR,60]); - }; - if (_controlIDCTemp isEqualTo VDL_FPS_SLIDER_IDC) exitWith { - _controlTemp sliderSetPosition (missionNamespace getVariable [VDL_GLOBAL_FPS_STR,60]); - }; - // check Freq - if (_controlIDCTemp isEqualTo VDL_FREQ_TEXT_EDIT_IDC) exitWith { - _controlTemp ctrlSetText str (missionNamespace getVariable [VDL_GLOBAL_FREQ_STR,3]); - }; - if (_controlIDCTemp isEqualTo VDL_FREQ_SLIDER_IDC) exitWith { - _controlTemp sliderSetPosition (missionNamespace getVariable [VDL_GLOBAL_FREQ_STR,3]); - }; - // Min Obj Dist - if (_controlIDCTemp isEqualTo VDL_MIN_OBJ_DIST_TEXT_EDIT_IDC) exitWith { - _controlTemp ctrlSetText str (missionNamespace getVariable [VDL_GLOBAL_MIN_DIST_STR,500]); - }; - if (_controlIDCTemp isEqualTo VDL_MIN_OBJ_DIST_SLIDER_IDC) exitWith { - _controlTemp sliderSetPosition (missionNamespace getVariable [VDL_GLOBAL_MIN_DIST_STR,500]); - }; - // Max Obj Dist - if (_controlIDCTemp isEqualTo VDL_MAX_OBJ_DIST_TEXT_EDIT_IDC) exitWith { - _controlTemp ctrlSetText str (missionNamespace getVariable [VDL_GLOBAL_MAX_DIST_STR,1700]); - }; - if (_controlIDCTemp isEqualTo VDL_MAX_OBJ_DIST_SLIDER_IDC) exitWith { - _controlTemp sliderSetPosition (missionNamespace getVariable [VDL_GLOBAL_MAX_DIST_STR,1700]); - }; - // Increment - if (_controlIDCTemp isEqualTo VDL_INCREMENT_TEXT_EDIT_IDC) exitWith { - _controlTemp ctrlSetText str (missionNamespace getVariable [VDL_GLOBAL_INC_STR,25]); - }; - if (_controlIDCTemp isEqualTo VDL_INCREMENT_SLIDER_IDC) exitWith { - _controlTemp sliderSetPosition (missionNamespace getVariable [VDL_GLOBAL_INC_STR,25]); - }; - // terrain - if (_controlIDCTemp isEqualTo VDL_TERRAIN_TEXT_EDIT_IDC) exitWith { - _controlTemp ctrlSetText str (missionNamespace getVariable [VDL_GLOBAL_VIEW_DIST_STR,viewDistance]); - }; - if (_controlIDCTemp isEqualTo VDL_TERRAIN_SLIDER_IDC) exitWith { - _controlTemp sliderSetPosition (missionNamespace getVariable [VDL_GLOBAL_VIEW_DIST_STR,viewDistance]); - }; -}; - -private ["_controlTemp","_controlIDCTemp"]; -_controls apply { - _controlTemp = _x; - call _fn_checkControl; -}; \ No newline at end of file diff --git a/KISKA Systems/View Distance Limiter/Functions/fn_handleVdlGuiCheckbox.sqf b/KISKA Systems/View Distance Limiter/Functions/fn_handleVdlGuiCheckbox.sqf deleted file mode 100644 index 665a6b02..00000000 --- a/KISKA Systems/View Distance Limiter/Functions/fn_handleVdlGuiCheckbox.sqf +++ /dev/null @@ -1,44 +0,0 @@ -#include "..\ViewDistanceLimiterCommonDefines.hpp" -/* ---------------------------------------------------------------------------- -Function: KISKA_fnc_handleVdlGuiCheckbox - -Description: - Acts as an event when the box is checked or unchecked in the VDL GUI. - It will either start the system or end it. - -Parameters: - 0: _control - The conrol of the box - 1: _checked - Is the box checked? - -Returns: - BOOL - -Examples: - (begin example) - // from onCheckedChanged event in config - _this call KISKA_fnc_handleVdlGuiCheckbox - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -disableSerialization; -if (!hasInterface) exitWith {}; - -params ["_control","_checked"]; - -// turn number into bool -_checked = [false,true] select _checked; - -if (_checked) then { - if !(call KISKA_fnc_isVDLSystemRunning) then { - [] spawn KISKA_fnc_viewDistanceLimiter; - hint "VDL system starting..."; - } else { - VDL_GLOBAL_RUN = true; - hint "VDL system resuming..."; - }; -} else { - VDL_GLOBAL_RUN = false; - hint "VDL system turning off..."; -}; \ No newline at end of file diff --git a/KISKA Systems/View Distance Limiter/Functions/fn_isVdlSystemRunning.sqf b/KISKA Systems/View Distance Limiter/Functions/fn_isVdlSystemRunning.sqf deleted file mode 100644 index 976bcc51..00000000 --- a/KISKA Systems/View Distance Limiter/Functions/fn_isVdlSystemRunning.sqf +++ /dev/null @@ -1,29 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: KISKA_fnc_isVdlSystemRunning - -Description: - Checks to see whether the global var that controls the VDL loop is currently - true. - -Parameters: - NONE - -Returns: - BOOL - -Examples: - (begin example) - _isSystemRunning = call KISKA_fnc_isVdlSystemRunning; - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -disableSerialization; -if (!hasInterface) exitWith {false}; - -#include "..\ViewDistanceLimiterCommonDefines.hpp" - -private _isRunning = missionNamespace getVariable [VDL_GLOBAL_RUN_STR,false]; - -_isRunning \ No newline at end of file diff --git a/KISKA Systems/View Distance Limiter/Functions/fn_openVdlDialog.sqf b/KISKA Systems/View Distance Limiter/Functions/fn_openVdlDialog.sqf deleted file mode 100644 index 1a2b42c7..00000000 --- a/KISKA Systems/View Distance Limiter/Functions/fn_openVdlDialog.sqf +++ /dev/null @@ -1,26 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: KISKA_fnc_openVdlDialog - -Description: - Opens the GUI for the VDL system. - -Parameters: - NONE - -Returns: - BOOL - -Examples: - (begin example) - call KISKA_fnc_openVdlDialog; - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -disableSerialization; -if (!hasInterface) exitWith {false}; - -#include "..\ViewDistanceLimiterCommonDefines.hpp" - -createDialog VIEW_DISTANCE_LIMITER_DIALOG_STR; \ No newline at end of file diff --git a/KISKA Systems/View Distance Limiter/Functions/fn_setAllVdlButton.sqf b/KISKA Systems/View Distance Limiter/Functions/fn_setAllVdlButton.sqf deleted file mode 100644 index be194687..00000000 --- a/KISKA Systems/View Distance Limiter/Functions/fn_setAllVdlButton.sqf +++ /dev/null @@ -1,32 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: KISKA_fnc_setAllVdlButton - -Description: - Saves all the current values input to the VDL GUI. - -Parameters: - 0: _control - The control of the set all button - -Returns: - NOTHING - -Examples: - (begin example) - // used in onButtonClick eventhandler in config - _this call KISKA_fnc_setAllVdlButton; - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -disableSerialization; -if (!hasInterface) exitWith {}; - -params ["_control"]; -private _partnerControls = [_control] call KISKA_fnc_findVDLPartnerControl; - -_partnerControls apply { - [_x] call KISKA_fnc_setVDLValue; -}; - -hint "All changes applied"; \ No newline at end of file diff --git a/KISKA Systems/View Distance Limiter/Functions/fn_setVdlValue.sqf b/KISKA Systems/View Distance Limiter/Functions/fn_setVdlValue.sqf deleted file mode 100644 index ff592e63..00000000 --- a/KISKA Systems/View Distance Limiter/Functions/fn_setVdlValue.sqf +++ /dev/null @@ -1,62 +0,0 @@ -#include "..\controlTypes.hpp" -#include "..\ViewDistanceLimiterCommonDefines.hpp" -/* ---------------------------------------------------------------------------- -Function: KISKA_fnc_setAllVdlButton - -Description: - Takes the provided control's value and saves it to the corresponding global - variable. - -Parameters: - 0: _controlToRead - The control to get the value to save from - -Returns: - NOTHING - -Examples: - (begin example) - [_controlToRead] call KISKA_fnc_setVdlValue; - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -disableSerialization; -if (!hasInterface) exitWith {}; - -params [ - ["_controlToRead",controlNull,[controlNull]] -]; - -private _controlType = ctrlType _controlToRead; -if (!(_controlType isEqualTo CT_SLIDER) AND {!(_controlType isEqualTo CT_XSLIDER)}) then { - _controlToRead = [_controlToRead] call KISKA_fnc_findVDLPartnerControl; -}; - -private _sliderPosition = sliderPosition _controlToRead; -private _sliderPositionString = str _sliderPosition; -private _controlIDC = ctrlIDC _controlToRead; -if (_controlIDC isEqualTo VDL_FPS_SLIDER_IDC) exitWith { - VDL_GLOBAL_FPS = _sliderPosition; - hint (["Target FPS is now:",_sliderPositionString] joinString " "); -}; -if (_controlIDC isEqualTo VDL_FREQ_SLIDER_IDC) exitWith { - VDL_GLOBAL_FREQ = _sliderPosition; - hint (["Frequency of checks is now:",_sliderPositionString] joinString " "); -}; -if (_controlIDC isEqualTo VDL_MIN_OBJ_DIST_SLIDER_IDC) exitWith { - VDL_GLOBAL_MIN_DIST = _sliderPosition; - hint (["Minimum object view distance is now:",_sliderPositionString] joinString " "); -}; -if (_controlIDC isEqualTo VDL_MAX_OBJ_DIST_SLIDER_IDC) exitWith { - VDL_GLOBAL_MAX_DIST = _sliderPosition; - hint (["Maximum object view distance is now:",_sliderPositionString] joinString " "); -}; -if (_controlIDC isEqualTo VDL_INCREMENT_SLIDER_IDC) exitWith { - VDL_GLOBAL_INC = _sliderPosition; - hint (["The increment of view distance is now:",_sliderPositionString] joinString " "); -}; -if (_controlIDC isEqualTo VDL_TERRAIN_SLIDER_IDC) exitWith { - VDL_GLOBAL_VIEW_DIST = _sliderPosition; - hint (["Your overall view distance is now:",_sliderPositionString] joinString " "); -}; \ No newline at end of file diff --git a/KISKA Systems/View Distance Limiter/Functions/fn_viewDistanceLimiter.sqf b/KISKA Systems/View Distance Limiter/Functions/fn_viewDistanceLimiter.sqf deleted file mode 100644 index 09e6be2d..00000000 --- a/KISKA Systems/View Distance Limiter/Functions/fn_viewDistanceLimiter.sqf +++ /dev/null @@ -1,90 +0,0 @@ -/* ---------------------------------------------------------------------------- -Function: KISKA_fnc_viewDistanceLimiter - -Description: - Starts a looping function for limiting a player's viewDistance. - Loop can be stopped by setting mission variable "KISKA_VDL_run" to false. - All other values have global vars that can be edited while it is in use. - - See each param for associated global var. - -Parameters: - - 0: _targetFPS - The desired FPS (lower) limit (KISKA_VDL_fps) - 1: _checkFreq - The frequency of checks for FPS (KISKA_VDL_freq) - 2: _minObjectDistance - The minimum the objectViewDistance, can be set by (KISKA_VDL_minDist) - 3: _maxObjectDistance - The max the objectViewDistance, can be set by (KISKA_VDL_maxDist) - 4: _increment - The amount the viewDistance can incriment up or down each cycle (KISKA_VDL_inc) - 5: _viewDistance - This is the static overall viewDistance, can be set by (KISKA_VDL_viewDist) - This is static because it doesn't affect FPS too much. - -Returns: - NOTHING - -Examples: - (begin example) - - Every 3 seconds, check - [45,3,500,1700,3000,25] spawn KISKA_fnc_viewDistanceLimiter; - - (end) - -Author(s): - Ansible2 // Cipher ----------------------------------------------------------------------------- */ -if (!hasInterface OR {!canSuspend}) exitWith { - "Must be run in scheduled environment." call BIS_fnc_error; -}; - -#include "..\ViewDistanceLimiterCommonDefines.hpp" - -params [ - ["_targetFPS",missionNamespace getVariable [VDL_GLOBAL_FPS_STR,60],[123]], - ["_checkFreq",missionNamespace getVariable [VDL_GLOBAL_FREQ_STR,3],[123]], - ["_minObjectDistance",missionNamespace getVariable [VDL_GLOBAL_MIN_DIST_STR,500],[123]], - ["_maxObjectDistance",missionNamespace getVariable [VDL_GLOBAL_MAX_DIST_STR,1700],[123]], - ["_increment",missionNamespace getVariable [VDL_GLOBAL_INC_STR,25],[123]], - ["_viewDistance",missionNamespace getVariable [VDL_GLOBAL_VIEW_DIST_STR,3000],[123]] -]; - -VDL_GLOBAL_RUN = true; -VDL_GLOBAL_FPS = _targetFPS; -VDL_GLOBAL_FREQ = _checkFreq; -VDL_GLOBAL_MIN_DIST = _minObjectDistance; -VDL_GLOBAL_MAX_DIST = _maxObjectDistance; -VDL_GLOBAL_VIEW_DIST = _viewDistance; -VDL_GLOBAL_INC = _increment; - -private "_objectViewDistance"; -private _fn_moveUp = { - if (_objectViewDistance < VDL_GLOBAL_MAX_DIST) exitWith { - setObjectViewDistance (_objectViewDistance + VDL_GLOBAL_INC); - }; - if (_objectViewDistance > VDL_GLOBAL_MAX_DIST) exitWith { - setObjectViewDistance VDL_GLOBAL_MAX_DIST; - }; -}; -private _fn_moveDown = { - if (_objectViewDistance > VDL_GLOBAL_MIN_DIST) exitWith { - setObjectViewDistance (_objectViewDistance - VDL_GLOBAL_INC); - }; - if (_objectViewDistance < VDL_GLOBAL_MIN_DIST) exitWith { - setObjectViewDistance VDL_GLOBAL_MIN_DIST; - }; -}; -while {sleep VDL_GLOBAL_FREQ; VDL_GLOBAL_RUN} do { - _objectViewDistance = getObjectViewDistance select 0; - - if (VDL_GLOBAL_VIEW_DIST != viewDistance) then { - setViewDistance VDL_GLOBAL_VIEW_DIST; - }; - - // is fps at target? - if (diag_fps < VDL_GLOBAL_FPS) then { - // not at target fps - call _fn_moveDown; - } else { - // at target fps - call _fn_moveUp; - }; -}; \ No newline at end of file diff --git a/KISKA Systems/View Distance Limiter/ViewDistanceLimiterDialog.hpp b/KISKA Systems/View Distance Limiter/ViewDistanceLimiterDialog.hpp deleted file mode 100644 index d97b711e..00000000 --- a/KISKA Systems/View Distance Limiter/ViewDistanceLimiterDialog.hpp +++ /dev/null @@ -1,320 +0,0 @@ -#include "viewDistanceLimiterBases.hpp" - -class VIEW_DISTANCE_LIMITER_DIALOG -{ - idd = VIEW_DISTANCE_LIMITER_DIALOG_IDD; - movingEnabled = true; - enableSimulation = true; - onLoad = "[_this select 0] call KISKA_fnc_handleVDLDialogOpen"; - onUnload = "hintSilent ''"; - - class controls - { - /* ------------------------------------------------------------------------- - General Controls - ------------------------------------------------------------------------- */ - class VDL_FRAME: VDL_RSC_FRAME_BASE - { - idc = VDL_FRAME_IDC; - - x = 0.699219 * safezoneW + safezoneX; - y = 0.260417 * safezoneH + safezoneY; - w = 0.140625 * safezoneW; - h = 0.458333 * safezoneH; - }; - class VDL_HEADER_TEXT: VDL_RSC_TEXT_BASE - { - idc = VDL_HEADER_TEXT_IDC; - - text = "VIEW DISTANCE LIMITER"; //--- ToDo: Localize; - x = 0.699219 * safezoneW + safezoneX; - y = 0.260417 * safezoneH + safezoneY; - w = 0.140625 * safezoneW; - h = 0.0208333 * safezoneH; - colorBackground[] = PROFILE_BACKGROUND_COLOR(0.65); - style = ST_CENTER; - sizeEx = 0.0208333 * safezoneH; - }; - class VDL_CLOSE_DIALOG_BUTTON: VDL_RSC_BUTTON_BASE - { - idc = VDL_CLOSE_DIALOG_BUTTON_IDC; - - text = "Close Interface"; //--- ToDo: Localize; - x = 0.757813 * safezoneW + safezoneX; - y = 0.28125 * safezoneH + safezoneY; - w = 0.0820313 * safezoneW; - h = 0.0208333 * safezoneH; - onMouseButtonClick = "closeDialog 2"; - sizeEx = 0.0208333 * safezoneH; - }; - class VDL_SET_ALL_BUTTON: VDL_RSC_BUTTON_BASE - { - idc = VDL_SET_ALL_BUTTON_IDC; - - text = "Set All Changes"; //--- ToDo: Localize; - x = 0.699219 * safezoneW + safezoneX; - y = 0.6875 * safezoneH + safezoneY; - w = 0.140625 * safezoneW; - h = 0.03125 * safezoneH; - onButtonClick = "_this call KISKA_fnc_setAllVDLButton"; - sizeEx = 0.03125 * safezoneH; - }; - class VDL_SYSTEM_ON_CHECKBOX: VDL_RSC_CHECKBOX_BASE - { - idc = VDL_SYSTEM_ON_CHECKBOX_IDC; - - x = 0.746094 * safezoneW + safezoneX; - y = 0.28125 * safezoneH + safezoneY; - w = 0.0117188 * safezoneW; - h = 0.0208333 * safezoneH; - colorText[] = {-1,-1,-1,1}; - colorActive[] = {-1,-1,-1,1}; - onCheckedChanged = "_this call KISKA_fnc_handleVdlGUICheckBox"; - onload = "(_this select 0) cbSetChecked (call KISKA_fnc_isVDLSystemRunning);"; - }; - class VDL_SYSTEM_ON_TEXT: VDL_RSC_TEXT_BASE - { - idc = VDL_SYSTEM_ON_TEXT_IDC; - - text = "System On:"; //--- ToDo: Localize; - x = 0.699219 * safezoneW + safezoneX; - y = 0.28125 * safezoneH + safezoneY; - w = 0.046875 * safezoneW; - h = 0.0208333 * safezoneH; - colorBackground[] = {-1,-1,-1,1}; - sizeEx = 0.0208333 * safezoneH; - }; - /* ------------------------------------------------------------------------- - Target FPS - ------------------------------------------------------------------------- */ - class VDL_SET_FPS_BUTTON: VDL_RSC_BUTTON_BASE - { - idc = VDL_SET_FPS_BUTTON_IDC; - - text = "Set FPS Target"; //--- ToDo: Localize; - x = 0.699219 * safezoneW + safezoneX; - y = 0.3125 * safezoneH + safezoneY; - w = 0.140625 * safezoneW; - h = 0.0208333 * safezoneH; - sizeEx = 0.0208333 * safezoneH; - }; - class VDL_FPS_TEXT_EDIT: VDL_RSC_EDIT_BASE - { - idc = VDL_FPS_TEXT_EDIT_IDC; - - text = "12345"; //--- ToDo: Localize; - x = 0.804687 * safezoneW + safezoneX; - y = 0.34375 * safezoneH + safezoneY; - w = 0.0351563 * safezoneW; - h = 0.0208333 * safezoneH; - sizeEx = 0.0208333 * safezoneH; - }; - class VDL_FPS_SLIDER: VDL_RSC_SLIDER_BASE - { - idc = VDL_FPS_SLIDER_IDC; - - x = 0.705078 * safezoneW + safezoneX; - y = 0.34375 * safezoneH + safezoneY; - w = 0.0996094 * safezoneW; - h = 0.0208333 * safezoneH; - sliderPosition = 60; - sliderRange[] = {15,120}; - sliderStep = 1; - lineSize = 1; - tooltip = "Your target FPS that you want to achieve"; //--- ToDo: Localize; - }; - /* ------------------------------------------------------------------------- - Check Frequency - ------------------------------------------------------------------------- */ - class VDL_SET_FREQ_BUTTON: VDL_RSC_BUTTON_BASE - { - idc = VDL_SET_FREQ_BUTTON_IDC; - - text = "Set Check Frequency"; //--- ToDo: Localize; - x = 0.699219 * safezoneW + safezoneX; - y = 0.375 * safezoneH + safezoneY; - w = 0.140625 * safezoneW; - h = 0.0208333 * safezoneH; - sizeEx = 0.0208333 * safezoneH; - }; - class VDL_FREQ_SLIDER: VDL_RSC_SLIDER_BASE - { - idc = VDL_FREQ_SLIDER_IDC; - - x = 0.705078 * safezoneW + safezoneX; - y = 0.40625 * safezoneH + safezoneY; - w = 0.0996094 * safezoneW; - h = 0.0208333 * safezoneH; - sliderPosition = 3; - sliderRange[] = {1,10}; - sliderStep = 1; - lineSize = 1; - tooltip = "This is how often the view distance will be adjusted in seconds"; //--- ToDo: Localize; - }; - class VDL_FREQ_TEXT_EDIT: VDL_RSC_EDIT_BASE - { - idc = VDL_FREQ_TEXT_EDIT_IDC; - - text = "12345"; //--- ToDo: Localize; - x = 0.804688 * safezoneW + safezoneX; - y = 0.40625 * safezoneH + safezoneY; - w = 0.0351563 * safezoneW; - h = 0.0208333 * safezoneH; - sizeEx = 0.0208333 * safezoneH; - }; - /* ------------------------------------------------------------------------- - Min Obj View Distance - ------------------------------------------------------------------------- */ - class VDL_MIN_OBJ_DIST_BUTTON: VDL_RSC_BUTTON_BASE - { - idc = VDL_MIN_OBJ_DIST_BUTTON_IDC; - - text = "Set Min Object Distance"; //--- ToDo: Localize; - x = 0.699219 * safezoneW + safezoneX; - y = 0.4375 * safezoneH + safezoneY; - w = 0.140625 * safezoneW; - h = 0.0208333 * safezoneH; - sizeEx = 0.0208333 * safezoneH; - }; - class VDL_MIN_OBJ_DIST_SLIDER: VDL_RSC_SLIDER_BASE - { - idc = VDL_MIN_OBJ_DIST_SLIDER_IDC; - - x = 0.705078 * safezoneW + safezoneX; - y = 0.46875 * safezoneH + safezoneY; - w = 0.0996094 * safezoneW; - h = 0.0208333 * safezoneH; - sliderPosition = 500; - sliderRange[] = {100,3000}; - sliderStep = 5; - lineSize = 10; - }; - class VDL_MIN_OBJ_DIST_TEXT_EDIT: VDL_RSC_EDIT_BASE - { - idc = VDL_MIN_OBJ_DIST_TEXT_EDIT_IDC; - - text = "12345"; //--- ToDo: Localize; - x = 0.804687 * safezoneW + safezoneX; - y = 0.46875 * safezoneH + safezoneY; - w = 0.0351563 * safezoneW; - h = 0.0208333 * safezoneH; - sizeEx = 0.0208333 * safezoneH; - }; - /* ------------------------------------------------------------------------- - Max Obj View Distance - ------------------------------------------------------------------------- */ - class VDL_MAX_OBJ_DIST_BUTTON: VDL_RSC_BUTTON_BASE - { - idc = VDL_MAX_OBJ_DIST_BUTTON_IDC; - - text = "Set Max Object Distance"; //--- ToDo: Localize; - x = 0.699219 * safezoneW + safezoneX; - y = 0.5 * safezoneH + safezoneY; - w = 0.140625 * safezoneW; - h = 0.0208333 * safezoneH; - sizeEx = 0.0208333 * safezoneH; - }; - class VDL_MAX_OBJ_DIST_SLIDER: VDL_RSC_SLIDER_BASE - { - idc = VDL_MAX_OBJ_DIST_SLIDER_IDC; - - x = 0.705078 * safezoneW + safezoneX; - y = 0.53125 * safezoneH + safezoneY; - w = 0.0996094 * safezoneW; - h = 0.0208333 * safezoneH; - sliderPosition = 1000; - sliderRange[] = {200,5000}; - sliderStep = 5; - lineSize = 10; - }; - class VDL_MAX_OBJ_DIST_TEXT_EDIT: VDL_RSC_EDIT_BASE - { - idc = VDL_MAX_OBJ_DIST_TEXT_EDIT_IDC; - - text = "12345"; //--- ToDo: Localize; - x = 0.804687 * safezoneW + safezoneX; - y = 0.53125 * safezoneH + safezoneY; - w = 0.0351563 * safezoneW; - h = 0.0208333 * safezoneH; - sizeEx = 0.0208333 * safezoneH; - }; - /* ------------------------------------------------------------------------- - Increment Size - ------------------------------------------------------------------------- */ - class VDL_INCREMENT_BUTTON: VDL_RSC_BUTTON_BASE - { - idc = VDL_INCREMENT_BUTTON_IDC; - - text = "Set Increment Size"; //--- ToDo: Localize; - x = 0.699219 * safezoneW + safezoneX; - y = 0.5625 * safezoneH + safezoneY; - w = 0.140625 * safezoneW; - h = 0.0208333 * safezoneH; - sizeEx = 0.0208333 * safezoneH; - }; - class VDL_INCREMENT_SLIDER: VDL_RSC_SLIDER_BASE - { - idc = VDL_INCREMENT_SLIDER_IDC; - - x = 0.705078 * safezoneW + safezoneX; - y = 0.59375 * safezoneH + safezoneY; - w = 0.0996094 * safezoneW; - h = 0.0208333 * safezoneH; - sliderPosition = 25; - sliderRange[] = {1,100}; - sliderStep = 1; - lineSize = 1; - tooltip = "By how much will the view distance be adjusted in meters to achieve FPS?"; //--- ToDo: Localize; - }; - class VDL_INCREMENT_TEXT_EDIT: VDL_RSC_EDIT_BASE - { - idc = VDL_INCREMENT_TEXT_EDIT_IDC; - - text = "12345"; //--- ToDo: Localize; - x = 0.804687 * safezoneW + safezoneX; - y = 0.59375 * safezoneH + safezoneY; - w = 0.0351563 * safezoneW; - h = 0.0208333 * safezoneH; - sizeEx = 0.0208333 * safezoneH; - }; - /* ------------------------------------------------------------------------- - Terrain View Distance - ------------------------------------------------------------------------- */ - class VDL_TERRAIN_BUTTON: VDL_RSC_BUTTON_BASE - { - idc = VDL_TERRAIN_BUTTON_IDC; - - text = "Set Terrain View Distance"; //--- ToDo: Localize; - x = 0.699219 * safezoneW + safezoneX; - y = 0.625 * safezoneH + safezoneY; - w = 0.140625 * safezoneW; - h = 0.0208333 * safezoneH; - sizeEx = 0.0208333 * safezoneH; - }; - class VDL_TERRAIN_SLIDER: VDL_RSC_SLIDER_BASE - { - idc = VDL_TERRAIN_SLIDER_IDC; - - x = 0.705078 * safezoneW + safezoneX; - y = 0.65625 * safezoneH + safezoneY; - w = 0.0996094 * safezoneW; - h = 0.0208333 * safezoneH; - sliderPosition = 200; - sliderRange[] = {100,6000}; - sliderStep = 5; - lineSize = 10; - tooltip = "The overall (static) view distance; this can be rather high without an issue."; //--- ToDo: Localize; - }; - class VDL_TERRAIN_TEXT_EDIT: VDL_RSC_EDIT_BASE - { - idc = VDL_TERRAIN_TEXT_EDIT_IDC; - - text = "12345"; //--- ToDo: Localize; - x = 0.804687 * safezoneW + safezoneX; - y = 0.65625 * safezoneH + safezoneY; - w = 0.0351563 * safezoneW; - h = 0.0208333 * safezoneH; - sizeEx = 0.0208333 * safezoneH; - }; - }; -}; \ No newline at end of file diff --git a/KISKA Systems/View Distance Limiter/controlTypes.hpp b/KISKA Systems/View Distance Limiter/controlTypes.hpp deleted file mode 100644 index d4d87b54..00000000 --- a/KISKA Systems/View Distance Limiter/controlTypes.hpp +++ /dev/null @@ -1,38 +0,0 @@ -// keys -#include "dikCodes.hpp" -// Control types -#define CT_STATIC 0 -#define CT_BUTTON 1 -#define CT_EDIT 2 -#define CT_SLIDER 3 -#define CT_COMBO 4 -#define CT_LISTBOX 5 -#define CT_TOOLBOX 6 -#define CT_CHECKBOXES 7 -#define CT_PROGRESS 8 -#define CT_HTML 9 -#define CT_STATIC_SKEW 10 -#define CT_ACTIVETEXT 11 -#define CT_TREE 12 -#define CT_STRUCTURED_TEXT 13 -#define CT_CONTEXT_MENU 14 -#define CT_CONTROLS_GROUP 15 -#define CT_SHORTCUTBUTTON 16 -#define CT_HITZONES 17 -#define CT_XKEYDESC 40 -#define CT_XBUTTON 41 -#define CT_XLISTBOX 42 -#define CT_XSLIDER 43 -#define CT_XCOMBO 44 -#define CT_ANIMATED_TEXTURE 45 -#define CT_OBJECT 80 -#define CT_OBJECT_ZOOM 81 -#define CT_OBJECT_CONTAINER 82 -#define CT_OBJECT_CONT_ANIM 83 -#define CT_LINEBREAK 98 -#define CT_USER 99 -#define CT_MAP 100 -#define CT_MAP_MAIN 101 -#define CT_LISTNBOX 102 -#define CT_ITEMSLOT 103 -#define CT_CHECKBOX 77 \ No newline at end of file diff --git a/KISKA Systems/View Distance Limiter/dikCodes.hpp b/KISKA Systems/View Distance Limiter/dikCodes.hpp deleted file mode 100644 index a81df72a..00000000 --- a/KISKA Systems/View Distance Limiter/dikCodes.hpp +++ /dev/null @@ -1,189 +0,0 @@ -#ifndef DIK_ESCAPE - -/**************************************************************************** - * - * DirectInput keyboard scan codes - * - ****************************************************************************/ - -#define DIK_ESCAPE 0x01 -#define DIK_1 0x02 -#define DIK_2 0x03 -#define DIK_3 0x04 -#define DIK_4 0x05 -#define DIK_5 0x06 -#define DIK_6 0x07 -#define DIK_7 0x08 -#define DIK_8 0x09 -#define DIK_9 0x0A -#define DIK_0 0x0B -#define DIK_MINUS 0x0C /* - on main keyboard */ -#define DIK_EQUALS 0x0D -#define DIK_BACK 0x0E /* backspace */ -#define DIK_TAB 0x0F -#define DIK_Q 0x10 -#define DIK_W 0x11 -#define DIK_E 0x12 -#define DIK_R 0x13 -#define DIK_T 0x14 -#define DIK_Y 0x15 -#define DIK_U 0x16 -#define DIK_I 0x17 -#define DIK_O 0x18 -#define DIK_P 0x19 -#define DIK_LBRACKET 0x1A -#define DIK_RBRACKET 0x1B -#define DIK_RETURN 0x1C /* Enter on main keyboard */ -#define DIK_LCONTROL 0x1D -#define DIK_A 0x1E -#define DIK_S 0x1F -#define DIK_D 0x20 -#define DIK_F 0x21 -#define DIK_G 0x22 -#define DIK_H 0x23 -#define DIK_J 0x24 -#define DIK_K 0x25 -#define DIK_L 0x26 -#define DIK_SEMICOLON 0x27 -#define DIK_APOSTROPHE 0x28 -#define DIK_GRAVE 0x29 /* accent grave */ -#define DIK_LSHIFT 0x2A -#define DIK_BACKSLASH 0x2B -#define DIK_Z 0x2C -#define DIK_X 0x2D -#define DIK_C 0x2E -#define DIK_V 0x2F -#define DIK_B 0x30 -#define DIK_N 0x31 -#define DIK_M 0x32 -#define DIK_COMMA 0x33 -#define DIK_PERIOD 0x34 /* . on main keyboard */ -#define DIK_SLASH 0x35 /* / on main keyboard */ -#define DIK_RSHIFT 0x36 -#define DIK_MULTIPLY 0x37 /* * on numeric keypad */ -#define DIK_LMENU 0x38 /* left Alt */ -#define DIK_SPACE 0x39 -#define DIK_CAPITAL 0x3A -#define DIK_F1 0x3B -#define DIK_F2 0x3C -#define DIK_F3 0x3D -#define DIK_F4 0x3E -#define DIK_F5 0x3F -#define DIK_F6 0x40 -#define DIK_F7 0x41 -#define DIK_F8 0x42 -#define DIK_F9 0x43 -#define DIK_F10 0x44 -#define DIK_NUMLOCK 0x45 -#define DIK_SCROLL 0x46 /* Scroll Lock */ -#define DIK_NUMPAD7 0x47 -#define DIK_NUMPAD8 0x48 -#define DIK_NUMPAD9 0x49 -#define DIK_SUBTRACT 0x4A /* - on numeric keypad */ -#define DIK_NUMPAD4 0x4B -#define DIK_NUMPAD5 0x4C -#define DIK_NUMPAD6 0x4D -#define DIK_ADD 0x4E /* + on numeric keypad */ -#define DIK_NUMPAD1 0x4F -#define DIK_NUMPAD2 0x50 -#define DIK_NUMPAD3 0x51 -#define DIK_NUMPAD0 0x52 -#define DIK_DECIMAL 0x53 /* . on numeric keypad */ -#define DIK_OEM_102 0x56 /* < > | on UK/Germany keyboards */ -#define DIK_F11 0x57 -#define DIK_F12 0x58 - -#define DIK_F13 0x64 /* (NEC PC98) */ -#define DIK_F14 0x65 /* (NEC PC98) */ -#define DIK_F15 0x66 /* (NEC PC98) */ - -#define DIK_KANA 0x70 /* (Japanese keyboard) */ -#define DIK_ABNT_C1 0x73 /* / ? on Portugese (Brazilian) keyboards */ -#define DIK_CONVERT 0x79 /* (Japanese keyboard) */ -#define DIK_NOCONVERT 0x7B /* (Japanese keyboard) */ -#define DIK_YEN 0x7D /* (Japanese keyboard) */ -#define DIK_ABNT_C2 0x7E /* Numpad . on Portugese (Brazilian) keyboards */ -#define DIK_NUMPADEQUALS 0x8D /* = on numeric keypad (NEC PC98) */ -#define DIK_PREVTRACK 0x90 /* Previous Track (DIK_CIRCUMFLEX on Japanese keyboard) */ -#define DIK_AT 0x91 /* (NEC PC98) */ -#define DIK_COLON 0x92 /* (NEC PC98) */ -#define DIK_UNDERLINE 0x93 /* (NEC PC98) */ -#define DIK_KANJI 0x94 /* (Japanese keyboard) */ -#define DIK_STOP 0x95 /* (NEC PC98) */ -#define DIK_AX 0x96 /* (Japan AX) */ -#define DIK_UNLABELED 0x97 /* (J3100) */ -#define DIK_NEXTTRACK 0x99 /* Next Track */ -#define DIK_NUMPADENTER 0x9C /* Enter on numeric keypad */ -#define DIK_RCONTROL 0x9D -#define DIK_MUTE 0xA0 /* Mute */ -#define DIK_CALCULATOR 0xA1 /* Calculator */ -#define DIK_PLAYPAUSE 0xA2 /* Play / Pause */ -#define DIK_MEDIASTOP 0xA4 /* Media Stop */ -#define DIK_VOLUMEDOWN 0xAE /* Volume - */ -#define DIK_VOLUMEUP 0xB0 /* Volume + */ -#define DIK_WEBHOME 0xB2 /* Web home */ -#define DIK_NUMPADCOMMA 0xB3 /* , on numeric keypad (NEC PC98) */ -#define DIK_DIVIDE 0xB5 /* / on numeric keypad */ -#define DIK_SYSRQ 0xB7 -#define DIK_RMENU 0xB8 /* right Alt */ -#define DIK_PAUSE 0xC5 /* Pause */ -#define DIK_HOME 0xC7 /* Home on arrow keypad */ -#define DIK_UP 0xC8 /* UpArrow on arrow keypad */ -#define DIK_PRIOR 0xC9 /* PgUp on arrow keypad */ -#define DIK_LEFT 0xCB /* LeftArrow on arrow keypad */ -#define DIK_RIGHT 0xCD /* RightArrow on arrow keypad */ -#define DIK_END 0xCF /* End on arrow keypad */ -#define DIK_DOWN 0xD0 /* DownArrow on arrow keypad */ -#define DIK_NEXT 0xD1 /* PgDn on arrow keypad */ -#define DIK_INSERT 0xD2 /* Insert on arrow keypad */ -#define DIK_DELETE 0xD3 /* Delete on arrow keypad */ -#define DIK_LWIN 0xDB /* Left Windows key */ -#define DIK_RWIN 0xDC /* Right Windows key */ -#define DIK_APPS 0xDD /* AppMenu key */ -#define DIK_POWER 0xDE /* System Power */ -#define DIK_SLEEP 0xDF /* System Sleep */ -#define DIK_WAKE 0xE3 /* System Wake */ -#define DIK_WEBSEARCH 0xE5 /* Web Search */ -#define DIK_WEBFAVORITES 0xE6 /* Web Favorites */ -#define DIK_WEBREFRESH 0xE7 /* Web Refresh */ -#define DIK_WEBSTOP 0xE8 /* Web Stop */ -#define DIK_WEBFORWARD 0xE9 /* Web Forward */ -#define DIK_WEBBACK 0xEA /* Web Back */ -#define DIK_MYCOMPUTER 0xEB /* My Computer */ -#define DIK_MAIL 0xEC /* Mail */ -#define DIK_MEDIASELECT 0xED /* Media Select */ - -/* - * Alternate names for keys, to facilitate transition from DOS. - */ -#define DIK_BACKSPACE DIK_BACK /* backspace */ -#define DIK_NUMPADSTAR DIK_MULTIPLY /* * on numeric keypad */ -#define DIK_LALT DIK_LMENU /* left Alt */ -#define DIK_CAPSLOCK DIK_CAPITAL /* CapsLock */ -#define DIK_NUMPADMINUS DIK_SUBTRACT /* - on numeric keypad */ -#define DIK_NUMPADPLUS DIK_ADD /* + on numeric keypad */ -#define DIK_NUMPADPERIOD DIK_DECIMAL /* . on numeric keypad */ -#define DIK_NUMPADSLASH DIK_DIVIDE /* / on numeric keypad */ -#define DIK_RALT DIK_RMENU /* right Alt */ -#define DIK_UPARROW DIK_UP /* UpArrow on arrow keypad */ -#define DIK_PGUP DIK_PRIOR /* PgUp on arrow keypad */ -#define DIK_LEFTARROW DIK_LEFT /* LeftArrow on arrow keypad */ -#define DIK_RIGHTARROW DIK_RIGHT /* RightArrow on arrow keypad */ -#define DIK_DOWNARROW DIK_DOWN /* DownArrow on arrow keypad */ -#define DIK_PGDN DIK_NEXT /* PgDn on arrow keypad */ - -/* - * Alternate names for keys originally not used on US keyboards. - */ -#define DIK_CIRCUMFLEX DIK_PREVTRACK /* Japanese keyboard */ - - -/* - * Combination keys - */ -#define INPUT_CTRL_OFFSET 512 -#define INPUT_SHIFT_OFFSET 1024 -#define INPUT_ALT_OFFSET 2048 - - -#endif /* DIK_ESCAPE */ \ No newline at end of file diff --git a/KISKA Systems/View Distance Limiter/viewDistanceLimiterBases.hpp b/KISKA Systems/View Distance Limiter/viewDistanceLimiterBases.hpp deleted file mode 100644 index e044c5d9..00000000 --- a/KISKA Systems/View Distance Limiter/viewDistanceLimiterBases.hpp +++ /dev/null @@ -1,300 +0,0 @@ -// Generated by: "Default" call BIS_fnc_exportGUIBaseClasses; -#include "viewDistanceLimiterCommonDefines.hpp" -#include "controlTypes.hpp" - -// Static styles -#define ST_POS 0x0F -#define ST_HPOS 0x03 -#define ST_VPOS 0x0C -#define ST_LEFT 0x00 -#define ST_RIGHT 0x01 -#define ST_CENTER 0x02 -#define ST_DOWN 0x04 -#define ST_UP 0x08 -#define ST_VCENTER 0x0C - -#define ST_TYPE 0xF0 -#define ST_SINGLE 0x00 -#define ST_MULTI 0x10 -#define ST_TITLE_BAR 0x20 -#define ST_PICTURE 0x30 -#define ST_FRAME 0x40 -#define ST_BACKGROUND 0x50 -#define ST_GROUP_BOX 0x60 -#define ST_GROUP_BOX2 0x70 -#define ST_HUD_BACKGROUND 0x80 -#define ST_TILE_PICTURE 0x90 -#define ST_WITH_RECT 0xA0 -#define ST_LINE 0xB0 -#define ST_UPPERCASE 0xC0 -#define ST_LOWERCASE 0xD0 - -#define ST_SHADOW 0x100 -#define ST_NO_RECT 0x200 -#define ST_KEEP_ASPECT_RATIO 0x800 - -// Slider styles -#define SL_DIR 0x400 -#define SL_VERT 0 -#define SL_HORZ 0x400 - -#define SL_TEXTURES 0x10 - -// progress bar -#define ST_VERTICAL 0x01 -#define ST_HORIZONTAL 0 - -// Listbox styles -#define LB_TEXTURES 0x10 -#define LB_MULTI 0x20 - -// Tree styles -#define TR_SHOWROOT 1 -#define TR_AUTOCOLLAPSE 2 - -// Default grid -#define GUI_GRID_WAbs ((safezoneW / safezoneH) min 1.2) -#define GUI_GRID_HAbs (GUI_GRID_WAbs / 1.2) -#define GUI_GRID_W (GUI_GRID_WAbs / 40) -#define GUI_GRID_H (GUI_GRID_HAbs / 25) -#define GUI_GRID_X (safezoneX) -#define GUI_GRID_Y (safezoneY + safezoneH - GUI_GRID_HAbs) - -// Default text sizes -#define GUI_TEXT_SIZE_SMALL (GUI_GRID_H * 0.8) -#define GUI_TEXT_SIZE_MEDIUM (GUI_GRID_H * 1) -#define GUI_TEXT_SIZE_LARGE (GUI_GRID_H * 1.2) - -// Pixel grid -#define pixelScale 0.50 -#define GRID_W (pixelW * pixelGrid * pixelScale) -#define GRID_H (pixelH * pixelGrid * pixelScale) - -#define PROFILE_BACKGROUND_COLOR(ALPHA)\ -{\ - "(profilenamespace getvariable ['GUI_BCG_RGB_R',0.13])",\ - "(profilenamespace getvariable ['GUI_BCG_RGB_G',0.54])",\ - "(profilenamespace getvariable ['GUI_BCG_RGB_B',0.21])",\ - ALPHA\ -} - -#define TOOLTIP_COLOR_BOX tooltipColorBox[] = {1,1,1,1} // the box frame -#define TOOLTIP_COLOR_TEXT tooltipColorText[] = {1,1,1,1} -#define TOOLTIP_COLOR_SHADE tooltipColorShade[] = {-1,-1,-1,1} // the interior fill of the box - - -class VDL_RSC_EDIT_BASE -{ - deletable = 0; - fade = 0; - access = 0; - type = CT_EDIT; - x = 0; - y = 0; - h = 0.04; - w = 0.2; - colorBackground[] = {1,1,1,0.25}; - colorText[] = {0.95,0.95,0.95,1}; - colorDisabled[] = {1,1,1,0.25}; - colorSelection[] = PROFILE_BACKGROUND_COLOR(1); - autocomplete = ""; - text = ""; - size = 0.2; - style = ST_FRAME; - font = "RobotoCondensed"; - shadow = 2; - sizeEx = GUI_TEXT_SIZE_MEDIUM; - canModify = 1; - TOOLTIP_COLOR_BOX; - TOOLTIP_COLOR_TEXT; - TOOLTIP_COLOR_SHADE; - onKeyDown = "_this call KISKA_fnc_adjustVdlControls"; -}; -class VDL_RSC_SLIDER_BASE -{ - deletable = 0; - fade = 0; - type = CT_XSLIDER; - color[] = {1,1,1,0.6}; - colorActive[] = {1,1,1,1}; - colorDisable[] = {1,1,1,0.4}; - style = SL_TEXTURES + SL_HORZ; - shadow = 0; - x = 0; - y = 0; - h = 0.029412; - w = 0.4; - colorDisabled[] = {1,1,1,0.2}; - arrowEmpty = "\A3\ui_f\data\gui\cfg\slider\arrowEmpty_ca.paa"; - arrowFull = "\A3\ui_f\data\gui\cfg\slider\arrowFull_ca.paa"; - border = "\A3\ui_f\data\gui\cfg\slider\border_ca.paa"; - thumb = "\A3\ui_f\data\gui\cfg\slider\thumb_ca.paa"; - TOOLTIP_COLOR_BOX; - TOOLTIP_COLOR_TEXT; - TOOLTIP_COLOR_SHADE; - sliderPosition = 5; - sliderRange[] = {1,10}; - sliderStep = 1; - onSliderPosChanged = "_this call KISKA_fnc_adjustVdlControls"; -}; -class VDL_RSC_BUTTON_BASE -{ - deletable = 0; - fade = 0; - access = 0; - type = CT_BUTTON; - text = ""; - colorText[] = {1,1,1,1}; - colorDisabled[] = {1,1,1,0.25}; - colorBackground[] = {0,0,0,0.5}; - colorBackgroundDisabled[] = {0,0,0,0.5}; - colorBackgroundActive[] = PROFILE_BACKGROUND_COLOR(1); - colorFocused[] = {0,0,0,0.5}; - colorShadow[] = {0,0,0,0}; - colorBorder[] = {0,0,0,1}; - TOOLTIP_COLOR_BOX; - TOOLTIP_COLOR_TEXT; - TOOLTIP_COLOR_SHADE; - soundEnter[] = - { - "\A3\ui_f\data\sound\RscButton\soundEnter", - 0.09, - 1 - }; - soundPush[] = - { - "\A3\ui_f\data\sound\RscButton\soundPush", - 0.09, - 1 - }; - soundClick[] = - { - "\A3\ui_f\data\sound\RscButton\soundClick", - 0.09, - 1 - }; - soundEscape[] = - { - "\A3\ui_f\data\sound\RscButton\soundEscape", - 0.09, - 1 - }; - idc = -1; - style = ST_CENTER; - x = 0; - y = 0; - w = 0.095589; - h = 0.039216; - shadow = 2; - font = "RobotoCondensed"; - sizeEx = GUI_TEXT_SIZE_MEDIUM; - url = ""; - offsetX = 0; - offsetY = 0; - offsetPressedX = 0; - offsetPressedY = 0; - borderSize = 0; - onButtonClick = "_this call KISKA_fnc_setVDLValue"; -}; -class VDL_RSC_TEXT_BASE -{ - deletable = 0; - fade = 0; - access = 0; - type = CT_STATIC; - idc = -1; - colorBackground[] = {0,0,0,0}; - colorText[] = {1,1,1,1}; - text = ""; - fixedWidth = 0; - x = 0; - y = 0; - h = 0.037; - w = 0.3; - style = ST_LEFT; - shadow = 1; - colorShadow[] = {0,0,0,0.5}; - font = "RobotoCondensed"; - SizeEx = GUI_TEXT_SIZE_MEDIUM; - linespacing = 1; - TOOLTIP_COLOR_BOX; - TOOLTIP_COLOR_TEXT; - TOOLTIP_COLOR_SHADE; -}; -class VDL_RSC_FRAME_BASE -{ - type = CT_STATIC; - idc = -1; - deletable = 0; - style = ST_FRAME; - shadow = 2; - colorText[] = {-1,-1,-1,1}; - colorBackground[] = {1,1,1,1}; - colorActive[] = {-1,-1,-1,1}; - font = "RobotoCondensed"; - sizeEx = 0.02; - text = ""; - x = 0; - y = 0; - w = 0.3; - h = 0.3; -}; -class VDL_RSC_CHECKBOX_BASE -{ - idc = -1; - type = CT_CHECKBOX; - deletable = 0; - style = ST_LEFT; - checked = 0; - x = "0.375 * safezoneW + safezoneX"; - y = "0.36 * safezoneH + safezoneY"; - w = "0.025 * safezoneW"; - h = "0.04 * safezoneH"; - color[] = {1,1,1,0.7}; - colorFocused[] = {1,1,1,1}; - colorHover[] = {1,1,1,1}; - colorPressed[] = {1,1,1,1}; - colorDisabled[] = {1,1,1,0.2}; - colorBackground[] = {0,0,0,0}; - colorBackgroundFocused[] = {0,0,0,0}; - colorBackgroundHover[] = {0,0,0,0}; - colorBackgroundPressed[] = {0,0,0,0}; - colorBackgroundDisabled[] = {0,0,0,0}; - textureChecked = "A3\Ui_f\data\GUI\RscCommon\RscCheckBox\CheckBox_checked_ca.paa"; - textureUnchecked = "A3\Ui_f\data\GUI\RscCommon\RscCheckBox\CheckBox_unchecked_ca.paa"; - textureFocusedChecked = "A3\Ui_f\data\GUI\RscCommon\RscCheckBox\CheckBox_checked_ca.paa"; - textureFocusedUnchecked = "A3\Ui_f\data\GUI\RscCommon\RscCheckBox\CheckBox_unchecked_ca.paa"; - textureHoverChecked = "A3\Ui_f\data\GUI\RscCommon\RscCheckBox\CheckBox_checked_ca.paa"; - textureHoverUnchecked = "A3\Ui_f\data\GUI\RscCommon\RscCheckBox\CheckBox_unchecked_ca.paa"; - texturePressedChecked = "A3\Ui_f\data\GUI\RscCommon\RscCheckBox\CheckBox_checked_ca.paa"; - texturePressedUnchecked = "A3\Ui_f\data\GUI\RscCommon\RscCheckBox\CheckBox_unchecked_ca.paa"; - textureDisabledChecked = "A3\Ui_f\data\GUI\RscCommon\RscCheckBox\CheckBox_checked_ca.paa"; - textureDisabledUnchecked = "A3\Ui_f\data\GUI\RscCommon\RscCheckBox\CheckBox_unchecked_ca.paa"; - TOOLTIP_COLOR_BOX; - TOOLTIP_COLOR_TEXT; - TOOLTIP_COLOR_SHADE; - soundEnter[] = - { - "\A3\ui_f\data\sound\RscButton\soundEnter", - 0.09, - 1 - }; - soundPush[] = - { - "", - 0.1, - 1 - }; - soundClick[] = - { - "", - 0.1, - 1 - }; - soundEscape[] = - { - "\A3\ui_f\data\sound\RscButton\soundEscape", - 0.09, - 1 - }; -}; \ No newline at end of file diff --git a/KISKA Systems/View Distance Limiter/viewDistanceLimiterCommonDefines.hpp b/KISKA Systems/View Distance Limiter/viewDistanceLimiterCommonDefines.hpp deleted file mode 100644 index e11c3dc5..00000000 --- a/KISKA Systems/View Distance Limiter/viewDistanceLimiterCommonDefines.hpp +++ /dev/null @@ -1,90 +0,0 @@ -// general -#define VIEW_DISTANCE_LIMITER_DIALOG KISKA_viewDistanceLimiter_Dialog -#define VIEW_DISTANCE_LIMITER_DIALOG_STR "KISKA_viewDistanceLimiter_Dialog" -#define VIEW_DISTANCE_LIMITER_DIALOG_IDD 2154 - -#define VDL_FRAME KISKA_viewDistanceLimiter_Frame_1800 -#define VDL_FRAME_IDC 1800 -#define VDL_HEADER_TEXT KISKA_viewDistanceLimiter_headerText_1000 -#define VDL_HEADER_TEXT_IDC 1000 -#define VDL_CLOSE_DIALOG_BUTTON KISKA_viewDistanceLimiter_closeDiagButton_1601 -#define VDL_CLOSE_DIALOG_BUTTON_IDC 1601 -#define VDL_SET_ALL_BUTTON KISKA_viewDistance_setAllChangesButton_1602 -#define VDL_SET_ALL_BUTTON_IDC 1602 -#define VDL_SYSTEM_ON_CHECKBOX KISKA_viewDistance_systemOnCheckBox_2800 -#define VDL_SYSTEM_ON_CHECKBOX_IDC 2800 -#define VDL_SYSTEM_ON_TEXT KISKA_viewDistance_systemOnText_1001 -#define VDL_SYSTEM_ON_TEXT_IDC 1001 - -// FPS -#define VDL_SET_FPS_BUTTON KISKA_viewDistance_setFPSButton_1603 -#define VDL_SET_FPS_BUTTON_IDC 1603 -#define VDL_FPS_SLIDER KISKA_viewDistance_FPSSlider_1900 -#define VDL_FPS_SLIDER_IDC 1900 -#define VDL_FPS_TEXT_EDIT KISKA_viewDistance_FPSText_1002 -#define VDL_FPS_TEXT_EDIT_IDC 1002 - -// Check Freq -#define VDL_SET_FREQ_BUTTON KISKA_viewDistance_setFrequencyButton_1604 -#define VDL_SET_FREQ_BUTTON_IDC 1604 -#define VDL_FREQ_SLIDER KISKA_viewDistance_frequencySlider_1901 -#define VDL_FREQ_SLIDER_IDC 1901 -#define VDL_FREQ_TEXT_EDIT KISKA_viewDistance_frequencyText_1003 -#define VDL_FREQ_TEXT_EDIT_IDC 1003 - -// Min Obj Dist -#define VDL_MIN_OBJ_DIST_BUTTON KISKA_viewDistance_setMinObjViewButton_1605 -#define VDL_MIN_OBJ_DIST_BUTTON_IDC 1605 -#define VDL_MIN_OBJ_DIST_SLIDER KISKA_viewDistance_minObjViewSlider_1902 -#define VDL_MIN_OBJ_DIST_SLIDER_IDC 1902 -#define VDL_MIN_OBJ_DIST_TEXT_EDIT KISKA_viewDistance_minObjViewText_1004 -#define VDL_MIN_OBJ_DIST_TEXT_EDIT_IDC 1004 - -// Max Obj Dist -#define VDL_MAX_OBJ_DIST_BUTTON KISKA_viewDistance_setMaxObjViewButton_1608 -#define VDL_MAX_OBJ_DIST_BUTTON_IDC 1608 -#define VDL_MAX_OBJ_DIST_SLIDER KISKA_viewDistance_maxObjViewSlider_1903 -#define VDL_MAX_OBJ_DIST_SLIDER_IDC 1903 -#define VDL_MAX_OBJ_DIST_TEXT_EDIT KISKA_viewDistance_maxObjViewText_1005 -#define VDL_MAX_OBJ_DIST_TEXT_EDIT_IDC 1005 - -// Increment -#define VDL_INCREMENT_BUTTON KISKA_viewDistance_setIncrementButton_1609 -#define VDL_INCREMENT_BUTTON_IDC 1609 -#define VDL_INCREMENT_SLIDER KISKA_viewDistance_incrementSlider_1904 -#define VDL_INCREMENT_SLIDER_IDC 1904 -#define VDL_INCREMENT_TEXT_EDIT KISKA_viewDistance_incrementText_1006 -#define VDL_INCREMENT_TEXT_EDIT_IDC 1006 - -// Terrain -#define VDL_TERRAIN_BUTTON KISKA_viewDistance_setTerrainViewButton_1610 -#define VDL_TERRAIN_BUTTON_IDC 1610 -#define VDL_TERRAIN_SLIDER KISKA_viewDistance_terrainViewSlider_1905 -#define VDL_TERRAIN_SLIDER_IDC 1905 -#define VDL_TERRAIN_TEXT_EDIT KISKA_viewDistance_terrainViewText_1007 -#define VDL_TERRAIN_TEXT_EDIT_IDC 1007 - -// Base classes -#define VDL_RSC_EDIT_BASE KISKA_viewDistanceLimiter_RscEdit -#define VDL_RSC_FRAME_BASE KISKA_viewDistanceLimiter_RscFrame -#define VDL_RSC_TEXT_BASE KISKA_viewDistanceLimiter_RscText -#define VDL_RSC_BUTTON_BASE KISKA_viewDistanceLimiter_RscButton -#define VDL_RSC_CHECKBOX_BASE KISKA_viewDistanceLimiter_RscCheckBox -#define VDL_RSC_SLIDER_BASE KISKA_viewDistanceLimiter_RscXSliderH - -// GLOBAL STRINGS -#define VDL_GLOBAL_RUN_STR "KISKA_VDL_run" -#define VDL_GLOBAL_FPS_STR "KISKA_VDL_fps" -#define VDL_GLOBAL_FREQ_STR "KISKA_VDL_freq" -#define VDL_GLOBAL_MIN_DIST_STR "KISKA_VDL_minDist" -#define VDL_GLOBAL_MAX_DIST_STR "KISKA_VDL_maxDist" -#define VDL_GLOBAL_INC_STR "KISKA_VDL_inc" -#define VDL_GLOBAL_VIEW_DIST_STR "KISKA_VDL_viewDist" -// GLOBALS (not strings) -#define VDL_GLOBAL_RUN KISKA_VDL_run -#define VDL_GLOBAL_FPS KISKA_VDL_fps -#define VDL_GLOBAL_FREQ KISKA_VDL_freq -#define VDL_GLOBAL_MIN_DIST KISKA_VDL_minDist -#define VDL_GLOBAL_MAX_DIST KISKA_VDL_maxDist -#define VDL_GLOBAL_INC KISKA_VDL_inc -#define VDL_GLOBAL_VIEW_DIST KISKA_VDL_viewDist \ No newline at end of file diff --git a/description.ext b/description.ext index 15d0070c..4055f9d6 100644 --- a/description.ext +++ b/description.ext @@ -128,11 +128,11 @@ class RscTitles #include "Headers\descriptionEXT\GUI\shopGUI.hpp" #include "Headers\descriptionEXT\GUI\musicManager.hpp" -#include "KISKA Systems\View Distance Limiter\ViewDistanceLimiterDialog.hpp" #include "Headers\descriptionEXT\Build Items\Main Build Items.hpp" #include "Headers\descriptionEXT\Faction Headers\Faction Master.hpp" #include "Headers\descriptionEXT\Loot Lists\Main Loot List.hpp" +#include "KISKA Systems\KISKA View DIstance Limiter\Headers\View Distance Limiter Dialog.hpp" #include "KISKA Systems\KISKA Parameter Menu\Headers\params menu.hpp" -#include "KISKA Systems\KISKA Parameter Menu\Headers\missionParams.hpp" +#include "KISKA Systems\KISKA Parameter Menu\Headers\missionParams.hpp" \ No newline at end of file diff --git a/mission.sqm b/mission.sqm index e163e2ba..5682127a 100644 --- a/mission.sqm +++ b/mission.sqm @@ -6,6 +6,10 @@ class EditorData scaleGridStep=1; autoGroupingDist=10; toggles=1; + mods[]= + { + "3denEnhanced" + }; class ItemIDProvider { nextID=274; @@ -23,7 +27,7 @@ class EditorData }; }; binarizationWanted=0; -sourceName="Arma3Survival"; +sourceName="Arma-3-Survival"; addons[]= { "A3_Characters_F", @@ -104,13 +108,7 @@ class CustomAttributes { class data { - class type - { - type[]= - { - "ARRAY" - }; - }; + singleType="ARRAY"; }; }; }; @@ -122,13 +120,7 @@ class CustomAttributes { class data { - class type - { - type[]= - { - "SCALAR" - }; - }; + singleType="SCALAR"; value=1; }; }; @@ -141,13 +133,7 @@ class CustomAttributes { class data { - class type - { - type[]= - { - "SCALAR" - }; - }; + singleType="SCALAR"; value=2; }; }; @@ -165,13 +151,7 @@ class CustomAttributes { class data { - class type - { - type[]= - { - "SCALAR" - }; - }; + singleType="SCALAR"; value=2; }; }; @@ -244,13 +224,7 @@ class Mission { class data { - class type - { - type[]= - { - "STRING" - }; - }; + singleType="STRING"; value="Male02GRE"; }; }; @@ -263,13 +237,7 @@ class Mission { class data { - class type - { - type[]= - { - "SCALAR" - }; - }; + singleType="SCALAR"; value=1.04; }; }; @@ -332,13 +300,7 @@ class Mission { class data { - class type - { - type[]= - { - "STRING" - }; - }; + singleType="STRING"; value="Male02GRE"; }; }; @@ -351,13 +313,7 @@ class Mission { class data { - class type - { - type[]= - { - "SCALAR" - }; - }; + singleType="SCALAR"; value=0.95999998; }; }; @@ -526,13 +482,7 @@ class Mission { class data { - class type - { - type[]= - { - "STRING" - }; - }; + singleType="STRING"; value="Male05GRE"; }; }; @@ -545,13 +495,7 @@ class Mission { class data { - class type - { - type[]= - { - "SCALAR" - }; - }; + singleType="SCALAR"; value=1.04; }; }; @@ -597,13 +541,7 @@ class Mission { class data { - class type - { - type[]= - { - "STRING" - }; - }; + singleType="STRING"; value="Male03GRE"; }; }; @@ -616,13 +554,7 @@ class Mission { class data { - class type - { - type[]= - { - "SCALAR" - }; - }; + singleType="SCALAR"; value=1.04; }; }; @@ -908,18 +840,12 @@ class Mission class Attribute0 { property="groupID"; - expression="_this setGroupID [_value];"; + expression="_this setGroupIdGlobal [_value];"; class Value { class data { - class type - { - type[]= - { - "STRING" - }; - }; + singleType="STRING"; value="Survivors"; }; }; @@ -948,13 +874,7 @@ class Mission { class data { - class type - { - type[]= - { - "STRING" - }; - }; + singleType="STRING"; value="#adminLogged"; }; }; @@ -967,13 +887,7 @@ class Mission { class data { - class type - { - type[]= - { - "SCALAR" - }; - }; + singleType="SCALAR"; value=0; }; }; @@ -986,13 +900,7 @@ class Mission { class data { - class type - { - type[]= - { - "STRING" - }; - }; + singleType="STRING"; value=""; }; }; @@ -1005,13 +913,7 @@ class Mission { class data { - class type - { - type[]= - { - "SCALAR" - }; - }; + singleType="SCALAR"; value=3; }; }; @@ -1045,13 +947,7 @@ class Mission { class data { - class type - { - type[]= - { - "BOOL" - }; - }; + singleType="BOOL"; value=0; }; }; From 1d0871a40dc262c2ee235a50bf19b633620334ff Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 25 Jan 2025 09:52:13 -0700 Subject: [PATCH 131/133] #642 added KISKA_fnc_ACEX_setHCTransfer --- KISKA Systems/KISKA Functions.hpp | 2 + .../fn_ACEX_setHCTransfer.sqf | 49 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 KISKA Systems/KISKA Utility Functions/fn_ACEX_setHCTransfer.sqf diff --git a/KISKA Systems/KISKA Functions.hpp b/KISKA Systems/KISKA Functions.hpp index 924e0c52..0e3950d0 100644 --- a/KISKA Systems/KISKA Functions.hpp +++ b/KISKA Systems/KISKA Functions.hpp @@ -72,6 +72,8 @@ class KISKA class KISKA_utilities { file = "KISKA Systems\KISKA Utility Functions"; + class ACEX_setHCTransfer + {}; class addArsenal {}; class addKiskaDiaryEntry diff --git a/KISKA Systems/KISKA Utility Functions/fn_ACEX_setHCTransfer.sqf b/KISKA Systems/KISKA Utility Functions/fn_ACEX_setHCTransfer.sqf new file mode 100644 index 00000000..cb6df4d7 --- /dev/null +++ b/KISKA Systems/KISKA Utility Functions/fn_ACEX_setHCTransfer.sqf @@ -0,0 +1,49 @@ +/* ---------------------------------------------------------------------------- +Function: KISKA_fnc_ACEX_setHCTransfer + +Description: + Simply sets the blacklist variable of a given unit from being transferred by the + ACEX headless client module. Variable is set on the server. + +Parameters: + 0: _unit - The unit to blacklist + 1: _setting - The blacklist value to set (true to blacklist, false to allow transfer) + +Returns: + NOTHING + +Examples: + (begin example) + // disable transfer + [someGroup,true] call KISKA_fnc_ACEX_setHCTransfer; + (end) + + (begin example) + // enable transfer + [someGroup,false] call KISKA_fnc_ACEX_setHCTransfer; + (end) + +Author(s): + Ansible2 +---------------------------------------------------------------------------- */ +scriptName "KISKA_fnc_ACEX_setHCTransfer"; + +if (!isMultiplayer) exitWith { + ["No need to run in singleplayer..."] call KISKA_fnc_log; + nil +}; + +params [ + ["_unit",objNull,[grpNull,objNull]], + ["_setting",false,[true]] +]; + +if (isNull _unit) exitWith { + ["A null unit was passed, will not blacklist",true] call KISKA_fnc_log; + nil +}; + +_unit setVariable ["acex_headless_blacklist",_setting,2]; + + +nil From 346bd1ce6ef60a8cdf7a82ab6422e99a18cfe7a6 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Sat, 25 Jan 2025 10:18:08 -0700 Subject: [PATCH 132/133] #642 added moscow bombing files to main blacklist --- Headers/descriptionEXT/Loot Lists/Main Loot List.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Headers/descriptionEXT/Loot Lists/Main Loot List.hpp b/Headers/descriptionEXT/Loot Lists/Main Loot List.hpp index aab1b1bc..68659812 100644 --- a/Headers/descriptionEXT/Loot Lists/Main Loot List.hpp +++ b/Headers/descriptionEXT/Loot Lists/Main Loot List.hpp @@ -24,7 +24,9 @@ class BLWK_lootLists "rhs_mag_20Rnd_556x45_M200_Stanag", "rhsusf_100Rnd_762x51_m82_blank", "rhsusf_50Rnd_762x51_m82_blank", - "hgun_Pistol_Signal_F" + "hgun_Pistol_Signal_F", + "CUP_item_Moscow_Bombing_File", + "CUP_Item_item_Moscow_Bombing_File" }; lootWhitelist_launchers[] = { From 120280e416e327673b93aefcfd89f6643d4da038 Mon Sep 17 00:00:00 2001 From: Ansible2 Date: Thu, 30 Jan 2025 21:37:14 -0700 Subject: [PATCH 133/133] #642: fixed CAS attack infinite loops --- KISKA Systems/KISKA Utility Functions/fn_CASAttack.sqf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/KISKA Systems/KISKA Utility Functions/fn_CASAttack.sqf b/KISKA Systems/KISKA Utility Functions/fn_CASAttack.sqf index 78262bc0..8f0275e4 100644 --- a/KISKA Systems/KISKA Utility Functions/fn_CASAttack.sqf +++ b/KISKA Systems/KISKA Utility Functions/fn_CASAttack.sqf @@ -62,10 +62,6 @@ _plane setVariable ["KISKA_CAS_guidedFireEvent",{ { params ["_args","_id"]; - if (isNull _projectile) exitWith { - [_id] call CBAP_fnc_removePerFrameHandler; - }; - _args params [ "_projectile", "_projectileStartPosASL", @@ -76,6 +72,10 @@ _plane setVariable ["KISKA_CAS_guidedFireEvent",{ "_attackPosition" ]; + if (isNull _projectile) exitWith { + [_id] call CBAP_fnc_removePerFrameHandler; + }; + private _interval = linearConversion [_startTime,_timeAfterFlight,time,0,1]; private _velocity = velocity _projectile; _projectile setVelocityTransformation [