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

Extended Vehicle Customization #387

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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/common/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
PREP(changeGroupSide);
PREP(collapseTree);
PREP(createZeus);
PREP(customizeVehicle);
PREP(deployCountermeasures);
PREP(deserializeInventory);
PREP(deserializeObjects);
Expand Down Expand Up @@ -28,6 +29,7 @@ PREP(getSelectedUnits);
PREP(getSelectedVehicles);
PREP(getSideIcon);
PREP(getVehicleAmmo);
PREP(getVehicleCustomization);
PREP(getVehicleIcon);
PREP(getWeaponReloadTime);
PREP(hasDefaultInventory);
Expand Down
52 changes: 52 additions & 0 deletions addons/common/functions/fnc_customizeVehicle.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include "script_component.hpp"
/*
* Author: Kex
* Changes the textures, animation sources and/or mass of a given vehicle.
* Based on BIS_fnc_initVehicle, but can be applied multiple times without issues.
* In contrast to BIS_fnc_initVehicle, if texture is passed as an array,
* it can also alternatively be an array of texture paths (i.e. output of getObjectTextures).
*
* Arguments:
* 0: Vehicle <OBJECT>
* 1: Texture <BOOLEAN|ARRAY|STRING>
* 2: Animation <BOOLEAN|ARRAY|STRING>
* 3: Mass <BOOLEAN|NUMBER>
*
* Return Value:
* None
*
* Example:
* [vehicle player, [texturePath1, texturePath2], [animationSource1, animationPhase1]] call zen_common_fnc_customizeVehicle
*
* Public: No
*/

params ["_vehicle", ["_texture", false, [false, [], ""]], ["_animation", false, [false, [], ""]], ["_mass", false, [false, 0]]];

// Fix: BIS_fnc_initVehicle cannot animate doors multiple times
if (_animation isEqualType []) then {
for "_i" from (count _animation - 2) to 0 step -2 do {
private _configName = _animation select _i;
private _phase = _animation select (_i + 1);
if ("door" in toLower _configName && !("hide" in toLower _configName)) then {
_vehicle animateDoor [_configName, _phase];
// Remove entry, since already handled
_animation deleteAt _i;
_animation deleteAt _i;
};
};
if (_animation isEqualTo []) then {
_animation = nil;
};
};

if (_texture isEqualType [] && {count _texture < 2 || {(_texture select 1) isEqualType ""}}) then {
[_vehicle, nil, _animation, _mass] call BIS_fnc_initVehicle;
{
_vehicle setObjectTextureGlobal [_forEachIndex, _x];
} forEach _texture;
} else {
[_vehicle, _texture, _animation, _mass] call BIS_fnc_initVehicle;
};

nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary when function has return value of "None".

2 changes: 1 addition & 1 deletion addons/common/functions/fnc_deserializeObjects.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ private _fnc_deserializeVehicle = {
[_vehicle, "", []] call BIS_fnc_initVehicle;
} else {
_customization params ["_textures", "_animations"];
[_vehicle, _textures, _animations, true] call BIS_fnc_initVehicle;
[_vehicle, _textures, _animations, true] call FUNC(customizeVehicle);
};

