Skip to content
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

Rack - API and Usability Improvements #1334

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions addons/api/CfgFunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ class CfgFunctions {
PATHTO_FNC(initVehicleRacks);
PATHTO_FNC(isRackRadioRemovable);
PATHTO_FNC(mountRackRadio);
PATHTO_FNC(removeAllRacksFromVehicle);
PATHTO_FNC(removeRackFromVehicle);
PATHTO_FNC(replaceRacksOnVehicle);
PATHTO_FNC(unmountRackRadio);
};

Expand Down
2 changes: 2 additions & 0 deletions addons/api/fnc_addRackToVehicle.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ private _selectPlayer = {
[{
params ["_selectPlayer", "_condition", "_vehicle"];

if !([_vehicle] call FUNC(areVehicleRacksInitialized)) exitWith {false};

private _player = [_condition, _vehicle] call _selectPlayer;

!isNil "_player"
Expand Down
65 changes: 65 additions & 0 deletions addons/api/fnc_removeAllRacksFromVehicle.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include "script_component.hpp"
/*
* Author: mrschick
* Removes all Racks from a vehicle. Must be executed on the server.
*
* Arguments:
* 0: Vehicle <OBJECT> (default: objNull)
*
* Return Value:
* Racks removed successfully <BOOL>
*
* Example:
* [cursorTarget] call acre_api_fnc_removeAllRacksFromVehicle
*
* Public: Yes
*/

params [
["_vehicle", objNull, [objNull]]
];

if (!isServer) exitWith {
WARNING("Function must be called on the server.");
false
};

if (isNull _vehicle) exitWith {
WARNING_1("Trying to remove a rack from an undefined vehicle %1",_vehicle);
false
};

private _success = true;

if (!([_vehicle] call FUNC(areVehicleRacksInitialized))) then {
WARNING_1("Forcing initialisation of vehicle %1 in order to remove all racks",_vehicle);
_success = [_vehicle] call EFUNC(api,initVehicleRacks);
};

if (!_success) exitWith {
WARNING_1("Vehicle %1 failed to initialise",_vehicle);
};

// A player must do the action of removing a rack
private _player = objNull;

if (isDedicated) then {
// Pick the first player
_player = (allPlayers - entities "HeadlessClient_F") select 0;
} else {
_player = acre_player;
};

[{
params ["_vehicle", "_player"];
[_vehicle] call FUNC(areVehicleRacksInitialized)
}, {
params ["_vehicle", "_player"];

private _racks = [_vehicle] call FUNC(getVehicleRacks);
for "_i" from (count _racks) - 1 to 0 step -1 do {
[QEGVAR(sys_rack,removeVehicleRacks), [_vehicle, _racks select _i], _player] call CBA_fnc_targetEvent;
};
}, [_vehicle, _player]] call CBA_fnc_waitUntilAndExecute;

true
3 changes: 1 addition & 2 deletions addons/api/fnc_removeRackFromVehicle.sqf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "script_component.hpp"
/*
* Author: ACRE2Team
* Initialises all racks in the vehicle. Must be executed in the server.
* Removes a specific Rack from a vehicle. Must be executed on the server.
*
* Arguments:
* 0: Vehicle <OBJECT> (default: objNull)
Expand Down Expand Up @@ -54,4 +54,3 @@ if (isDedicated) then {
[QEGVAR(sys_rack,removeVehicleRacks), [_vehicle, _rackId], _player] call CBA_fnc_targetEvent;

true

74 changes: 74 additions & 0 deletions addons/api/fnc_replaceRacksOnVehicle.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include "script_component.hpp"
/*
* Author: mrschick
* Replaces all config-defined Racks on a vehicle with a different class of Rack, while keeping the same name, allowedPositions, etc.
* Must be executed on the server.
*
* Arguments:
* 0: Vehicle <OBJECT> (default: objNull)
* 1: Rack classname to remove <STRING> (default: "")
* 2: Rack classname to add <STRING> (default: "")
* 3: Condition called with argument "_unit" for rack init. If a longer function is given, it should be precompiled. <CODE> (default: {})
*
* Return Value:
* Racks replaced successfully <BOOL>
*
* Example:
* [cursorTarget, "ACRE_VRC103", "ACRE_VRC64", {}] call acre_api_fnc_replaceRacksOnVehicle
*
* Public: Yes
*/

params [
["_vehicle", objNull, [objNull]],
["_fromRack", "", [""]],
["_toRack", "", [""]],
["_condition", {}, [{}]]
];

if (!isServer) exitWith {
WARNING("Function must be called on the server.");
false
};

if (isNull _vehicle) exitWith {
WARNING_1("Trying to remove a rack from an undefined vehicle %1",_vehicle);
false
};

if (_fromRack == "" || {_toRack == ""}) exitWith {
WARNING_1("Racks to replace on vehicle %1 were not defined",_vehicle);
false
};

if (_fromRack == _toRack) exitWith {
WARNING_1("Racks on vehicle %1 and intended replacements are the same",_vehicle);
false
};

// Store the desired Rack replacement as an object var which will be handled by sys_rack/fnc_initVehicle on the next initialization
_vehicle setVariable [QEGVAR(sys_rack,replaceRacks), [_fromRack, _toRack], true];

if ([_vehicle] call FUNC(areVehicleRacksInitialized)) then {
// If Racks have already been initialized, revert the initialization to run this function again
[_vehicle] call FUNC(removeAllRacksFromVehicle);

[{
params ["_vehicle"];
(_vehicle getVariable [QEGVAR(sys_rack,vehicleRacks), []]) isEqualTo []
}, {
params ["_vehicle"];

_vehicle setVariable [QEGVAR(sys_rack,initialized), false, true];

private _success = true;
WARNING_1("Forcing initialisation of vehicle %1 in order to alter all racks",_vehicle);
_success = [_vehicle, _condition] call EFUNC(api,initVehicleRacks);

if (!_success) exitWith {
WARNING_1("Vehicle %1 failed to initialise",_vehicle);
};
}, [_vehicle]] call CBA_fnc_waitUntilAndExecute;
};

true
6 changes: 6 additions & 0 deletions addons/api/fnc_setMultiPushToTalkAssignment.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ private _index = _var findIf {

if (_index != -1) exitWith { false };

// Save Rack PTT Assignments to vehicle
private _vehicle = objectParent acre_player;
if (!isNull _vehicle) then {
_vehicle setVariable [QEGVAR(sys_rack,MPTTAssignment), _var];
};

if (acre_player isEqualTo player) then { // using zeus player voice
ACRE_ASSIGNED_PTT_RADIOS = _var;
} else { // using zeus remote voice
Expand Down
2 changes: 1 addition & 1 deletion addons/sys_gui/RscTitles.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class RscTitles {
};
class VehicleInfoText: RscStructuredText {
idc = 2;
w = QUOTE(10 * VEHICLE_INFO_DEFAULT_W); // Must be specifically widened
w = QUOTE(VEHICLE_INFO_DEFAULT_W);
};
};
};
Expand Down
2 changes: 1 addition & 1 deletion addons/sys_gui/fnc_updateVehicleInfo.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ _ctrlText ctrlSetStructuredText parseText _str;

// Calculate new height (3 elements per row)
private _rows = ceil ((1 max _elements) / 3);
private _newBaseH = (((safeZoneW / safeZoneH) min 1.2) / 1.2) / 25;
private _newBaseH = (((safeZoneW / safeZoneH) min 1.2) / 1.2) / 23;
private _newH = _newBaseH * _rows;
private _newContainerH = (0.8 * _newH) + 0.001;
TRACE_4("vehicle info height",_elements,_rows,_newH,_newContainerH);
Expand Down
5 changes: 3 additions & 2 deletions addons/sys_intercom/fnc_getStationVariableName.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Arguments:
* 0: Vehicle with intercom <OBJECT>
* 1: Unit to be checked <OBJECT>
* 2: Component prefix for the variable name <STRING> (default: "acre_sys_intercom_station_%1")
*
* Return Value:
* Variable name, string of length 0 if not found <STRING>
Expand All @@ -16,14 +17,14 @@
* Public: No
*/

params ["_vehicle", "_unit"];
params ["_vehicle", "_unit", ["_prefix", QGVAR(station_%1)]];

private _found = false;
private _varName = "";
{
if (_unit isEqualTo (_x select 0)) exitWith {
private _role = toLower (_x select 1);
_varName = format [QGVAR(station_%1), _role];
_varName = format [_prefix, _role];
if (_role in ["cargo", "turret"]) then {
if (_role isEqualTo "cargo") then {
_varName = format ["%1_%2", _varName, _x select 2];
Expand Down
4 changes: 4 additions & 0 deletions addons/sys_rack/fnc_addRackOnReturn.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ if (_idx != -1) then {
_vehicle setVariable [QGVAR(queue), _queue];
};

if (_queue isEqualTo []) then {
_vehicle setVariable [QGVAR(initialized), true, true];
};

if (!_handled) then {
WARNING_2("Recieved new rack ID (%1) for vehicle (%2) but no entry in queue rack.",_rackId,typeOf _vehicle);
};
75 changes: 45 additions & 30 deletions addons/sys_rack/fnc_enterVehicle.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,22 @@

params ["_vehicle", "_unit"];

if (_unit != _vehicle && {isNull remoteControlled _unit}) then {
private _initialized = _vehicle getVariable [QGVAR(initialized), false];

if (!_initialized) then {
// Only initialize if we are first in the crew array - This helps prevent multiple requests if multiple players enter a vehicle around the same time.
private _crew = [_vehicle] call EFUNC(sys_core,getPlayersInVehicle);
private _firstPlayer = objNull;
{
if (!isNull _x) exitWith {
_firstPlayer = _x;
};
} forEach _crew;

if (!isNull _firstPlayer) then {
if (_unit == _firstPlayer) then {
[_vehicle] call FUNC(initVehicle);

// Give some time for the racks to initialise properly
[{
[_this select 0] call FUNC(configureRackIntercom);
// Update the display
[_this select 0, _this select 1] call EFUNC(sys_intercom,updateVehicleInfoText);
}, [_vehicle, _unit], 0.5] call CBA_fnc_waitAndExecute;
};
} else { // No other players.
if (_unit == _vehicle || {!(isNull remoteControlled _unit)}) exitWith {};

private _initialized = _vehicle getVariable [QGVAR(initialized), false];

if (!_initialized) then {
// Only initialize if we are first in the crew array - This helps prevent multiple requests if multiple players enter a vehicle around the same time.
private _crew = [_vehicle] call EFUNC(sys_core,getPlayersInVehicle);
private _firstPlayer = objNull;
{
if (!isNull _x) exitWith {
_firstPlayer = _x;
};
} forEach _crew;

if (!isNull _firstPlayer) then {
if (_unit == _firstPlayer) then {
[_vehicle] call FUNC(initVehicle);

// Give some time for the racks to initialise properly
Expand All @@ -52,11 +43,35 @@ if (_unit != _vehicle && {isNull remoteControlled _unit}) then {
[_this select 0, _this select 1] call EFUNC(sys_intercom,updateVehicleInfoText);
}, [_vehicle, _unit], 0.5] call CBA_fnc_waitAndExecute;
};
};
} else { // No other players.
[_vehicle] call FUNC(initVehicle);

// Enable the PFH if it is not active (can only be active if the unit is using an external radio before entering the vehicle)
if (GVAR(rackPFH) == -1) then {
GVAR(rackPFH) = [DFUNC(rackPFH), 1, [_unit, _vehicle]] call CBA_fnc_addPerFrameHandler;
TRACE_1("rack PFH",GVAR(rackPFH));
// Give some time for the racks to initialise properly
[{
[_this select 0] call FUNC(configureRackIntercom);
// Update the display
[_this select 0, _this select 1] call EFUNC(sys_intercom,updateVehicleInfoText);
}, [_vehicle, _unit], 0.5] call CBA_fnc_waitAndExecute;
};
};

// Enable the PFH if it is not active (can only be active if the unit is using an external radio before entering the vehicle)
if (GVAR(rackPFH) == -1) then {
GVAR(rackPFH) = [DFUNC(rackPFH), 1, [_unit, _vehicle]] call CBA_fnc_addPerFrameHandler;
TRACE_1("rack PFH",GVAR(rackPFH));
};

// Re-Use stored radios for the current position
private _varName = [_vehicle, _unit, QGVAR(usedRacks_%1)] call EFUNC(sys_intercom,getStationVariableName);
if (_varName isNotEqualTo "") then {
private _usedRacks = _vehicle getVariable [_varName, []];
{
[_vehicle, _unit, _x] call FUNC(startUsingMountedRadio);
} forEach _usedRacks;
};

// Load saved PTT assignments of previously used Racks
private _vehiclePTTs = _vehicle getVariable [QGVAR(MPTTAssignment), []];
if (_vehiclePTTs isNotEqualTo []) then {
[_vehiclePTTs] call EFUNC(api,setMultiPushToTalkAssignment);
};
39 changes: 33 additions & 6 deletions addons/sys_rack/fnc_initVehicle.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,45 @@ params ["_vehicle"];

private _initialized = _vehicle getVariable [QGVAR(initialized), false];
if (!_initialized) then {
private _racks = configOf _vehicle >> "AcreRacks";
private _racks = configProperties [(configOf _vehicle >> "AcreRacks"), "isClass _x", true];

// Set initialized flag if vehicle config has no defined Racks
if (_racks isEqualTo []) exitWith {
_vehicle setVariable [QGVAR(initialized), true, true];
};

// Handle acre_api_fnc_replaceRacksOnVehicle having defined a Rack class to replace
private _replaceVar = _vehicle getVariable [QGVAR(replaceRacks), false];
private ["_fromRack", "_toRack"];
if (_replaceVar isEqualType []) then {
_fromRack = _replaceVar select 0;
_toRack = _replaceVar select 1;
_vehicle setVariable [QGVAR(replaceRacks), false, true];
};

{
private _componentName = getText (_x >> "componentName");

private ["_componentName", "_components", "_mountedRadio"];
if (!isNil "_toRack" && {_componentName == _fromRack}) then {
private _toRackConfig = configFile >> "CfgAcreRacks" >> _toRack;
_componentName = _toRack;
_components = getArray (_toRackConfig >> "defaultComponents");
_mountedRadio = switch (_toRack) do {
case "ACRE_VRC64": { "ACRE_PRC77" };
case "ACRE_VRC103": { "ACRE_PRC117F" };
case "ACRE_SEM90": { "ACRE_SEM70" };
default { "" };
};
} else {
_components = getArray (_x >> "defaultComponents");
_mountedRadio = getText (_x >> "mountedRadio");
};

private _displayName = getText (_x >> "displayName");
private _shortName = getText (_x >> "shortName");
private _allowed = [_vehicle, getArray (_x >> "allowedPositions")] call EFUNC(sys_core,processVehicleSystemAccessArray);
private _disabled = [_vehicle, getArray (_x >> "disabledPositions")] call EFUNC(sys_core,processVehicleSystemAccessArray);
private _components = getArray (_x >> "defaultComponents");
private _mountedRadio = getText (_x >> "mountedRadio");
private _isRadioRemovable = getNumber (_x >> "isRadioRemovable") == 1;
private _intercoms = [_vehicle, _x] call FUNC(configWiredIntercoms);

Expand All @@ -37,7 +66,5 @@ if (!_initialized) then {
};

[_vehicle, _componentName, _displayName, _shortName, _isRadioRemovable, _allowed, _disabled, _mountedRadio, _components, _intercoms] call FUNC(addRack);
} forEach (configProperties [_racks, "isClass _x", true]);

_vehicle setVariable [QGVAR(initialized), true, true];
} forEach _racks;
};
2 changes: 1 addition & 1 deletion addons/sys_rack/fnc_rackChildrenActions.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ if (_mountedRadio == "") then { // Empty
} else {
private _class = configFile >> "CfgWeapons" >> _mountedRadio;
private _currentChannel = [_mountedRadio] call EFUNC(api,getRadioChannel);
private _displayName = format [localize ELSTRING(ace_interact,channelShort), getText (_class >> "displayName"), _currentChannel];
private _displayName = [_mountedRadio] call EFUNC(sys_core,getDescriptiveName);
private _icon = getText (_class >> "picture");

// General radio
Expand Down
Loading