-
Notifications
You must be signed in to change notification settings - Fork 736
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
Quick Mount - Add Get In and Change seat action menu #5745
Changes from 29 commits
c1b9ec8
39c9c8b
9e73ca8
0222463
9e17c18
414d00e
5316536
8af3296
3e3993a
02d5a69
3b0d540
17ca955
7eccae8
a66d97e
81f711d
6cc77b8
5dedfd4
b03fde9
a04b4c8
6a204d4
fdc67c7
7ac8515
b70c904
e472b02
de71707
0e439af
8d59c9e
5a02381
283fae0
fb01018
5856d7b
09356d6
493e5b3
59a97df
32e8e5d
274ef00
66b661d
ef3cc84
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
PREP(addFreeSeatsActions); | ||
PREP(canShowFreeSeats); | ||
PREP(getInNearest); | ||
PREP(moduleInit); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
#include "script_component.hpp" | ||
/* | ||
* Author: Dystopian | ||
* Creates actions for vehicle free seats. | ||
* | ||
* Arguments: | ||
* 0: Vehicle <OBJECT> | ||
* 1: Unit <OBJECT> | ||
* | ||
* Return Value: | ||
* Child actions <ARRAY> | ||
* | ||
* Example: | ||
* [cursorObject, player] call ace_quickmount_fnc_addFreeSeatsActions | ||
* | ||
* Public: No | ||
*/ | ||
|
||
#define TO_COMPARTMENT_STRING(var) if !(var isEqualType "") then {var = format [ARR_2("Compartment%1",var)]} | ||
|
||
// this will check UAV vehicle like Stomper (with cargo seat) | ||
#define IS_CREW_UAV(vehicleConfig) ("UAVPilot" == getText (configFile >> "CfgVehicles" >> getText (vehicleConfig >> "crew") >> "simulation")) | ||
|
||
// workaround getting damage when moveout while vehicle is moving | ||
#define MOVEOUT_AND_BLOCK_DAMAGE \ | ||
if (isDamageAllowed _player) then { \ | ||
_player allowDamage false; \ | ||
SETVAR(_player,GVAR(damageBlocked),true); \ | ||
}; \ | ||
moveOut _player; | ||
|
||
// this is used in statements when move from driver | ||
#define MOVEOUT_AND_BLOCK_DAMAGE_AND_CHECK_ENGINE_ON \ | ||
private _preserveEngineOn = _player == driver _target && {isEngineOn _target}; \ | ||
MOVEOUT_AND_BLOCK_DAMAGE; \ | ||
if (_preserveEngineOn) then {_target engineOn true}; | ||
|
||
// moveIn right after moveOut doesn't work in MP for non-local vehicles, player just stays out | ||
// we have to wait some time (e.g. until player is out) | ||
// usually it takes 1 frame in SP and 3 frames in MP, so in MP looks a little lagging | ||
// also if unit isn't moved to new seat in 0.5 seconds, we move him back to his seat | ||
#define MOVE_IN(command) \ | ||
[ARR_3( \ | ||
{isNull objectParent (_this select 0)}, \ | ||
{ \ | ||
params [ARR_2("_player","_moveInParams")]; \ | ||
_player command _moveInParams; \ | ||
[ARR_5( \ | ||
{!isNull objectParent _this}, \ | ||
{ \ | ||
if (GETVAR(_this,GVAR(damageBlocked),false)) then { \ | ||
_this allowDamage true; \ | ||
SETVAR(_this,GVAR(damageBlocked),nil); \ | ||
}; \ | ||
}, \ | ||
_player, \ | ||
0.5, \ | ||
{ \ | ||
(_this getVariable QGVAR(moveBackParams)) call (_this getVariable QGVAR(moveBackCode)); \ | ||
if (GETVAR(_this,GVAR(damageBlocked),false)) then { \ | ||
_this allowDamage true; \ | ||
SETVAR(_this,GVAR(damageBlocked),nil); \ | ||
}; \ | ||
} \ | ||
)] call CBA_fnc_waitUntilAndExecute; \ | ||
}, \ | ||
[ARR_2(_player,_this select 2)] \ | ||
)] call CBA_fnc_waitUntilAndExecute; | ||
|
||
#define ICON_DRIVER "A3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\role_driver_ca.paa" | ||
#define ICON_PILOT "A3\ui_f\data\IGUI\Cfg\Actions\getinpilot_ca.paa" | ||
#define ICON_CARGO "A3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\role_cargo_ca.paa" | ||
#define ICON_GUNNER "A3\ui_f\data\IGUI\Cfg\Actions\getingunner_ca.paa" | ||
#define ICON_COMMANDER "A3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\role_commander_ca.paa" | ||
#define ICON_TURRET "A3\ui_f\data\IGUI\RscIngameUI\RscUnitInfo\role_gunner_ca.paa" | ||
#define ICON_FFV "A3\ui_f\data\IGUI\Cfg\CrewAimIndicator\gunnerAuto_ca.paa" | ||
|
||
scopeName "main"; | ||
|
||
params ["_vehicle", "_player"]; | ||
|
||
private _vehicleConfig = configFile >> "CfgVehicles" >> typeOf _vehicle; | ||
private _isInVehicle = _player in _vehicle; | ||
private _fullCrew = fullCrew [_vehicle, "", true]; | ||
|
||
private ["_driverCompartments", "_isDriverIsolated", "_cargoCompartments", "_cargoCompartmentsLast", "_compartment"]; | ||
|
||
if (_isInVehicle) then { | ||
_driverCompartments = (_vehicleConfig >> "driverCompartments") call BIS_fnc_getCfgData; | ||
// Air class by default has driverCompartments=0 and cargoCompartments[]={0}, so we have to disable them | ||
_isDriverIsolated = _driverCompartments isEqualTo 0 && {_vehicle isKindOf "Air"}; | ||
TO_COMPARTMENT_STRING(_driverCompartments); | ||
|
||
_cargoCompartments = getArray (_vehicleConfig >> "cargoCompartments"); | ||
{ | ||
if !(_x isEqualType "") then { | ||
_cargoCompartments set [_forEachIndex, format ["Compartment%1", _x]]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Look how it was with Macro sets variable not array member so I can't use it here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will test in a week There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't understand how it can be. If you are doing the same thing, but with less commands and less variables (forEachIndex) it shouldn't possibly be slower. Edit: Ah understood now.
yeah they aren't. My variant copies _x if it's already a string. Yours just does nothing. Do you have an example vehicle where cargoCompartments isn't actually an array of strings? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 0.0083 ms
vs
when There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dedmen when you edit your message nobody gets notification unlike when you create message (maybe in github desktop?). I really accidentally found your question.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well I expected you read the message on github. Instead of in a notification E-Mail or wherever. |
||
}; | ||
} forEach _cargoCompartments; | ||
_cargoCompartmentsLast = count _cargoCompartments - 1; | ||
|
||
TRACE_2("",_driverCompartments,_cargoCompartments); | ||
|
||
// find current compartment | ||
( | ||
_fullCrew select (_fullCrew findIf {_player == _x select 0}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this will error if player is not in crew. Are you sure he is? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, |
||
) params ["", "_role", "_cargoIndex", "_turretPath"]; | ||
|
||
switch (_role) do { | ||
case "driver": { | ||
if (_isDriverIsolated) then { | ||
[] breakOut "main"; | ||
}; | ||
_compartment = _driverCompartments; | ||
_player setVariable [QGVAR(moveBackCode), {(_this select 0) moveInDriver (_this select 1)}]; | ||
_player setVariable [QGVAR(moveBackParams), [_player, _vehicle]]; | ||
}; | ||
case "cargo": { | ||
private _cargoNumber = fullCrew [_vehicle, "cargo", true] findIf {_player == _x select 0}; | ||
_compartment = _cargoCompartments select (_cargoNumber min _cargoCompartmentsLast); | ||
_player setVariable [QGVAR(moveBackCode), {(_this select 0) moveInCargo (_this select 1)}]; | ||
_player setVariable [QGVAR(moveBackParams), [_player, [_vehicle, _cargoIndex]]]; | ||
}; | ||
default { | ||
private _turretConfig = [_vehicleConfig, _turretPath] call CBA_fnc_getTurret; | ||
_compartment = (_turretConfig >> "gunnerCompartments") call BIS_fnc_getCfgData; | ||
TO_COMPARTMENT_STRING(_compartment); | ||
_player setVariable [QGVAR(moveBackCode), {(_this select 0) moveInTurret (_this select 1)}]; | ||
_player setVariable [QGVAR(moveBackParams), [_player, [_vehicle, _turretPath]]]; | ||
}; | ||
}; | ||
TRACE_4("",_role,_cargoIndex,_turretPath,_compartment); | ||
}; | ||
|
||
private _actions = []; | ||
private _cargoNumber = -1; | ||
{ | ||
scopeName "crewLoop"; | ||
_x params ["_unit", "_role", "_cargoIndex", "_turretPath", "_isPersonTurret"]; | ||
if (!isNull _unit && {alive _unit}) then { | ||
if (_role == "cargo") then { | ||
INC(_cargoNumber); | ||
}; | ||
} else { | ||
private ["_name", "_icon", "_statement", "_params"]; | ||
switch (toLower _role) do { | ||
case "driver": { | ||
if ( | ||
lockedDriver _vehicle | ||
|| {IS_CREW_UAV(_vehicleConfig)} | ||
|| {0 == getNumber (_vehicleConfig >> "hasDriver")} | ||
) then { | ||
breakTo "crewLoop"; | ||
}; | ||
if (_isInVehicle) then { | ||
if (_compartment != _driverCompartments || {_isDriverIsolated}) then {breakTo "crewLoop"}; | ||
_params = _vehicle; | ||
_statement = {MOVEOUT_AND_BLOCK_DAMAGE; MOVE_IN(moveInDriver)}; | ||
} else { | ||
_params = ["GetInDriver", _vehicle]; | ||
_statement = {_player action (_this select 2)}; | ||
}; | ||
if (_vehicle isKindOf "Air") then { | ||
_name = localize "str_getin_pos_pilot"; | ||
_icon = ICON_PILOT; | ||
} else { | ||
_name = localize "str_driver"; | ||
_icon = ICON_DRIVER; | ||
}; | ||
}; | ||
case "cargo": { | ||
INC(_cargoNumber); | ||
if (_vehicle lockedCargo _cargoIndex) then {breakTo "crewLoop"}; | ||
if (_isInVehicle) then { | ||
if (_compartment != (_cargoCompartments select (_cargoNumber min _cargoCompartmentsLast))) then {breakTo "crewLoop"}; | ||
_params = [_vehicle, _cargoIndex]; | ||
_statement = {MOVEOUT_AND_BLOCK_DAMAGE_AND_CHECK_ENGINE_ON; MOVE_IN(moveInCargo)}; | ||
} else { | ||
_params = ["GetInCargo", _vehicle, _cargoNumber]; | ||
_statement = {_player action (_this select 2)}; | ||
}; | ||
_name = format ["%1 %2", localize "str_getin_pos_passenger", _cargoNumber + 1]; | ||
_icon = ICON_CARGO; | ||
}; | ||
default { // all turrets including FFV | ||
if (_vehicle lockedTurret _turretPath) then {breakTo "crewLoop"}; | ||
if (_role == "gunner" && {IS_CREW_UAV(_vehicleConfig)}) then {breakTo "crewLoop"}; | ||
private _turretConfig = [_vehicleConfig, _turretPath] call CBA_fnc_getTurret; | ||
if (_isInVehicle) then { | ||
private _gunnerCompartments = (_turretConfig >> "gunnerCompartments") call BIS_fnc_getCfgData; | ||
TO_COMPARTMENT_STRING(_gunnerCompartments); | ||
if (_compartment != _gunnerCompartments) then {breakTo "crewLoop"}; | ||
_params = [_vehicle, _turretPath]; | ||
_statement = {MOVEOUT_AND_BLOCK_DAMAGE_AND_CHECK_ENGINE_ON; MOVE_IN(moveInTurret)}; | ||
} else { | ||
_params = ["GetInTurret", _vehicle, _turretPath]; | ||
_statement = {_player action (_this select 2)}; | ||
}; | ||
_name = getText (_turretConfig >> "gunnerName"); | ||
_icon = switch true do { | ||
case (0 < getNumber (_turretConfig >> "isCopilot")): {ICON_PILOT}; | ||
case (_role == "gunner"): {ICON_GUNNER}; | ||
case (_role == "commander"): {ICON_COMMANDER}; | ||
case (_isPersonTurret): {ICON_FFV}; | ||
case ("" isEqualTo getText (_turretConfig >> "gun")): {ICON_CARGO}; | ||
default {ICON_TURRET}; | ||
}; | ||
}; | ||
}; | ||
private _action = [ | ||
format ["%1%2%3", _role, _cargoIndex, _turretPath], | ||
_name, _icon, _statement, {true}, {}, _params | ||
] call EFUNC(interact_menu,createAction); | ||
_actions pushBack [_action, [], _vehicle]; | ||
}; | ||
} forEach _fullCrew; | ||
|
||
_actions |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#include "script_component.hpp" | ||
/* | ||
* Author: Dystopian | ||
* Checks if Free Seats menu can be shown. | ||
* | ||
* Arguments: | ||
* 0: Vehicle <OBJECT> | ||
* 1: Unit <OBJECT> | ||
* | ||
* Return Value: | ||
* Can show menu <BOOL> | ||
* | ||
* Example: | ||
* [cursorObject, player] call ace_quickmount_fnc_canShowFreeSeats | ||
* | ||
* Public: No | ||
*/ | ||
|
||
params ["_vehicle", "_unit"]; | ||
|
||
( | ||
GVAR(enabled) && {GVAR(enableGetInMenu)} | ||
|| {!isNull objectParent _unit} | ||
PabstMirror marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) | ||
&& {alive _vehicle} | ||
&& {2 > locked _vehicle} | ||
&& { | ||
-1 == crew _vehicle findIf {alive _x} | ||
|| {0.6 <= side group _unit getFriend side group _vehicle} | ||
} | ||
&& { | ||
0.3 < vectorUp _vehicle select 2 // moveIn* and GetIn* don't work for flipped vehicles | ||
|| {_vehicle isKindOf "Air"} // except Air | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,43 @@ | ||
[ | ||
QGVAR(enabled), | ||
"CHECKBOX", | ||
localize ELSTRING(common,Enabled), | ||
format ["ACE %1", localize LSTRING(Category)], | ||
ELSTRING(common,Enabled), | ||
format ["ACE %1", LLSTRING(Category)], | ||
true, | ||
true | ||
] call CBA_settings_fnc_init; | ||
|
||
[ | ||
QGVAR(distance), | ||
"SLIDER", | ||
[localize LSTRING(Distance), localize LSTRING(DistanceDescription)], | ||
format ["ACE %1", localize LSTRING(Category)], | ||
[LSTRING(Distance), LSTRING(DistanceDescription)], | ||
format ["ACE %1", LLSTRING(Category)], | ||
[0, 10, DEFAULT_DISTANCE, 0], | ||
true | ||
] call CBA_settings_fnc_init; | ||
|
||
[ | ||
QGVAR(speed), | ||
"SLIDER", | ||
[localize LSTRING(Speed), localize LSTRING(SpeedDescription)], | ||
format ["ACE %1", localize LSTRING(Category)], | ||
[LSTRING(Speed), LSTRING(SpeedDescription)], | ||
format ["ACE %1", LLSTRING(Category)], | ||
[0, 30, DEFAULT_SPEED, 0], | ||
true | ||
] call CBA_settings_fnc_init; | ||
|
||
[ | ||
QGVAR(priority), | ||
"LIST", | ||
[localize LSTRING(Priority), localize LSTRING(PriorityDescription)], | ||
format ["ACE %1", localize LSTRING(Category)], | ||
[[0, 1, 2, 3], [localize "str_getin_pos_driver", localize "str_getin_pos_gunn", localize "str_getin_pos_comm", localize "str_getin_pos_passenger"], DEFAULT_PRIORITY], | ||
[LSTRING(Priority), LSTRING(PriorityDescription)], | ||
format ["ACE %1", LLSTRING(Category)], | ||
[[0, 1, 2, 3], ["str_getin_pos_driver", "str_getin_pos_gunn", "str_getin_pos_comm", "str_getin_pos_passenger"], DEFAULT_PRIORITY], | ||
false | ||
] call CBA_settings_fnc_init; | ||
|
||
[ | ||
QGVAR(enableGetInMenu), | ||
"CHECKBOX", | ||
LSTRING(SettingEnableGetInMenuName), | ||
format ["ACE %1", LLSTRING(Category)], | ||
true | ||
] call CBA_settings_fnc_init; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might want to use
[_player, "blockDamage", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EFUNC(common,statusEffect_set)
would set global variable twice in 1 second. I don't think it's worth it to use it just for 1 secondallowDamage
.