{
Expand Down
5 changes: 3 additions & 2 deletions addons/common/functions/fnc_exportMissionSQF.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,9 @@ private _fnc_processVehicle = {
_outputObjects pushBack ["%1 forceFlagTexture %2;", _varName, str _flagTexture];
};

(_vehicle call BIS_fnc_getVehicleCustomization) params ["_textures", "_animations"];
_outputObjects pushBack ["[%1, %2, %3, true] call BIS_fnc_initVehicle;", _varName, _textures, _animations];
(_vehicle call FUNC(getVehicleCustomization)) params ["_textures", "_animations"];
_outputObjects pushBack ["[%1, nil, %2, true] call BIS_fnc_initVehicle;", _varName, _animations];
_outputObjects pushBack ["{%1 setObjectTextureGlobal [_forEachIndex, _x]} forEach %2;", _varName, _textures];

[_vehicle, _varName] call _fnc_processInventory;

Expand Down
47 changes: 47 additions & 0 deletions addons/common/functions/fnc_getVehicleCustomization.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "script_component.hpp"
/*
* Author: Kex
* Return vehicle customization settings.
* Based on BIS_fnc_getVehicleCustomization.
* In contrast to BIS_fnc_getVehicleCustomization, it works properly for doors
* and textures are returned as an array of texture paths (i.e. output of getObjectTextures).
*
* Arguments:
* 0: Vehicle <OBJECT>
*
* Return Value:
* Array of texture paths and array of animations <ARRAY>
*
* Example:
* [vehicle player] call zen_common_fnc_getVehicleCustomization
*
* Public: No
*/

params ["_vehicle"];

private _vehicleType = typeOf _vehicle;
private _vehicleConfig = configFile >> "CfgVehicles" >> _vehicleType;
Comment on lines +23 to +24
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can use configOf command.


private _animations = [];
{
private _config = _x;
private _configName = configName _config;
private _source = getText (_config >> "source");

if (!(toLower _configName in BLACKLIST_ANIMATION_NAMES) && {!(toLower _source in BLACKLIST_ANIMATION_SOURCES) && {BLACKLIST_ANIMATION_ATTRIBUTES findIf {isClass (_config >> _x)} == -1}}) then {
private _phase = if ("door" in toLower _configName && !("hide" in toLower _configName)) then {
_vehicle doorPhase _configName;
} else {
_vehicle animationPhase _configName;
};
// Some sources will return negative values
if (_phase >= 0) then {
_animations append [_configName, _phase];
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolon.

};
} forEach configProperties [_vehicleConfig >> "animationSources", "isClass _x", true];

private _textures = getObjectTextures _vehicle;

[_textures, _animations]
2 changes: 1 addition & 1 deletion addons/common/functions/fnc_serializeObjects.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ private _fnc_serializeVehicle = {

private _fuel = fuel _vehicle;
private _inventory = _vehicle call FUNC(serializeInventory);
private _customization = _vehicle call BIS_fnc_getVehicleCustomization;
private _customization = _vehicle call FUNC(getVehicleCustomization);
private _flagTexture = getForcedFlagTexture _vehicle;

private _pylonMagazines = getPylonMagazines _vehicle;
Expand Down
5 changes: 5 additions & 0 deletions addons/common/script_component.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,8 @@

// Prevent certain magazines from being handled by ammo functions
#define BLACKLIST_MAGAZINES ["Laserbatteries"]

// Prevent certain source animations from being displayed in the garage
#define BLACKLIST_ANIMATION_SOURCES ["hit", "markerlight", "reload", "reloadmagazine", "revolving", "ammorandom", "damper", "wheel"]
#define BLACKLIST_ANIMATION_NAMES ["proxy", "doors"]
#define BLACKLIST_ANIMATION_ATTRIBUTES ["weapon", "wheel"]
1 change: 1 addition & 0 deletions addons/garage/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
PREP(applyToAll);
PREP(closeGarage);
PREP(defineCustomTexture);
PREP(getVehicleData);
PREP(handleMouse);
PREP(onAnimationSelect);
Expand Down
2 changes: 2 additions & 0 deletions addons/garage/XEH_preInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ GVAR(camYaw) = -45;
true
] call EFUNC(attributes,addButton);

#include "initCustomVehicleTextures.sqf"

ADDON = true;
4 changes: 2 additions & 2 deletions addons/garage/functions/fnc_applyToAll.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
* Public: No
*/

(GVAR(center) call BIS_fnc_getVehicleCustomization) params ["_texture", "_animations"];
(GVAR(center) call EFUNC(common,getVehicleCustomization)) params ["_textures", "_animations"];

private _vehicleType = typeOf GVAR(center);

{
if (typeOf _x isEqualTo _vehicleType) then {
[_x, _texture, _animations, true] call BIS_fnc_initVehicle;
[_x, _textures, _animations, true] call EFUNC(common,customizeVehicle);
};
} forEach SELECTED_OBJECTS;
36 changes: 36 additions & 0 deletions addons/garage/functions/fnc_defineCustomTexture.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include "script_component.hpp"
/*
* Author: Kex
* Defines custom texture variant for all vehicles that inherit from the given vehicle type.
*
* Arguments:
* 0: Base vehicle type <STRING>
* 1: Texture variant name <STRING>
* 2: Path of texture for each hidden selection <ARRAY>
*
* Return Value:
* None
*
* Example:
* [vehicleType, variantName, [texturePath1, texturePath2]] call zen_garage_fnc_defineCustomTexture
*
* Public: Yes
*/

params ["_baseVehicleType", "_variantName", "_texture"];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this function is public, should do type checking in params.


if (isNil QGVAR(customVehicleTextures)) then {
GVAR(customVehicleTextures) = [] call CBA_fnc_createNamespace;
};

{
private _vehicleType = configName _x;
// Clear garage cache
GVAR(vehicleDataCache) setVariable [_vehicleType, []];
Kexanone marked this conversation as resolved.
Show resolved Hide resolved

private _textures = GVAR(customVehicleTextures) getVariable [_vehicleType, []];
_textures pushBack [_texture, _variantName];
GVAR(customVehicleTextures) setVariable [_vehicleType, _textures];
} forEach (format ["configName _x isKindOf '%1'", _baseVehicleType] configClasses (configFile >> "CfgVehicles"));

nil
42 changes: 22 additions & 20 deletions addons/garage/functions/fnc_getVehicleData.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,31 @@ private _vehicleType = typeOf _vehicle;
private _vehicleData = GVAR(vehicleDataCache) getVariable _vehicleType;

if (isNil "_vehicleData") then {
_vehicleData = [];

private _vehicleConfig = configFile >> "CfgVehicles" >> _vehicleType;
private _vehicleFaction = faction _vehicle;

private _animations = [];
([_vehicle] call EFUNC(common,getVehicleCustomization)) params ["", "_currentAnimations"];
for "_i" from 0 to (count _currentAnimations - 2) step 2 do {
private _configName = _currentAnimations select _i;
private _displayName = getText (_vehicleConfig >> "animationSources" >> _configName >> "displayName");
if (_displayName == "") then {
_displayName = (_configName splitString "_") joinString " ";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary parentheses.

};
_animations pushBack [_configName, _displayName];
};

private _textures = [];
{
private _entries = [];

{
private _displayName = getText (_x >> "displayName");
private _factions = getArray (_x >> "factions");

if (
_displayName != ""
&& {getNumber (_x >> "scope") == 2 || {!isNumber (_x >> "scope")}}
&& {_factions isEqualTo [] || {_factions findIf {_x == _vehicleFaction} > -1}}
) then {
_entries pushBack [configName _x, _displayName];
};
} forEach configProperties [_x, "isClass _x", true];

_vehicleData pushBack _entries;
} forEach [_vehicleConfig >> "animationSources", _vehicleConfig >> "textureSources"];
private _configName = configName _x;
private _displayName = getText (_x >> "displayName");
_textures pushBack [_configName, _displayName];
} forEach configProperties [_vehicleConfig >> "textureSources", "isClass _x", true];

// Adding custom definitions
private _customTextures = GVAR(customVehicleTextures) getVariable [_vehicleType, []];
_textures append _customTextures;

_vehicleData = [_animations, _textures];

GVAR(vehicleDataCache) setVariable [_vehicleType, _vehicleData];
};
Expand Down
2 changes: 1 addition & 1 deletion addons/garage/functions/fnc_onAnimationSelect.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ for "_i" from 0 to (lbSize _ctrlListAnimations - 1) do {
};

// Update vehicle animations
[GVAR(center), nil, _animations, true] call BIS_fnc_initVehicle;
[GVAR(center), nil, _animations, true] call EFUNC(common,customizeVehicle);
9 changes: 8 additions & 1 deletion addons/garage/functions/fnc_onTextureSelect.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,12 @@ for "_i" from 0 to (lbSize _ctrlListTextures - 1) do {
// Check selected texture
_ctrlListTextures lbSetPicture [_selectedIndex, ICON_CHECKED];

private _texture = _ctrlListTextures lbData _selectedIndex;

// Handle serialized array
if (_texture != "" && {_texture select [0, 1] == '['}) then {
_texture = parseSimpleArray _texture;
Kexanone marked this conversation as resolved.
Show resolved Hide resolved
};

// Update vehicle textures
[GVAR(center), [_ctrlListTextures lbData _selectedIndex, 1]] call BIS_fnc_initVehicle;
[GVAR(center), _texture] call EFUNC(common,customizeVehicle);
32 changes: 23 additions & 9 deletions addons/garage/functions/fnc_populateLists.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,17 @@ private _vehicleData = [GVAR(center)] call FUNC(getVehicleData);
_vehicleData params ["_vehicleAnimations", "_vehicleTextures"];

private _fnc_addToList = {
params ["_ctrlList", "_configName", "_displayName", "_isChecked"];
params ["_ctrlList", "_variant", "_displayName", "_isChecked"];

if !(_variant isEqualType "") then {
_variant = str _variant;
};

if (_isChecked isEqualType false) then {_isChecked = parseNumber _isChecked};

private _index = _ctrlList lbAdd _displayName;
_ctrlList lbSetData [_index, _configName];

_ctrlList lbSetData [_index, _variant];
_ctrlList lbSetValue [_index, _isChecked];
_ctrlList lbSetTooltip [_index, _displayName];
_ctrlList lbSetPicture [_index, [ICON_UNCHECKED, ICON_CHECKED] select _isChecked];
Expand All @@ -38,7 +43,11 @@ private _ctrlListAnimations = _display displayCtrl IDC_LIST_ANIMATIONS;
{
_x params ["_configName", "_displayName"];

private _isChecked = GVAR(center) animationPhase _configName;
private _isChecked = if ("door" in toLower _configName && !("hide" in toLower _configName)) then {
GVAR(center) doorPhase _configName;
} else {
GVAR(center) animationPhase _configName;
};
[_ctrlListAnimations, _configName, _displayName, _isChecked] call _fnc_addToList;
} forEach _vehicleAnimations;

Expand All @@ -47,20 +56,25 @@ private _ctrlListTextures = _display displayCtrl IDC_LIST_TEXTURES;
private _sourcesConfig = configOf GVAR(center) >> "textureSources";
private _currentTextures = getObjectTextures GVAR(center) apply {toLower _x};
{
_x params ["_configName", "_displayName"];
_x params ["_variant", "_displayName"];

private _configTextures = getArray (_sourcesConfig >> _configName >> "textures");
private _textures = if (_variant isEqualType "") then {
getArray (_sourcesConfig >> _variant >> "textures");
} else {
_variant;
};
Comment on lines +69 to +73
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No semicolon for return values of code blocks.

private _isChecked = true;
if (count _configTextures == count _currentTextures) then {
{if !((_currentTextures select _forEachIndex) in toLower _x) exitWith {_isChecked = false}} forEach _configTextures;
if (count _textures == count _currentTextures) then {
{if !((_currentTextures select _forEachIndex) in toLower _x) exitWith {_isChecked = false}} forEach _textures;
} else {
_isChecked = false;
};

[_ctrlListTextures, _configName, _displayName, _isChecked] call _fnc_addToList;
[_ctrlListTextures, _variant, _displayName, _isChecked] call _fnc_addToList;
} forEach _vehicleTextures;

// Set font height and hide both lists
// Set font height and sort both lists
{
_x ctrlSetFontHeight POS_H(0.8); // Todo: setting for font height?
lbSort _x;
} forEach [_ctrlListAnimations, _ctrlListTextures];
Loading