diff --git a/Debug/fn_createMarkers.sqf b/Debug/fn_createMarkers.sqf index d5301bd..5fa8507 100644 --- a/Debug/fn_createMarkers.sqf +++ b/Debug/fn_createMarkers.sqf @@ -11,8 +11,9 @@ SIMTOOLS_FORCEDEPLOYMENT_DEBUG_MARKERS = []; [_orbat, { params [ "_echelon", - "_pos", - "_children" + ["_pos", [], [[0]], [0,2,3]], + ["_deployment", "", [""]], + ["_children", []] ]; private _name = format ["%1-%2-%3", player, _echelon, _pos]; diff --git a/fn_Formation.sqf b/fn_Formation.sqf index e9f69a3..11fad93 100644 --- a/fn_Formation.sqf +++ b/fn_Formation.sqf @@ -1,6 +1,7 @@ params [ ["_size", "", [""]], ["_position", [], [[0]]], + ["_deployment", "", [""]], ["_subordinates", [], [[]]] ]; @@ -8,6 +9,7 @@ private _fnc_typeCheck = { params [ ["_size", "", [""]], ["_position", [], [[0]]], + ["_deployment", "", [""]], ["_subordinates", [], [[]]] ]; @@ -22,6 +24,11 @@ private _fnc_typeCheck = { false }; + if ("_deployment" == "") exitWith { + ["'%1' is not a valid deployment value, at %2", _this select 2, _this] call BIS_fnc_error; + false + }; + if ((_subordinates apply {_x call _fnc_typeCheck}) findIf {!_x} > 1) exitWith { false }; @@ -31,4 +38,4 @@ private _fnc_typeCheck = { if (!(_this call _fnc_typeCheck)) exitWith { nil }; -[_size, _position, _subordinates] +[_size, _position, _deployment, _subordinates] diff --git a/fn_deployForce.sqf b/fn_deployForce.sqf index 4f84698..5d19d4d 100644 --- a/fn_deployForce.sqf +++ b/fn_deployForce.sqf @@ -2,49 +2,9 @@ params [ ["_orbat", []] ]; -if (count _orbat < 1) exitWith { "Orbat is empty" call BIS_fnc_error; }; +if (count _orbat < 1) exitWith {["Orbat is empty"] call BIS_fnc_error}; -// [[echelon, pos, parentArrayRef], ...] -private _queue = []; - -[_orbat, { - params [ - "_echelon", - "_pos", - ["_children", []], - ["_parent", []] - ]; - - private _element = [_echelon, _pos, _parent]; - _queue pushBack _element; - - { - // Set index 3 explicitly for leaf (childless) nodes - _x set [3, _element]; - } forEach _children; - - _children; -}] call SimTools_ForceDeployment_fnc_breadthFirstTraversal; - -prepareAndPlace = { - params [ - "_echelon", - "_composition", - "_pos", - "_name", - "_killzoneRadius" - ]; - - // TODO: Figure out if MVP compositions are doing this in their inits/triggers - { _x hideObjectGlobal true } foreach nearestTerrainObjects [_pos, [], _killzoneRadius]; - - // LARs_fnc_spawnComp expects 3D ATL pos, everything else can handle 2D. - if (count _pos == 2) then { _pos pushBack 0; }; - - [_composition, _pos] call LARs_fnc_spawnComp; -}; - -switchOnEchelon = { +_fnc_switchOnEchelon = { params [ "_echelon", "_BNCode", @@ -69,89 +29,76 @@ private _fobs = []; private _cops = []; private _pbs = []; private _pbBacklist = []; -{ - private _next = [ - _x select 0, - _x select 1, - _x select 2 + +[_orbat, { + params [ + "_echelon", + ["_pos", [], [[0]], [0,2,3]], + ["_deployment", "", [""]], + ["_children", []], + ["_parent", [], [[]]], + ["_blacklist", [], [[]]] ]; - if (_x select 0 == "Platoon") then { - _next pushBack _pbBacklist; + + if (_echelon == "Platoon") then { + _blacklist = _blacklist + _pbBacklist; }; - _next call { - params [ - "_echelon", - ["_pos", [], [[0]], [0,2,3]], - ["_parent", [], [[]], [0,3]], - ["_blacklist", [], [[]]] - ]; - - private [ - "_composition", - "_killzoneRadius", - "_blacklistRadius", - "_siblings" - ]; - [ - _echelon, - { - _composition = "FOB"; - _killzoneRadius = 50; - _blacklistRadius = 8000; - _siblings = _fobs; - }, - { - _composition = "COP"; - _killzoneRadius = 40; - _blacklistRadius = 2000; - _siblings = _cops; - }, - { - _composition = "PB"; - _killzoneRadius = 15; - _blacklistRadius = 600; - _siblings = _pbs; - } - ] call switchOnEchelon; - - if (count _pos < 2) then { - private _parentPos = []; - if (count _parent > 2) then {_parentPos = _parent select 1}; - - { - _blacklist pushBack [_x, _blacklistRadius]; - } forEach _siblings; - - private _newPos = [_composition, _parentPos, _blacklist] call SimTools_ForceDeployment_fnc_findValidPos; - _pos set [0, _newPos select 0]; - _pos set [1, _newPos select 1]; - if (count _newPos < 3) then { _pos pushBack 0; }; - - if (_echelon == "Company") then { - private _vector = (_pos vectorFromTo _parentPos); - _vector = _vector vectorMultiply 1000; - private _dir = (_vector select 0) atan2 (_vector select 1); - if (_dir < 0) then {_dir = 360 + _dir}; - private _blacklistCenter = _pos vectorAdd _vector; - - _pbBacklist pushBack ([_blacklistCenter, [2000, 1000, _dir, true]]); - }; - }; - [ - _echelon, - { _fobs }, - { _cops }, - { _pbs } - ] call switchOnEchelon pushBack _pos; - - // TODO: Add naming scheme - private _name = str _forEachIndex; - [_echelon, _composition, _pos, _name, _killzoneRadius] call prepareAndPlace; - _x set [1, _pos]; - - _pos + private [ + "_killzoneRadius", + "_blacklistRadius", + "_siblings" + ]; + [ + _echelon, + { + _killzoneRadius = 50; + _blacklistRadius = 8000; + _siblings = _fobs; + }, + { + _killzoneRadius = 40; + _blacklistRadius = 2000; + _siblings = _cops; + }, + { + _killzoneRadius = 15; + _blacklistRadius = 600; + _siblings = _pbs; + } + ] call _fnc_switchOnEchelon; + + if (count _pos < 2) then { + private _parentPos = if (count _parent >= 2) then {_parent select 1} else {[]}; + + _siblings apply {_blacklist pushBack [_x, _blacklistRadius]}; + + private _newPos = [_echelon, _parentPos, _blacklist] call SimTools_ForceDeployment_fnc_findValidPos; + _pos set [0, _newPos select 0]; + _pos set [1, _newPos select 1]; + if (count _newPos < 3) then {_pos pushBack 0}; + + if (_echelon == "Company") then { + private _vector = (_pos vectorFromTo _parentPos); + _vector = _vector vectorMultiply 1000; + private _dir = (_vector select 0) atan2 (_vector select 1); + if (_dir < 0) then {_dir = 360 + _dir}; + private _blacklistCenter = _pos vectorAdd _vector; + + _pbBacklist pushBack ([_blacklistCenter, [2000, 1000, _dir, true]]); + }; }; -} forEach _queue; + + [ + _echelon, + { _fobs }, + { _cops }, + { _pbs } + ] call _fnc_switchOnEchelon pushBack _pos; + + [_pos, _killzoneRadius] call compileFinal _deployment; + + _children apply {_x set [4, [_echelon, _pos]]; _x} +}] call SimTools_ForceDeployment_fnc_breadthFirstTraversal; _orbat diff --git a/fn_findValidPos.sqf b/fn_findValidPos.sqf index 7166613..66aa8c4 100644 --- a/fn_findValidPos.sqf +++ b/fn_findValidPos.sqf @@ -1,5 +1,5 @@ params [ - "_composition", + "_echelon", ["_parent", []], ["_blacklist", []] ]; @@ -11,8 +11,8 @@ private [ ]; try { - switch (toUpper _composition) do { - case "FOB": { + switch (_echelon) do { + case "Battalion": { // Place a FOB randomly // Add 8km buffer around FOB for siblings _parent_min_radius = 0; @@ -20,7 +20,7 @@ try { _sibling_buffer_radius = 8000; _object_dist = 10; }; - case "COP": { + case "Company": { // Place a COP between 1-3km from FOB // Add 2km buffer around COP for siblings _parent_min_radius = 1000; @@ -28,7 +28,7 @@ try { _sibling_buffer_radius = 2000; _object_dist = 10; }; - case "PB": { + case "Platoon": { // Place a PB between 500-2km from COP // Add 600m buffer around PB for siblings _parent_min_radius = 500; diff --git a/fn_parseCfgOrbat.sqf b/fn_parseCfgOrbat.sqf index ab88a83..25d6247 100644 --- a/fn_parseCfgOrbat.sqf +++ b/fn_parseCfgOrbat.sqf @@ -11,11 +11,11 @@ private _fnc_traverseSubclasses = { private _subordinates = getArray (_class >> "subordinates"); if (count _subordinates < 1 && {_subordinates = _class call BIS_fnc_returnChildren; count _subordinates < 1}) exitWith { - [getText (_class >> "size"), getArray (_class >> "position")] call SimTools_ForceDeployment_fnc_Formation + [getText (_class >> "size"), getArray (_class >> "position"), getText (_class >> "deployment")] call SimTools_ForceDeployment_fnc_Formation }; _subordinates = _subordinates apply {[_x] call _fnc_traverseSubclasses}; - [getText (_class >> "size"), getArray (_class >> "position"), _subordinates] call SimTools_ForceDeployment_fnc_Formation + [getText (_class >> "size"), getArray (_class >> "position"), getText (_class >> "deployment"), _subordinates] call SimTools_ForceDeployment_fnc_Formation }; _orbats apply {[_x] call _fnc_traverseSubclasses}