-
Notifications
You must be signed in to change notification settings - Fork 5
StaticLine - Implement Automatic Group Deployments #77
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
DartRuffian
merged 7 commits into
DartsArmaMods:main
from
bagigi-arma:feature/command-group-jumps
Mar 10, 2026
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
8d1108d
Remove personal preference from VSCode settings
mrschick d849244
Fix undefined variable use in helocast
mrschick 7c3e0ed
Optimize fnc_canJump
mrschick 6876016
Fix image link in Helocast documentation
mrschick 897ba09
Improve automatic backpack handling after landing
mrschick a068872
Implement Automatic Group Deployments
mrschick 409a535
Fix locality when checking for levelled ramps #78
mrschick File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| class Cfg3DEN { | ||
| class Object { | ||
| class AttributeCategories { | ||
| class PREFIX { | ||
| displayName = QUOTE(MOD_NAME); | ||
| collapsed = 0; | ||
| class Attributes { | ||
| class GVAR(isJumpMaster) { | ||
| displayName = CSTRING(jumpMaster_displayName); | ||
| tooltip = CSTRING(jumpMaster_tooltip); | ||
| property = QGVAR(isJumpMasterID); | ||
| control = "Checkbox"; | ||
| defaultValue = "false"; | ||
| condition = "objectBrain"; | ||
| expression = QUOTE(_this setVariable [ARR_3(QQGVAR(isJumpMaster),_value,true)]); | ||
| }; | ||
| }; | ||
| }; | ||
| }; | ||
| }; | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|
mrschick marked this conversation as resolved.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| #include "..\script_component.hpp" | ||
| /* | ||
| * Author: mrschick | ||
| * Checks if a unit can command the static line jump of an embarked+hooked player or AI group. | ||
| * | ||
| * Arguments: | ||
| * 0: Vehicle <OBJECT> | ||
| * 1: Unit <OBJECT> | ||
| * | ||
| * Return Value: | ||
| * True if unit can command jumps, otherwise false <BOOL> | ||
| * | ||
| * Example: | ||
| * [objectParent ace_player, ace_player] call aftb_staticLine_fnc_canDeployGroups; | ||
| * | ||
| * Public: No | ||
| */ | ||
|
|
||
| params ["_vehicle", "_unit"]; | ||
| TRACE_2("fnc_canDeployGroups",_vehicle,_unit); | ||
|
|
||
| GVAR(commandGroupJumps) > 0 && { | ||
| (_unit == leader _unit) || {_unit getVariable [QGVAR(isJumpMaster), false]} || {[_vehicle, _unit] call FUNC(isAircraftCrew)} | ||
| } && { | ||
| _vehicle call EFUNC(common,isRampOpen) && { [_vehicle, _unit] call FUNC(checkJumpCondition) } | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| #include "..\script_component.hpp" | ||
| /* | ||
| * Author: DartRuffian | ||
| * Checks if a unit satisfies the vehicle's jump condition. | ||
| * | ||
| * Arguments: | ||
| * 0: Vehicle <OBJECT> | ||
| * 1: Unit <OBJECT> | ||
| * | ||
| * Return Value: | ||
| * True if the unit satisfies the vehicle's jump condition, otherwise false <BOOL> | ||
| * | ||
| * Example: | ||
| * [objectParent ace_player, ace_player] call aftb_staticLine_fnc_checkJumpCondition; | ||
| * | ||
| * Public: No | ||
| */ | ||
|
|
||
| params ["_vehicle", "_unit"]; | ||
| TRACE_2("fnc_checkJumpCondition",_vehicle,_unit); | ||
|
|
||
| private _rampAnims = _vehicle call EFUNC(common,getRampAnimations); | ||
| private _jumpCondition = compile getText (configOf _vehicle >> QGVAR(condition)); | ||
|
|
||
| if (_jumpCondition isEqualTo {}) then { _jumpCondition = { true }; }; | ||
|
|
||
| [_vehicle, _unit, _rampAnims] call _jumpCondition |
93 changes: 93 additions & 0 deletions
93
addons/staticline/functions/fnc_deployGroupsChildrenActions.sqf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| #include "..\script_component.hpp" | ||
| /* | ||
| * Author: mrschick | ||
| * Dynamically fills the deployGroups action with subactions, allowing high-ranking crew/passengers to command the staggered line jump of embarked groups (hooked players or AI), or group leaders to command the jump of their own group. | ||
| * | ||
| * Arguments: | ||
| * 0: Vehicle <OBJECT> | ||
| * 1: Unit <OBJECT> | ||
| * | ||
| * Return Value: | ||
| * Array of ACE Child Actions <ARRAY> | ||
| * | ||
| * Example: | ||
| * [objectParent ace_player, ace_player] call aftb_staticLine_fnc_deployGroupsChildrenActions; | ||
| * | ||
| * Public: No | ||
| */ | ||
|
|
||
| params ["_vehicle", "_unit"]; | ||
|
|
||
| // Generate array of embarked groups | ||
| private _embarkedUnits = _vehicle call EFUNC(common,getPassengers); | ||
| private _embarkedGroups = []; | ||
| { | ||
| _embarkedGroups pushBackUnique (group _x); | ||
| } forEach _embarkedUnits; | ||
|
|
||
| // Abort early if there are no groups to deploy | ||
| if (_embarkedGroups isEqualTo []) exitWith {[]}; | ||
|
|
||
| // Evaluate specific permissions player should have, to determine which interactions are available to them | ||
| private _unitIsJumpMaster = (_unit getVariable [QGVAR(isJumpMaster), false]) || {GVAR(commandGroupJumps) > 1 && {[_vehicle, _unit] call FUNC(isAircraftCrew)}}; | ||
|
|
||
| private _actions = []; | ||
| private _action = []; | ||
|
|
||
| if ((_vehicle getVariable [QGVAR(unitsToDeploy), []]) isNotEqualTo []) then { | ||
| // If a deployment is in progress, only give jumpmasters the action to abort any in-progress deployment | ||
| if (_unitIsJumpMaster) then { | ||
| private _unitsRemaining = count (_vehicle getVariable [QGVAR(unitsToDeploy), []]); | ||
| _action = ([ | ||
| QGVAR(abortGroupDeployment), | ||
| format [LLSTRING(action_abortGroupDeployment), _unitsRemaining], | ||
| "", | ||
| {(_this select 0) setVariable [QGVAR(unitsToDeploy), [], true]}, | ||
| {true} | ||
| ] call ace_interact_menu_fnc_createAction); | ||
| _actions pushBack [_action, [], _vehicle]; | ||
| }; | ||
| } else { | ||
| // Pilot/Jumpmaster can deploy all groups in sequence | ||
| if (_unitIsJumpMaster && {count _embarkedGroups > 1}) then { | ||
| _action = [ | ||
| QGVAR(deployAllGroups), | ||
| LLSTRING(action_deployAllGroups), | ||
| "", | ||
| { | ||
| params ["_vehicle", "_unit", "_args"]; | ||
| [_vehicle, false, _args call FUNC(getUnitsToDeploy)] call FUNC(jumpAI); | ||
| }, | ||
| {true}, | ||
| {}, | ||
| [_embarkedGroups, _embarkedUnits] | ||
| ] call ace_interact_menu_fnc_createAction; | ||
| _actions pushBack [_action, [], _vehicle]; | ||
| }; | ||
|
|
||
| // Generate one action per-group, to deploy each automatically | ||
| { | ||
| private _group = _x; | ||
| // Jumpmasters can deploy any group, group leaders can only deploy their own | ||
| if (_unitIsJumpMaster || {GVAR(commandGroupJumps) == 3 && {_unit == leader _group}}) then { | ||
| private _groupUnits = (units _group) arrayIntersect _embarkedUnits; | ||
| private _hookedUnits = _groupUnits select {_x getVariable [QGVAR(isHooked), false] || {!isPlayer _x}}; | ||
| private _groupName = groupId _group; | ||
| _action = [ | ||
| QGVAR(deploy_) + _groupName, | ||
| format ["%1 (%2)", _groupName, format [LLSTRING(action_hooked), count _hookedUnits, count _groupUnits]], | ||
| "", | ||
| { | ||
| params ["_vehicle", "_unit", "_args"]; | ||
| [_vehicle, false, _args call FUNC(getUnitsToDeploy)] call FUNC(jumpAI); | ||
| }, | ||
| {true}, | ||
| {}, | ||
| [[_group], _embarkedUnits] | ||
|
mrschick marked this conversation as resolved.
|
||
| ] call ace_interact_menu_fnc_createAction; | ||
| _actions pushBack [_action, [], _vehicle]; | ||
| }; | ||
| } forEach _embarkedGroups; | ||
| }; | ||
|
|
||
| _actions; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| #include "..\script_component.hpp" | ||
| /* | ||
| * Author: mrschick | ||
| * Generate an array of ALL units to be deployed during the commanded Group Deployment. | ||
| * - The units are sorted by their group. | ||
| * - Within each group, units are always sorted side-by-side with others of their assigned color, so that "teams" aren't separated. | ||
| * - The position of the leader's "team", as well as his position within it, is determined by the CBA Setting GVAR(leaderJumpOrder). | ||
| * | ||
| * Arguments: | ||
| * 0: Groups to deploy <ARRAY> | ||
| * 1: Units embarked <ARRAY> | ||
| * | ||
| * Return Value: | ||
| * Array of units to deploy <ARRAY> | ||
| * | ||
| * Example: | ||
| * [group ace_player, units (vehicle ace_player)] call aftb_staticLine_fnc_getUnitsToDeploy; | ||
| * | ||
| * Public: No | ||
| */ | ||
|
|
||
| params ["_groupsToDeploy", "_embarkedUnits"]; | ||
|
|
||
| if (_groupsToDeploy isEqualTo [] || {_embarkedUnits isEqualTo []}) exitWith {[]}; | ||
|
|
||
| private _unitsToDeploy = []; | ||
|
|
||
| // Iterate through all groups to deploy, to ensure units are sorted by their group | ||
| { | ||
| private _group = _x; | ||
| private _leader = leader _group; | ||
| private _groupUnits = (units _group) arrayIntersect _embarkedUnits; | ||
| private _unitCount = count _groupUnits; | ||
|
|
||
| /* | ||
| * The following logic uses HashMaps and Array operations to ensure that: | ||
| * - Units of the same color (assignedTeam) are ALWAYS grouped together; | ||
| * - The Group Leader's position within the group's deployment sequence is AS CLOSE AS POSSIBLE to where determined by the CBA Setting (first, last, in the middle); | ||
| */ | ||
| private _groupUnitsSorted = []; | ||
|
|
||
| // 1. Group Units with the same "Team" (color) together, into HashMap Buckets | ||
| private _allTeams = createHashMap; | ||
| { (_allTeams getOrDefault [(_x getVariable [QGVAR(assignedTeam), assignedTeam _x]), [], true]) pushBack _x } forEach _groupUnits; | ||
|
|
||
| // 2. Separate the Leader's Team Bucket from the others | ||
| private _leaderColor = _leader getVariable [QGVAR(assignedTeam), assignedTeam _leader]; | ||
| private _leaderTeam = _allTeams get _leaderColor; | ||
| _allTeams deleteAt _leaderColor; | ||
|
|
||
| private _otherTeams = []; | ||
| { _otherTeams pushBack _y } forEach _allTeams; | ||
|
|
||
| // 3. Reposition the leader's team in the sequence, as well him within his own team, to reflect the preference defined by the CBA Setting | ||
| switch (GVAR(leaderJumpOrder)) do { | ||
| case 0: { // Leader jumps first | ||
| _groupUnitsSorted append ([_leader] + (_leaderTeam - [_leader])); | ||
| _groupUnitsSorted append (flatten _otherTeams); | ||
| }; | ||
| case 1: { // Leader jumps in the middle of his group | ||
| // Separate the other teams into 2 buckets, _before and _after, to place them around the leader's team | ||
| private _mid = floor ((count _otherTeams) / 2); | ||
| private _before = flatten (_otherTeams select [0, _mid]); | ||
| private _after = flatten (_otherTeams select [_mid]); | ||
|
|
||
| // Append teams before the leader's | ||
| _groupUnitsSorted append _before; | ||
|
|
||
| // Center the leader as close as possible in his group's sequence, while keeping him with his own team | ||
| private _firstLeaderTeamIdx = count _before; | ||
| private _lastLeaderTeamIdx = _unitCount - count _after - 1; | ||
| private _leaderIdx = ((floor (_unitCount / 2)) max _firstLeaderTeamIdx) min _lastLeaderTeamIdx; | ||
|
|
||
| // Append the leader's team to the group's sequence, with the leader in the desired position/index | ||
| _leaderTeam = _leaderTeam - [_leader]; | ||
| for [{_i = _firstLeaderTeamIdx}, {_i <= _lastLeaderTeamIdx}, {_i = _i + 1}] do { | ||
| if (_i == _leaderIdx) then { | ||
| _groupUnitsSorted set [_i, _leader]; | ||
| } else { | ||
| _groupUnitsSorted set [_i, _leaderTeam deleteAt 0]; | ||
| }; | ||
| }; | ||
|
|
||
| // Append teams after the leader's | ||
| _groupUnitsSorted append _after; | ||
| }; | ||
| case 2: { // Leader jumps last | ||
| _groupUnitsSorted append (flatten _otherTeams); | ||
| _groupUnitsSorted append ((_leaderTeam - [_leader]) + [_leader]); | ||
| }; | ||
| }; | ||
|
|
||
| #ifdef DEBUG_MODE_FULL | ||
| // Debug output of the current group's jump order, i.e: ["R", "R", "R-L", "B", "B", "B"] | ||
| systemChat str (_groupUnitsSorted apply { | ||
| private _color = (assignedTeam _x) select [0, 1]; | ||
| if (_x == leader _x) then {_color + "-L"} else {_color}; | ||
| }); | ||
| #endif | ||
|
|
||
| // 4. Append the now sorted group to the collective sequence of groups to deploy, filtering out players that aren't hooked in | ||
| _unitsToDeploy append (_groupUnitsSorted select {_x getVariable [QGVAR(isHooked), false] || {!isPlayer _x}}); | ||
| } forEach _groupsToDeploy; | ||
|
|
||
| _unitsToDeploy; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.