diff --git a/AUTHORS.txt b/AUTHORS.txt index abb66683b8..4fe978dd40 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -128,6 +128,7 @@ Tessa Elieff Toaster Tonic Tourorist +Tuupertunut Valentin Torikian voiper VyMajoris(W-Cephei) diff --git a/addons/captives/CfgVehicles.hpp b/addons/captives/CfgVehicles.hpp index 6a93d35195..45a3f323e6 100644 --- a/addons/captives/CfgVehicles.hpp +++ b/addons/captives/CfgVehicles.hpp @@ -51,6 +51,7 @@ class CfgVehicles { showDisabled = 0; icon = QPATHTOF(UI\captive_ca.paa); priority = 2.2; + insertChildren = QUOTE(call DFUNC(addLoadCaptiveActions)); }; class GVAR(UnloadCaptive) { displayName = CSTRING(UnloadCaptive); diff --git a/addons/captives/XEH_PREP.hpp b/addons/captives/XEH_PREP.hpp index 9ce78e438a..bf0b06a1db 100644 --- a/addons/captives/XEH_PREP.hpp +++ b/addons/captives/XEH_PREP.hpp @@ -1,3 +1,4 @@ +PREP(addLoadCaptiveActions); PREP(canApplyHandcuffs); PREP(canEscortCaptive); PREP(canFriskPerson); diff --git a/addons/captives/functions/fnc_addLoadCaptiveActions.sqf b/addons/captives/functions/fnc_addLoadCaptiveActions.sqf new file mode 100644 index 0000000000..0c7adbda7a --- /dev/null +++ b/addons/captives/functions/fnc_addLoadCaptiveActions.sqf @@ -0,0 +1,25 @@ +/* + * Author: 654wak654 + * Adds child actions to the "load captive" action for near vehicles. + * + * Arguments: + * 0: Captive + * + * Return Value: + * Child actions + * + * Example: + * [kevin] call ace_medical_fnc_addLoadCaptiveActions + * + * Public: No + */ +#include "script_component.hpp" + +params ["_target"]; + +private _statement = { + params ["_target", "_player", "_vehicle"]; + [_player, _target, _vehicle] call FUNC(doLoadCaptive); +}; + +[_target call EFUNC(common,nearestVehiclesFreeSeat), _statement, _target] call EFUNC(interact_menu,createVehiclesActions) diff --git a/addons/captives/functions/fnc_canLoadCaptive.sqf b/addons/captives/functions/fnc_canLoadCaptive.sqf index b968f1754a..782661ea1c 100644 --- a/addons/captives/functions/fnc_canLoadCaptive.sqf +++ b/addons/captives/functions/fnc_canLoadCaptive.sqf @@ -4,20 +4,20 @@ * * Arguments: * 0: Unit that wants to load a captive - * 1: A captive. ObjNull for the first escorted captive (may be null) - * 2: Vehicle to load the captive into. ObjNull for the nearest vehicle (may be null) + * 1: A captive. objNull for the first escorted captive + * 2: Vehicle to load the captive into. objNull for the nearest vehicle * * Return Value: - * The return value + * Can load captive * * Example: - * [player, bob, car] call ACE_captives_fnc_canLoadCaptive + * [bob, tom, car] call ace_captives_fnc_canLoadCaptive * * Public: No */ #include "script_component.hpp" -params ["_unit", "_target","_vehicle"]; +params ["_unit", "_target", "_vehicle"]; // Don't show "Load Captive" if unit is unconscious (already has "Load Patient") if (_target getVariable ["ACE_isUnconscious", false]) exitWith {false}; @@ -30,20 +30,16 @@ if ((isNull _target) && {_unit getVariable [QGVAR(isEscorting), false]}) then { }; } forEach (attachedObjects _unit); }; -if ((isNull _target) || {(vehicle _target) != _target} || {!(_target getVariable [QGVAR(isHandcuffed), false])}) exitWith {false}; +if (isNull _target || {(vehicle _target) != _target} || {!(_target getVariable [QGVAR(isHandcuffed), false])}) exitWith {false}; if (isNull _vehicle) then { - //Looking at a captive unit, search for nearby vehicles with valid seats: - { - if ((_x emptyPositions "cargo") > 0) exitWith { - _vehicle = _x; - }; - } forEach (nearestObjects [_unit, ["Car", "Tank", "Helicopter", "Plane", "Ship"], 10]); + // Looking at a captive unit, get nearest vehicle with valid seat: + _vehicle = (_target call EFUNC(common,nearestVehiclesFreeSeat)) param [0, objNull]; } else { - //We have a vehicle picked, make sure it has empty seats: - if ((_vehicle emptyPositions "cargo") == 0) then { + // We have a vehicle picked, make sure it has empty seats: + if (_vehicle emptyPositions "cargo" == 0 && {_vehicle emptyPositions "gunner" == 0}) then { _vehicle = objNull; }; }; -(!isNull _vehicle) +!isNull _vehicle diff --git a/addons/captives/functions/fnc_doLoadCaptive.sqf b/addons/captives/functions/fnc_doLoadCaptive.sqf index 82e446b460..c47cc389d4 100644 --- a/addons/captives/functions/fnc_doLoadCaptive.sqf +++ b/addons/captives/functions/fnc_doLoadCaptive.sqf @@ -4,42 +4,37 @@ * * Arguments: * 0: Unit that wants to load a captive - * 1: A captive. ObjNull for the first escorted captive - * 2: Vehicle to load the captive into. ObjNull for the nearest vehicle + * 1: A captive. objNull for the first escorted captive + * 2: Vehicle to load the captive into. objNull for the nearest vehicle * * Return Value: * None * * Example: - * [bob, tom, car] call ACE_captives_fnc_doLoadCaptive + * [bob, tom, car] call ace_captives_fnc_doLoadCaptive * * Public: No */ #include "script_component.hpp" -params ["_unit", "_target","_vehicle"]; +params ["_unit", "_target", "_vehicle"]; -if ((isNull _target) && {_unit getVariable [QGVAR(isEscorting), false]}) then { - //Looking at a vehicle while escorting, get target from attached objects: +if (isNull _target && {_unit getVariable [QGVAR(isEscorting), false]}) then { + // Looking at a vehicle while escorting, get target from attached objects: { if (_x getVariable [QGVAR(isHandcuffed), false]) exitWith { _target = _x; }; } forEach (attachedObjects _unit); }; -if ((isNull _target) || {(vehicle _target) != _target} || {!(_target getVariable [QGVAR(isHandcuffed), false])}) exitWith {WARNING("");}; +if (isNull _target || {(vehicle _target) != _target} || {!(_target getVariable [QGVAR(isHandcuffed), false])}) exitWith {WARNING("");}; if (isNull _vehicle) then { - //Looking at a captive unit, search for nearby vehicles with valid seats: - { - // if (([_x] call FUNC(findEmptyNonFFVCargoSeat)) != -1) exitWith { - if ((_x emptyPositions "cargo") > 0) exitWith { - _vehicle = _x; - }; - } forEach (nearestObjects [_unit, ["Car", "Tank", "Helicopter", "Plane", "Ship"], 10]); + // Looking at a captive unit, get nearest vehicle with valid seat: + _vehicle = (_target call EFUNC(common,nearestVehiclesFreeSeat)) param [0, objNull]; } else { - // if (([_vehicle] call FUNC(findEmptyNonFFVCargoSeat)) == -1) then { - if ((_vehicle emptyPositions "cargo") == 0) then { + // We have a vehicle picked, make sure it has empty seats: + if (_vehicle emptyPositions "cargo" == 0 && {_vehicle emptyPositions "gunner" == 0}) then { _vehicle = objNull; }; }; diff --git a/addons/captives/functions/fnc_findEmptyNonFFVCargoSeat.sqf b/addons/captives/functions/fnc_findEmptyNonFFVCargoSeat.sqf index 63792a7c55..91bb800c05 100644 --- a/addons/captives/functions/fnc_findEmptyNonFFVCargoSeat.sqf +++ b/addons/captives/functions/fnc_findEmptyNonFFVCargoSeat.sqf @@ -18,20 +18,18 @@ params ["_vehicle"]; TRACE_1("params", _vehicle); -private _vehicleConfig = configFile >> "CfgVehicles" >> (typeOf _vehicle); - scopeName "main"; { _x params ["_unit", "_role", "_cargoIndex", "_turretPath", "_isPersonTurret"]; - if ((isNull _unit) && {_role == "cargo"} && {_cargoIndex > -1} && {!_isPersonTurret}) then { + if (isNull _unit && {_role == "cargo"} && {_cargoIndex > -1} && {!_isPersonTurret}) then { [_cargoIndex, false] breakOut "main"; }; } forEach (fullCrew [_vehicle, "", true]); { _x params ["_unit", "_role", "_cargoIndex", "_turretPath", "_isPersonTurret"]; - if ((isNull _unit) && {_cargoIndex > -1}) then { + if (isNull _unit && {_cargoIndex > -1}) then { [_cargoIndex, true] breakOut "main"; }; } forEach (fullCrew [_vehicle, "", true]); diff --git a/addons/captives/stringtable.xml b/addons/captives/stringtable.xml index 9056351363..80769e88fe 100644 --- a/addons/captives/stringtable.xml +++ b/addons/captives/stringtable.xml @@ -314,7 +314,7 @@ Saját oldal megbilincselhető Связать союзника Puoi ammanettare unità alleate - 自陣営への拘束を可能に + 拘束ユニットを自陣営へ 자기편에게 수갑을 채울 수 있게 합니다 可以銬住同陣營隊友 可以铐住同阵营队友 @@ -330,7 +330,7 @@ A játékosok megkötözhetik-e a saját oldalukon lévő egységeket Разрешить игрокам связывать юнитов своей стороны I giocatori possono ammanettare unità alleate - プレイヤーがユニットを拘束し、彼らの陣営に変更できます。 + プレイヤーが拘束したユニットの陣営を自陣営に変更させ。 자기편에게 케이블타이를 사용할 수 있게합니다 玩家可以使用束線帶銬住同陣營隊友 玩家可以使用束线带铐住同阵营队友 @@ -362,7 +362,7 @@ A játékosok megadhatják magukat a fegyverük elrakása után Игроки могут сдаться в плен после того, как уберут оружие I giocatori possono arrendersi dopo aver messo via le proprie armi - プレイヤーは武器を収めたあとに投降できるようにします。 + プレイヤーは武器を収めたあと投降できるようにします。 비무장한 플레이어가 투항할 수 있게 합니다 玩家能在收起自己武器後投降 玩家能在收起自己武器后投降 @@ -430,6 +430,8 @@ Sets the unit under the cursor captive. Nimmt die Einheit vor dem Cursor fest. + カーソル先のユニットを拘束 + Imposta l'unità nello stato di prigioniero. Require AI surrendering diff --git a/addons/cargo/functions/fnc_addCargoVehiclesActions.sqf b/addons/cargo/functions/fnc_addCargoVehiclesActions.sqf index 176b2f31b6..111407e3fe 100644 --- a/addons/cargo/functions/fnc_addCargoVehiclesActions.sqf +++ b/addons/cargo/functions/fnc_addCargoVehiclesActions.sqf @@ -4,42 +4,28 @@ * * Arguments: * 0: Target - * 1: Player * * Return Value: - * Children actions + * Child actions * * Example: - * [target, player] call ace_cargo_fnc_addCargoVehiclesActions + * [cursorObject] call ace_cargo_fnc_addCargoVehiclesActions * * Public: No */ #include "script_component.hpp" -params ["_target", "_player"]; +params ["_target"]; private _statement = { - params ["_target", "_player", "_params"]; - _params params ["_vehicle"]; + params ["_target", "_player", "_vehicle"]; [_player, _target, _vehicle] call FUNC(startLoadIn); }; -private _actions = []; - -{ - private _config = configFile >> "CfgVehicles" >> typeOf _x; +private _vehicles = (nearestObjects [_target, GVAR(cargoHolderTypes), MAX_LOAD_DISTANCE]) select { + private _hasCargoConfig = 1 == getNumber (configFile >> "CfgVehicles" >> typeOf _x >> QGVAR(hasCargo)); private _hasCargoPublic = _x getVariable [QGVAR(hasCargo), false]; - private _hasCargoConfig = getNumber (_config >> QGVAR(hasCargo)) == 1; - if ((_hasCargoPublic || _hasCargoConfig) && {_x != _target}) then { - private _name = getText (_config >> "displayName"); - private _ownerName = [_x, true] call EFUNC(common,getName); - if ("" != _ownerName) then { - _name = format ["%1 (%2)", _name, _ownerName]; - }; - private _icon = (getText (_config >> "icon")) call BIS_fnc_textureVehicleIcon; - private _action = [format ["%1", _x], _name, _icon, _statement, {true}, {}, [_x]] call EFUNC(interact_menu,createAction); - _actions pushBack [_action, [], _target]; - }; -} forEach (nearestObjects [_player, GVAR(cargoHolderTypes), MAX_LOAD_DISTANCE]); + (_hasCargoConfig || {_hasCargoPublic}) && {_x != _target} +}; -_actions +[_vehicles, _statement, _target] call EFUNC(interact_menu,createVehiclesActions) diff --git a/addons/cargo/functions/fnc_initObject.sqf b/addons/cargo/functions/fnc_initObject.sqf index 5020f885b6..e291cc54f3 100644 --- a/addons/cargo/functions/fnc_initObject.sqf +++ b/addons/cargo/functions/fnc_initObject.sqf @@ -53,7 +53,7 @@ private _condition = { {(_target getVariable [QGVAR(canLoad), getNumber (configFile >> "CfgVehicles" >> (typeOf _target) >> QGVAR(canLoad))]) in [true, 1]} && {locked _target < 2} && {alive _target} && - {[_player, _target, []] call EFUNC(common,canInteractWith)} && + {[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} && {0 < { private _type = typeOf _x; private _hasCargoPublic = _x getVariable [QGVAR(hasCargo), false]; diff --git a/addons/cargo/functions/fnc_startLoadIn.sqf b/addons/cargo/functions/fnc_startLoadIn.sqf index 4fa0401772..447c679df0 100644 --- a/addons/cargo/functions/fnc_startLoadIn.sqf +++ b/addons/cargo/functions/fnc_startLoadIn.sqf @@ -42,7 +42,9 @@ if ([_object, _vehicle] call FUNC(canLoadItemIn)) then { [_object,_vehicle], {["ace_loadCargo", _this select 0] call CBA_fnc_localEvent}, {}, - localize LSTRING(LoadingItem) + localize LSTRING(LoadingItem), + {true}, + ["isNotSwimming"] ] call EFUNC(common,progressBar); _return = true; } else { diff --git a/addons/common/XEH_PREP.hpp b/addons/common/XEH_PREP.hpp index e39b55e5cb..823fa563f8 100644 --- a/addons/common/XEH_PREP.hpp +++ b/addons/common/XEH_PREP.hpp @@ -105,6 +105,7 @@ PREP(isInBuilding); PREP(isMedic); PREP(isModLoaded); PREP(isPlayer); +PREP(isSwimming); PREP(isUnderwater); PREP(lightIntensityFromObject); PREP(loadPerson); @@ -117,6 +118,7 @@ PREP(moduleLSDVehicles); PREP(muteUnit); PREP(muteUnitHandleInitPost); PREP(muteUnitHandleRespawn); +PREP(nearestVehiclesFreeSeat); PREP(numberToDigits); PREP(numberToDigitsString); PREP(numberToString); diff --git a/addons/common/functions/fnc_fixPosition.sqf b/addons/common/functions/fnc_fixPosition.sqf index fb14141fe2..b00c08f25a 100644 --- a/addons/common/functions/fnc_fixPosition.sqf +++ b/addons/common/functions/fnc_fixPosition.sqf @@ -1,6 +1,5 @@ /* - * Author: commy2 - * + * Author: commy2, Jonpas * Fixes position of an object. E.g. moves object above ground and adjusts to terrain slope. Requires local object. * * Arguments: @@ -10,7 +9,7 @@ * None * * Example: - * [bob] call ace_common_fnc_fixPosition + * bob call ace_common_fnc_fixPosition * * Public: No */ @@ -19,25 +18,28 @@ // setVectorUp requires local object if (!local _this) exitWith {}; -if ((getText (configFile >> "CfgVehicles" >> (typeOf _this) >> "simulation")) == "house") then { - //Houses don't have gravity/physics, so make sure they are not floating - private _posAbove = (getPos _this) select 2; +// Objects with disabled simulation and objects with simulation type "house" don't have gravity/physics, so make sure they are not floating +private _hasGravity = simulationEnabled _this && {!(getText (configFile >> "CfgVehicles" >> typeOf _this >> "simulation") == "house")}; + +if (!_hasGravity) then { + private _posAbove = (getPosATL _this) select 2; TRACE_2("house",_this,_posAbove); if (_posAbove > 0.1) then { - private _newPosASL = (getPosASL _this) vectorDiff [0,0,_posAbove]; - _this setPosASL _newPosASL; + private _newPosATL = (getPosATL _this) vectorDiff [0, 0, _posAbove]; + _this setPosATL _newPosATL; }; }; -private _position = getPos _this; +private _position = getPosATL _this; -// don't place the object below the ground +// Don't place the object below the ground if (_position select 2 < -0.1) then { _position set [2, -0.1]; - _this setPos _position; + _this setPosATL _position; }; -// adjust position to sloped terrain, if placed on ground -if (getPosATL _this select 2 == _position select 2) then { +// Adjust position to sloped terrain, if placed on ground +// Object without gravity/physics may have negative height when placed on slope, but those objects are definitely on the ground +if (!_hasGravity || {getPosATL _this select 2 == _position select 2}) then { _this setVectorUp surfaceNormal _position; }; diff --git a/addons/common/functions/fnc_goKneeling.sqf b/addons/common/functions/fnc_goKneeling.sqf index b838a4f047..5d45a3f400 100644 --- a/addons/common/functions/fnc_goKneeling.sqf +++ b/addons/common/functions/fnc_goKneeling.sqf @@ -1,6 +1,6 @@ /* * Author: commy2 - * Move unit to kneeling position (only if not yet prone). + * Move unit to kneeling position (only if not yet prone and not underwater). * * Arguments: * 0: Unit @@ -18,7 +18,7 @@ params ["_unit"]; // Animation changes even inside vehicle post-1.60 -if (stance _unit == "PRONE" || {vehicle ACE_player != ACE_player}) exitWith {}; +if (stance _unit == "PRONE" || {vehicle _unit != _unit} || {_unit call EFUNC(common,isSwimming)}) exitWith {}; [ _unit, diff --git a/addons/common/functions/fnc_isSwimming.sqf b/addons/common/functions/fnc_isSwimming.sqf new file mode 100644 index 0000000000..8aee92ad81 --- /dev/null +++ b/addons/common/functions/fnc_isSwimming.sqf @@ -0,0 +1,20 @@ +/* + * Author: das attorney, Jonpas + * Check if unit is swimming (surface swimming or diving). + * + * Arguments: + * 0: Unit + * + * Return Value: + * If unit is swimming + * + * Example: + * [bob] call ace_common_fnc_isSwimming + * + * Public: Yes + */ +#include "script_component.hpp" + +params [["_unit", objNull, [objNull]]]; + +((animationState _unit) select [1, 3]) in ["bdv","bsw","dve","sdv","ssw","swm"] diff --git a/addons/common/functions/fnc_loadPerson.sqf b/addons/common/functions/fnc_loadPerson.sqf index ae762b82be..4fc6245b5a 100644 --- a/addons/common/functions/fnc_loadPerson.sqf +++ b/addons/common/functions/fnc_loadPerson.sqf @@ -1,13 +1,14 @@ /* * Author: Glowbal - * Loads a specified unit into any nearby vehicle + * Loads a specified unit into any nearby vehicle, or _vehicle parameter. * * Arguments: * 0: Unit that will load * 1: Unit to be loaded + * 2: Vehicle that the unit will be loaded in (default: objNull) * * Return Value: - * the vehicle that the unitToBeloaded has been loaded in. Returns ObjNull if function failed + * Vehicle that the unitToBeloaded has been loaded in. Returns objNull if function failed * * Example: * [bob, kevin] call ace_common_fnc_loadPerson @@ -18,20 +19,14 @@ #define GROUP_SWITCH_ID QFUNC(loadPerson) -params ["_caller", "_unit"]; +params ["_caller", "_unit", ["_vehicle", objNull]]; -private _vehicle = objNull; +if (!([_caller, _unit, ["isNotDragging", "isNotCarrying", "isNotSwimming"]] call FUNC(canInteractWith)) || {_caller == _unit}) exitWith {_vehicle}; -if (!([_caller, _unit, ["isNotDragging", "isNotCarrying"]] call FUNC(canInteractWith)) || {_caller == _unit}) exitWith {_vehicle}; - -private _nearVehicles = nearestObjects [_unit, ["Car", "Air", "Tank", "Ship_F","Pod_Heli_Transport_04_crewed_base_F"], 10]; - -{ - TRACE_1("",_x); - if ((_x emptyPositions "cargo" > 0) || {_x emptyPositions "gunner" > 0}) exitWith { - _vehicle = _x; - }; -} forEach _nearVehicles; +// Try to use nearest vehicle if a vehicle hasn't been supplied +if (isNull _vehicle) then { + _vehicle = ([_unit] call FUNC(nearestVehiclesFreeSeat)) param [0, objNull]; +}; if (!isNull _vehicle) then { [_unit, true, GROUP_SWITCH_ID, side group _caller] call FUNC(switchToGroupSide); diff --git a/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf b/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf new file mode 100644 index 0000000000..080499d9cf --- /dev/null +++ b/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf @@ -0,0 +1,22 @@ +/* + * Author: 654wak654 + * Returns a list of vehicles near given unit that the unit can be a passenger in. + * + * Arguments: + * 0: Unit + * 1: Distance + * + * Return Value: + * Nearest vehicles with a free seat + * + * Example: + * [bob] call ace_common_fnc_nearestVehiclesFreeSeat + * + * Public: Yes + */ +#include "script_component.hpp" + +params ["_unit", ["_distance", 10]]; + +private _nearVehicles = nearestObjects [_unit, ["Car", "Air", "Tank", "Ship_F", "Pod_Heli_Transport_04_crewed_base_F"], _distance]; +_nearVehicles select {(_x emptyPositions "cargo" > 0) || {_x emptyPositions "gunner" > 0}} diff --git a/addons/common/stringtable.xml b/addons/common/stringtable.xml index ad1199f642..fc01efb655 100644 --- a/addons/common/stringtable.xml +++ b/addons/common/stringtable.xml @@ -12,7 +12,7 @@ ACE-Team ACE-Team ACE-Team - ACE-Team + ACE-チーム ACE-Team ACE-製作團隊 ACE-制作团队 @@ -1165,7 +1165,7 @@ pecek přep. alternar - トグル + 切り替え 토글 切換 切换 diff --git a/addons/dragging/functions/fnc_canDrag.sqf b/addons/dragging/functions/fnc_canDrag.sqf index b45a7d1d14..31c9810aba 100644 --- a/addons/dragging/functions/fnc_canDrag.sqf +++ b/addons/dragging/functions/fnc_canDrag.sqf @@ -18,7 +18,7 @@ params ["_unit", "_target"]; -if !([_unit, _target, []] call EFUNC(common,canInteractWith)) exitWith {false}; +if !([_unit, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // a static weapon has to be empty for dragging (ignore UAV AI) if ((typeOf _target) isKindOf "StaticWeapon" && {{(getText (configFile >> "CfgVehicles" >> (typeOf _x) >> "simulation")) != "UAVPilot"} count crew _target > 0}) exitWith {false}; diff --git a/addons/dragging/functions/fnc_canDrop.sqf b/addons/dragging/functions/fnc_canDrop.sqf index b9a6170bf2..286f6de3a9 100644 --- a/addons/dragging/functions/fnc_canDrop.sqf +++ b/addons/dragging/functions/fnc_canDrop.sqf @@ -18,6 +18,6 @@ params ["_unit", "_target"]; -if !([_unit, _target, ["isNotDragging"]] call EFUNC(common,canInteractWith)) exitWith {false}; +if !([_unit, _target, ["isNotDragging", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; _unit getVariable [QGVAR(draggedObject), objNull] == _target diff --git a/addons/dragging/functions/fnc_dropObject.sqf b/addons/dragging/functions/fnc_dropObject.sqf index f060c8d088..007f54adef 100644 --- a/addons/dragging/functions/fnc_dropObject.sqf +++ b/addons/dragging/functions/fnc_dropObject.sqf @@ -58,7 +58,7 @@ if (_inBuilding) then { _unit setVariable [QGVAR(isDragging), false, true]; _unit setVariable [QGVAR(draggedObject), objNull, true]; -// make object accesable for other units +// make object accessible for other units [objNull, _target, true] call EFUNC(common,claim); if !(_target isKindOf "CAManBase") then { diff --git a/addons/dragging/functions/fnc_getWeight.sqf b/addons/dragging/functions/fnc_getWeight.sqf index ac2db86ad0..2c63d220fa 100644 --- a/addons/dragging/functions/fnc_getWeight.sqf +++ b/addons/dragging/functions/fnc_getWeight.sqf @@ -31,6 +31,7 @@ private _totalWeight = 0; } forEach _item; true } count [ + //IGNORE_PRIVATE_WARNING ["_x"]; [getMagazineCargo _object, {configFile >> "CfgMagazines" >> _x}], [getBackpackCargo _object, {configFile >> "CfgVehicles" >> _x}], [getItemCargo _object, {configFile >> "CfgWeapons" >> _x >> "ItemInfo"}], diff --git a/addons/dragging/functions/fnc_handleAnimChanged.sqf b/addons/dragging/functions/fnc_handleAnimChanged.sqf index c59b088ee0..2a531ea67c 100644 --- a/addons/dragging/functions/fnc_handleAnimChanged.sqf +++ b/addons/dragging/functions/fnc_handleAnimChanged.sqf @@ -30,7 +30,7 @@ if (_unit != _realUnit) exitWith { if (_unit getVariable [QGVAR(isDragging), false]) then { // drop dragged object when not in valid animation - if !(_anim in DRAG_ANIMATIONS) then { + if (!(_anim in DRAG_ANIMATIONS) && {!(_unit call EFUNC(common,isSwimming))}) then { private _draggedObject = _unit getVariable [QGVAR(draggedObject), objNull]; if (!isNull _draggedObject) then { diff --git a/addons/dragging/functions/fnc_startDrag.sqf b/addons/dragging/functions/fnc_startDrag.sqf index cf08074d94..378128862a 100644 --- a/addons/dragging/functions/fnc_startDrag.sqf +++ b/addons/dragging/functions/fnc_startDrag.sqf @@ -39,9 +39,11 @@ _unit selectWeapon primaryWeapon _unit; [_unit, _target, true] call EFUNC(common,claim); // can't play action that depends on weapon if it was added the same frame -[{ - [_this, "grabDrag"] call EFUNC(common,doGesture); -}, _unit] call CBA_fnc_execNextFrame; +if !(_unit call EFUNC(common,isSwimming)) then { + [{ + [_this, "grabDrag"] call EFUNC(common,doGesture); + }, _unit] call CBA_fnc_execNextFrame; +}; // move a bit closer and adjust direction when trying to pick up a person if (_target isKindOf "CAManBase") then { diff --git a/addons/dragging/functions/fnc_startDragPFH.sqf b/addons/dragging/functions/fnc_startDragPFH.sqf index c7843cfdc9..a5bab835b7 100644 --- a/addons/dragging/functions/fnc_startDragPFH.sqf +++ b/addons/dragging/functions/fnc_startDragPFH.sqf @@ -50,7 +50,7 @@ if (CBA_missionTime > _timeOut) exitWith { }; // unit is ready to start dragging -if (animationState _unit in DRAG_ANIMATIONS) exitWith { +if (animationState _unit in DRAG_ANIMATIONS || {_unit call EFUNC(common,isSwimming)}) exitWith { TRACE_4("Start Dragging",_unit,_target,_timeOut,CBA_missionTime); [_unit, _target] call FUNC(dragObject); diff --git a/addons/dragging/script_component.hpp b/addons/dragging/script_component.hpp index 7a82a9ed3a..01b466972f 100644 --- a/addons/dragging/script_component.hpp +++ b/addons/dragging/script_component.hpp @@ -2,7 +2,7 @@ #define COMPONENT_BEAUTIFIED Dragging #include "\z\ace\addons\main\script_mod.hpp" -//#define DEBUG_ENABLED_DRAGGING +// #define DEBUG_ENABLED_DRAGGING // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS diff --git a/addons/explosives/CfgWeapons.hpp b/addons/explosives/CfgWeapons.hpp index 5f11116199..4eca355909 100644 --- a/addons/explosives/CfgWeapons.hpp +++ b/addons/explosives/CfgWeapons.hpp @@ -1,4 +1,13 @@ class CfgWeapons { + class Default; + class Put: Default { + muzzles[] += {QGVAR(muzzle)}; + class PutMuzzle: Default{}; + class GVAR(muzzle): PutMuzzle { + magazines[] = {"ACE_FlareTripMine_Mag"}; + }; + }; + class ACE_ItemCore; class CBA_MiscItem_ItemInfo; diff --git a/addons/fastroping/stringtable.xml b/addons/fastroping/stringtable.xml index 1e0bc373cb..be478a62c5 100644 --- a/addons/fastroping/stringtable.xml +++ b/addons/fastroping/stringtable.xml @@ -49,6 +49,7 @@ Stow fast roping system Arrotola le corde + ファスト ロープのシステムを収容 Deploy ropes diff --git a/addons/interact_menu/XEH_PREP.hpp b/addons/interact_menu/XEH_PREP.hpp index 55c35d54df..7ee668a583 100644 --- a/addons/interact_menu/XEH_PREP.hpp +++ b/addons/interact_menu/XEH_PREP.hpp @@ -7,6 +7,7 @@ PREP(compileMenuSelfAction); PREP(compileMenuZeus); PREP(collectActiveActionTree); PREP(createAction); +PREP(createVehiclesActions); PREP(ctrlSetParsedTextCached); PREP(findActionNode); PREP(handleEscapeMenu); diff --git a/addons/interact_menu/functions/fnc_createVehiclesActions.sqf b/addons/interact_menu/functions/fnc_createVehiclesActions.sqf new file mode 100644 index 0000000000..6bdc941118 --- /dev/null +++ b/addons/interact_menu/functions/fnc_createVehiclesActions.sqf @@ -0,0 +1,33 @@ +/* + * Author: Dystopian + * Creates child actions for vehicle list. + * Statement gets vehicle as action parameter. + * + * Arguments: + * 0: Vehicle list + * 1: Statement + * 2: Target + * + * Return Value: + * Array of actions + * + * Example: + * [nearestObjects [player, ["AllVehicles"], 10], {}, cursorObject] call ace_interact_menu_fnc_createVehiclesActions + * + * Public: No + */ +#include "script_component.hpp" + +params ["_vehicles", "_statement", "_target"]; + +_vehicles apply { + private _config = configFile >> "CfgVehicles" >> typeOf _x; + private _name = getText (_config >> "displayName"); + private _ownerName = [_x, true] call EFUNC(common,getName); + if ("" != _ownerName) then { + _name = format ["%1 (%2)", _name, _ownerName]; + }; + private _icon = (getText (_config >> "icon")) call BIS_fnc_textureVehicleIcon; + private _action = [format ["%1", _x], _name, _icon, _statement, {true}, {}, _x] call EFUNC(interact_menu,createAction); + [_action, [], _target] +} diff --git a/addons/interaction/XEH_postInit.sqf b/addons/interaction/XEH_postInit.sqf index fc0571ba4c..5d2b49f9b1 100644 --- a/addons/interaction/XEH_postInit.sqf +++ b/addons/interaction/XEH_postInit.sqf @@ -106,7 +106,7 @@ GVAR(isOpeningDoor) = false; {false}, [20, [true, false, false]], false] call CBA_fnc_addKeybind; -["isNotSwimming", {!underwater (_this select 0)}] call EFUNC(common,addCanInteractWithCondition); +["isNotSwimming", {!(_this call EFUNC(common,isSwimming))}] call EFUNC(common,addCanInteractWithCondition); ["isNotOnLadder", {getNumber (configFile >> "CfgMovesMaleSdr" >> "States" >> animationState (_this select 0) >> "ACE_isLadder") != 1}] call EFUNC(common,addCanInteractWithCondition); ["ace_settingsInitialized", { diff --git a/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf b/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf index 4a71677658..45cd71a53b 100644 --- a/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf +++ b/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf @@ -25,7 +25,7 @@ if (_unit != ACE_player) exitWith {}; _timeToCut = if ([_unit] call EFUNC(common,isEngineer)) then {7.5} else {11}; -if (!underwater _unit) then { +if !(_unit call EFUNC(common,isSwimming)) then { [_unit, "AinvPknlMstpSnonWnonDr_medic5", 0] call EFUNC(common,doAnimation); }; @@ -33,7 +33,7 @@ _onCompletion = { TRACE_1("_onCompletion",_this); (_this select 0) params ["_fenceObject", "", "_unit"]; _fenceObject setdamage 1; - if (!underwater _unit) then { + if !(_unit call EFUNC(common,isSwimming)) then { [_unit, "AmovPknlMstpSrasWrflDnon", 1] call EFUNC(common,doAnimation); }; }; @@ -41,7 +41,7 @@ _onCompletion = { _onFail = { TRACE_1("_onFail", _this); (_this select 0) params ["", "", "_unit"]; - if (!underwater _unit) then { + if !(_unit call EFUNC(common,isSwimming)) then { [_unit, "AmovPknlMstpSrasWrflDnon", 1] call EFUNC(common,doAnimation); }; }; diff --git a/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf b/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf index 34418fd422..286db1389b 100644 --- a/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf +++ b/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf @@ -25,7 +25,7 @@ _args params ["_magazineClassname", "_lastAmmoCount"]; private _fullMagazineCount = getNumber (configFile >> "CfgMagazines" >> _magazineClassname >> "count"); // Don't show anything if player can't interact -if (!([ACE_player, objNull, ["isNotInside", "isNotSitting", "isNowSwimming"]] call EFUNC(common,canInteractWith))) exitWith {}; +if (!([ACE_player, objNull, ["isNotInside", "isNotSitting", "isNotSwimming"]] call EFUNC(common,canInteractWith))) exitWith {}; // Count mags private _fullMags = 0; diff --git a/addons/magazinerepack/stringtable.xml b/addons/magazinerepack/stringtable.xml index 8af01c69fb..10e806b316 100644 --- a/addons/magazinerepack/stringtable.xml +++ b/addons/magazinerepack/stringtable.xml @@ -44,7 +44,7 @@ %1 carregador(es) cheio(s) e %2 disparo(s) a mais %1 teljes tár és %2 extra lőszer %1 полных магазина(ов) и %2 патрона(ов) - %1 個の満杯な弾倉と入りきらなかった %2 個の弾倉 + %1 個の満杯な弾倉と入りきらなかった %2 発の弾薬 %1개의 꽉찬 탄창과 %2발의 총알이 남았다 %1个满的弹匣与%2发额外子弹 %1個滿的彈匣與%2發額外子彈 @@ -92,7 +92,7 @@ %1 teljes és %2 részleges %1 pieno(i) e %2 parziale(i) %1 Total e %2 Parcial - %1 個の満杯で、 %2 の余分数 + %1 個の満杯と %2 個の弾薬入り弾倉 %1 꽉찼고 %2 부분참 %1个满的与%2个部分的 %1個滿的與%2個部分的 diff --git a/addons/medical/functions/fnc_addLoadPatientActions.sqf b/addons/medical/functions/fnc_addLoadPatientActions.sqf new file mode 100644 index 0000000000..b00ff72472 --- /dev/null +++ b/addons/medical/functions/fnc_addLoadPatientActions.sqf @@ -0,0 +1,25 @@ +/* + * Author: 654wak654 + * Adds child actions to the "load patient" action for near vehicles. + * + * Arguments: + * 0: Patient + * + * Return Value: + * Child actions + * + * Example: + * [kevin] call ace_medical_fnc_addLoadPatientActions + * + * Public: No + */ +#include "script_component.hpp" + +params ["_target"]; + +private _statement = { + params ["_target", "_player", "_vehicle"]; + [_player, _target, _vehicle] call FUNC(actionLoadUnit); +}; + +[_target call EFUNC(common,nearestVehiclesFreeSeat), _statement, _target] call EFUNC(interact_menu,createVehiclesActions) diff --git a/addons/medical/stringtable.xml b/addons/medical/stringtable.xml index d268b8289d..6b4b121557 100644 --- a/addons/medical/stringtable.xml +++ b/addons/medical/stringtable.xml @@ -2411,7 +2411,7 @@ A páciens, %1,<br/>%2.<br/>%3.<br/>%4 Pacient %1<br/>je %2.<br/>%3.<br/>%4 Paciente %1<br/>é %2.<br/>%3.<br/>%4 - 痛み %1<br/>は %2.<br/>%3.<br/>%4 + 患者 %1<br/>は %2.<br/>%3.<br/>%4 환자 %1<br/>는 %2.<br/>%3.<br/>%4 伤者 %1<br/>is %2.<br/>%3.<br/>%4 傷者 %1<br/>is %2.<br/>%3.<br/>%4 diff --git a/addons/medical_menu/stringtable.xml b/addons/medical_menu/stringtable.xml index 5cf2bdca6b..a3e58a2ba5 100644 --- a/addons/medical_menu/stringtable.xml +++ b/addons/medical_menu/stringtable.xml @@ -341,7 +341,7 @@ Alternar (Si mesmo) Přepnout (na sebe) Attiva (Te Stesso) - トグル (自分) + 切り替え (自分) 토글 (자신) 切换 (自己) 切換 (自己) @@ -761,7 +761,7 @@ Sangrando Krvácí Sanguinamento - 出血 + 出血中 출혈 出血中 出血中 diff --git a/addons/medical_treatment/functions/fnc_actionLoadUnit.sqf b/addons/medical_treatment/functions/fnc_actionLoadUnit.sqf index f110fb6f65..ec9f6cfb85 100644 --- a/addons/medical_treatment/functions/fnc_actionLoadUnit.sqf +++ b/addons/medical_treatment/functions/fnc_actionLoadUnit.sqf @@ -1,10 +1,11 @@ /* * Author: Glowbal - * Action for loading an unconscious or dead unit in the nearest vechile + * Action for loading an unconscious or dead unit in the nearest vehicle, or _vehicle if given. * * Arguments: * 0: The medic * 1: The patient + * 2: The vehicle (default: objNull) * * Return Value: * Vehicle they are loaded into (objNull on failure) @@ -16,20 +17,20 @@ */ #include "script_component.hpp" -params ["_caller", "_target"]; +params ["_caller", "_target", ["_vehicle", objNull]]; -if (_target call EFUNC(common,isAwake)) exitWith { +if ([_target] call EFUNC(common,isAwake)) exitWith { [QEGVAR(common,displayTextStructured), [[ELSTRING(medical,CanNotLoaded), _target call EFUNC(common,getName)], 1.5, _caller], _caller] call CBA_fnc_targetEvent; }; -if (_target call FUNC(isBeingCarried)) then { +if ([_target] call FUNC(isBeingCarried)) then { [_caller, _target] call EFUNC(dragging,dropObject_carry); }; -if (_target call FUNC(isBeingDragged)) then { +if ([_target] call FUNC(isBeingDragged)) then { [_caller, _target] call EFUNC(dragging,dropObject); }; -private _vehicle = [_caller, _target] call EFUNC(common,loadPerson); +private _vehicle = [_caller, _target, _vehicle] call EFUNC(common,loadPerson); _vehicle diff --git a/addons/rearm/XEH_PREP.hpp b/addons/rearm/XEH_PREP.hpp index 59a43b4b29..05377af37a 100644 --- a/addons/rearm/XEH_PREP.hpp +++ b/addons/rearm/XEH_PREP.hpp @@ -9,12 +9,14 @@ PREP(canTakeAmmo); PREP(createDummy); PREP(disable); PREP(dropAmmo); +PREP(getAllRearmTurrets); PREP(getCaliber); PREP(getHardpointMagazines); PREP(getMaxMagazines); PREP(getNeedRearmMagazines); PREP(getSupplyCount); -PREP(getVehicleMagazines); +PREP(getTurretConfigMagazines); +PREP(getTurretMagazineAmmo); PREP(grabAmmo); PREP(handleKilled); PREP(handleUnconscious); @@ -32,6 +34,7 @@ PREP(rearmSuccess); PREP(rearmSuccessLocal); PREP(removeMagazineFromSupply); PREP(setSupplyCount); +PREP(setTurretMagazineAmmo); PREP(storeAmmo); PREP(takeAmmo); PREP(takeSuccess); diff --git a/addons/rearm/functions/fnc_addRearmActions.sqf b/addons/rearm/functions/fnc_addRearmActions.sqf index c017c93509..b164449575 100644 --- a/addons/rearm/functions/fnc_addRearmActions.sqf +++ b/addons/rearm/functions/fnc_addRearmActions.sqf @@ -3,7 +3,7 @@ * Show the resupplyable ammunition of all surrounding vehicles. * * Arguments: - * 0: Target + * 0: Ammo Truck * * Return Value: * ChildActions @@ -15,7 +15,7 @@ */ #include "script_component.hpp" -params [["_truck", objNull, [objNull]]]; +params ["_truck"]; private _vehicles = nearestObjects [_truck, ["AllVehicles"], 20]; _vehicles = _vehicles select {(_x != _truck) && {!(_x isKindOf "CAManBase")} && {!(_x getVariable [QGVAR(disabled), false])}}; @@ -23,49 +23,12 @@ _vehicles = _vehicles select {(_x != _truck) && {!(_x isKindOf "CAManBase")} && private _vehicleActions = []; { private _vehicle = _x; - private _magazineHelper = []; - { - private _turretPath = _x; - private _magazines = [_vehicle, _turretPath] call FUNC(getVehicleMagazines); - { - private _magazine = _x; - if (!(_magazine in _magazineHelper)) then { - private _currentMagazines = { _x == _magazine } count (_vehicle magazinesTurret _turretPath); - private _maxMagazines = [_vehicle, _turretPath, _magazine] call FUNC(getMaxMagazines); - - if ((_currentMagazines < _maxMagazines) || {(_vehicle magazineTurretAmmo [_magazine, _turretPath]) < getNumber (configFile >> "CfgMagazines" >> _magazine >> "count")}) then { - _magazineHelper pushBack _magazine; - }; - }; - false - } count _magazines; - false - } count REARM_TURRET_PATHS; - - // 1.70 pylons - private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; - { - private _pylonName = configName _x; - private _pylonAmmo = _vehicle ammoOnPylon _pylonName; - private _pylonMagazine = (getPylonMagazines _vehicle) select _forEachIndex; - TRACE_3("",_pylonName,_pylonAmmo,_pylonMagazine); - - if (_pylonAmmo > 0) then { - // Try to refill current pylon: - private _magAmmo = getNumber (configFile >> "CfgMagazines" >> _pylonMagazine >> "count"); - if ((!(_pylonMagazine in _magazineHelper)) && {_pylonAmmo < _magAmmo}) then { - _magazineHelper pushBack _pylonMagazine; - }; - } else { - // See what we magazines can add to the empty pylon: - private _hardpointMags = [_x] call FUNC(getHardpointMagazines); - { - if (!(_x in _magazineHelper)) then { - _magazineHelper pushBack _x; - }; - } forEach _hardpointMags; - }; - } forEach _pylonConfigs; + + // Array of magazines that can be rearmed in the vehicle + private _needRearmMags = ([_vehicle] call FUNC(getNeedRearmMagazines)) apply {_x select 0}; + + // _needRearmMags without duplicates + private _magazineHelper = _needRearmMags arrayIntersect _needRearmMags; _magazineHelper = _magazineHelper select {[_truck, _x] call FUNC(hasEnoughSupply)}; TRACE_2("can add",_x,_magazineHelper); @@ -77,40 +40,46 @@ private _vehicleActions = []; }; if (GVAR(level) == 0) then { // [Level 0] adds a single action to rearm the entire vic - private _action = [_vehicle, - getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName"), - _icon, - {_this call FUNC(rearmEntireVehicle)}, - {true}, - {}, - _vehicle] call EFUNC(interact_menu,createAction); + private _action = [ + _vehicle, + getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName"), + _icon, + {_this call FUNC(rearmEntireVehicle)}, + {true}, + {}, + _vehicle + ] call EFUNC(interact_menu,createAction); _vehicleActions pushBack [_action, [], _truck]; } else { // [Level 1,2] - Add actions for each magazine private _actions = []; { - private _action = [_x, - getText(configFile >> "CfgMagazines" >> _x >> "displayName"), - getText(configFile >> "CfgMagazines" >> _x >> "picture"), - {_this call FUNC(takeAmmo)}, - {true}, - {}, - [_x, _vehicle]] call EFUNC(interact_menu,createAction); + private _action = [ + _x, + getText(configFile >> "CfgMagazines" >> _x >> "displayName"), + getText(configFile >> "CfgMagazines" >> _x >> "picture"), + {_this call FUNC(takeAmmo)}, + {true}, + {}, + [_x, _vehicle] + ] call EFUNC(interact_menu,createAction); _actions pushBack [_action, [], _truck]; } forEach _magazineHelper; - private _action = [_vehicle, + private _action = [ + _vehicle, getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName"), _icon, {}, {true}, {}, - []] call EFUNC(interact_menu,createAction); + [] + ] call EFUNC(interact_menu,createAction); + _vehicleActions pushBack [_action, _actions, _truck]; }; }; - false -} count _vehicles; +} forEach _vehicles; _vehicleActions diff --git a/addons/rearm/functions/fnc_addVehicleMagazinesToSupply.sqf b/addons/rearm/functions/fnc_addVehicleMagazinesToSupply.sqf index 087ea7fddd..2a8f9fed14 100644 --- a/addons/rearm/functions/fnc_addVehicleMagazinesToSupply.sqf +++ b/addons/rearm/functions/fnc_addVehicleMagazinesToSupply.sqf @@ -29,16 +29,17 @@ if (_vehicle isEqualType objNull) then {_vehicle = typeOf _vehicle}; if (_vehicle == "") exitWith { ERROR_1("VehicleType [%1] is empty in ace_rearm_fnc_addVehicleMagazinesToSupply",_string); }; +private _turrets = [_vehicle] call FUNC(getAllRearmTurrets); { private _turretPath = _x; - private _magazines = [_vehicle, _turretPath] call FUNC(getVehicleMagazines); + private _magazines = [_vehicle, _turretPath] call FUNC(getTurretConfigMagazines); TRACE_2("",_turretPath,_magazines); { [_truck, _x] call FUNC(addMagazineToSupply); false } count _magazines; false -} count REARM_TURRET_PATHS; +} count _turrets; // 1.70 pylons private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> _vehicle >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; diff --git a/addons/rearm/functions/fnc_canReadSupplyCounter.sqf b/addons/rearm/functions/fnc_canReadSupplyCounter.sqf index 80b5d35cd7..60ca21b3f5 100644 --- a/addons/rearm/functions/fnc_canReadSupplyCounter.sqf +++ b/addons/rearm/functions/fnc_canReadSupplyCounter.sqf @@ -16,10 +16,7 @@ */ #include "script_component.hpp" -params [ - ["_truck", objNull, [objNull]], - ["_unit", objNull, [objNull]] -]; +params ["_truck", "_unit"]; (alive _unit) && {_unit isKindOf "CAManBase"} diff --git a/addons/rearm/functions/fnc_canRearm.sqf b/addons/rearm/functions/fnc_canRearm.sqf index ea41cae5a9..236f23e233 100644 --- a/addons/rearm/functions/fnc_canRearm.sqf +++ b/addons/rearm/functions/fnc_canRearm.sqf @@ -16,10 +16,7 @@ */ #include "script_component.hpp" -params [ - ["_vehicle", objNull, [objNull]], - ["_unit", objNull, [objNull]] -]; +params ["_vehicle", "_unit"]; if (!alive _vehicle) exitWith {false}; if (GVAR(level) == 0 || {isNull _unit} || {!(_unit isKindOf "CAManBase")} || {!local _unit} || {_vehicle distance _unit > REARM_ACTION_DISTANCE} || {_vehicle getVariable [QGVAR(disabled), false]}) exitWith {false}; @@ -29,4 +26,9 @@ if (isNull _dummy) exitwith {false}; private _magazineClass = _dummy getVariable QGVAR(magazineClass); if (isNil "_magazineClass") exitWith {false}; -([_vehicle, _magazineClass] call FUNC(getNeedRearmMagazines)) select 0 +private _needRearmMags = [_vehicle] call FUNC(getNeedRearmMagazines); + +// Testing if vehicle needs rearm on any magazines of class _magazineClass +private _needsRearm = ({(_x select 0) isEqualTo _magazineClass} count _needRearmMags) > 0; + +_needsRearm diff --git a/addons/rearm/functions/fnc_canStoreAmmo.sqf b/addons/rearm/functions/fnc_canStoreAmmo.sqf index b303af372c..4c4989b1d7 100644 --- a/addons/rearm/functions/fnc_canStoreAmmo.sqf +++ b/addons/rearm/functions/fnc_canStoreAmmo.sqf @@ -16,10 +16,7 @@ */ #include "script_component.hpp" -params [ - ["_truck", objNull, [objNull]], - ["_unit", objNull, [objNull]] -]; +params ["_truck", "_unit"]; (alive _unit) && {_unit isKindOf "CAManBase"} diff --git a/addons/rearm/functions/fnc_canTakeAmmo.sqf b/addons/rearm/functions/fnc_canTakeAmmo.sqf index 6f15f46eb0..c508df378d 100644 --- a/addons/rearm/functions/fnc_canTakeAmmo.sqf +++ b/addons/rearm/functions/fnc_canTakeAmmo.sqf @@ -16,10 +16,7 @@ */ #include "script_component.hpp" -params [ - ["_truck", objNull, [objNull]], - ["_unit", objNull, [objNull]] -]; +params ["_truck", "_unit"]; (alive _unit) && {_unit isKindOf "CAManBase"} diff --git a/addons/rearm/functions/fnc_createDummy.sqf b/addons/rearm/functions/fnc_createDummy.sqf index ecdaf9ff55..afca11935f 100644 --- a/addons/rearm/functions/fnc_createDummy.sqf +++ b/addons/rearm/functions/fnc_createDummy.sqf @@ -16,10 +16,7 @@ */ #include "script_component.hpp" -params [ - ["_unit", objNull, [objNull]], - ["_magazineClass", "", [""]] -]; +params ["_unit", "_magazineClass"]; private _ammo = getText (configFile >> "CfgMagazines" >> _magazineClass >> "ammo"); private _dummyName = getText (configFile >> "CfgAmmo" >> _ammo >> QGVAR(dummy)); diff --git a/addons/rearm/functions/fnc_dropAmmo.sqf b/addons/rearm/functions/fnc_dropAmmo.sqf index 8c1336476d..61e744fcf5 100644 --- a/addons/rearm/functions/fnc_dropAmmo.sqf +++ b/addons/rearm/functions/fnc_dropAmmo.sqf @@ -18,9 +18,9 @@ #include "script_component.hpp" params [ - ["_unit", objNull, [objNull]], - ["_delete", false, [false]], - ["_unholster", true, [true]] + "_unit", + ["_delete", false], + ["_unholster", true] ]; private _dummy = _unit getVariable [QGVAR(dummy), objNull]; diff --git a/addons/rearm/functions/fnc_getAllRearmTurrets.sqf b/addons/rearm/functions/fnc_getAllRearmTurrets.sqf new file mode 100644 index 0000000000..890fe5cc6f --- /dev/null +++ b/addons/rearm/functions/fnc_getAllRearmTurrets.sqf @@ -0,0 +1,28 @@ +/* + * Author: Tuupertunut + * Returns all turrets in a vehicle. + * + * BIS command "allTurrets" does not return the driver turret at the time of writing (2017-07-16). + * This function just adds driver turret to the array returned by "allTurrets". + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Turret paths + * + * Example: + * [vehicle] call ace_rearm_fnc_getAllRearmTurrets + * + * Public: No + */ +#include "script_component.hpp" + +params ["_vehicle"]; + +private _turrets = allTurrets _vehicle; + +// Adding the driver turret "[-1]". +_turrets pushBack [-1]; + +_turrets diff --git a/addons/rearm/functions/fnc_getCaliber.sqf b/addons/rearm/functions/fnc_getCaliber.sqf index 7a07b9a1db..87f7b6cd88 100644 --- a/addons/rearm/functions/fnc_getCaliber.sqf +++ b/addons/rearm/functions/fnc_getCaliber.sqf @@ -18,7 +18,7 @@ #include "script_component.hpp" params [ - ["_magazineClass", "", [""]] + ["_magazineClass", ""] ]; if (_magazineClass isEqualTo "") exitWith {[8, 2]}; diff --git a/addons/rearm/functions/fnc_getHardpointMagazines.sqf b/addons/rearm/functions/fnc_getHardpointMagazines.sqf index 2a00fa8eb6..61a9591cd7 100644 --- a/addons/rearm/functions/fnc_getHardpointMagazines.sqf +++ b/addons/rearm/functions/fnc_getHardpointMagazines.sqf @@ -15,6 +15,8 @@ */ #include "script_component.hpp" +ACE_DEPRECATED(QFUNC(getHardpointMagazines),"3.12.0","getCompatiblePylonMagazines"); + params ["_pylonConfig"]; private _return = GVAR(hardpointGroupsCache) getVariable (str _pylonConfig); diff --git a/addons/rearm/functions/fnc_getMaxMagazines.sqf b/addons/rearm/functions/fnc_getMaxMagazines.sqf index c747714d86..6eba4e0ecc 100644 --- a/addons/rearm/functions/fnc_getMaxMagazines.sqf +++ b/addons/rearm/functions/fnc_getMaxMagazines.sqf @@ -17,13 +17,7 @@ */ #include "script_component.hpp" -params [ - ["_vehicle", objNull, [objNull]], - ["_turretPath", [], [[]]], - ["_magazineClass", "", [""]] -]; +params ["_vehicle", "_turretPath", "_magazineClass"]; -if (isNull _vehicle) exitWith {0}; - -private _count = {_x == _magazineClass} count ([_vehicle, _turretPath] call FUNC(getVehicleMagazines)); +private _count = {_x == _magazineClass} count ([_vehicle, _turretPath] call FUNC(getTurretConfigMagazines)); _count diff --git a/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf b/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf index 6b2620a99a..b4195bb966 100644 --- a/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf +++ b/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf @@ -1,78 +1,87 @@ /* - * Author: GitHawk, Jonpas - * Get rearm return value. + * Author: Tuupertunut + * Returns information about every magazine that can be rearmed in the vehicle. Multiple mags of + * same class in the same turret are grouped together for practical reasons. * * Arguments: * 0: Vehicle - * 1: Magazine Classname * * Return Value: - * Return Value - * 0: Can Rearm - * 1: TurretPath - * 2: Number of current magazines in turret path - * 3: Pylon Index (-1 if not a pylon) + * Magazine info + * Child arrays: + * 0: Magazine class + * 1: Turret path + * 2: Is pylon magazine + * 3: Pylon index (-1 if not pylon) + * 4: Max magazines + * 5: Current magazines + * 6: Max rounds per magazine + * 7: Current rounds in magazines * * Example: - * [tank, "500Rnd_127x99_mag_Tracer_Red"] call ace_rearm_fnc_getNeedRearmMagazines + * [tank] call ace_rearm_fnc_getNeedRearmMagazines * * Public: No */ #include "script_component.hpp" -params [["_vehicle", objNull, [objNull]], ["_magazineClass", "", [""]]]; +params ["_vehicle"]; -private _return = [false, [], 0, -1]; +private _magazineInfo = []; + +// 1.70 pylons +private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; { - private _magazines = [_vehicle, _x] call FUNC(getVehicleMagazines); + private _pylonConfig = _x; + + // Strangely, a 1-based index. + private _pylonIndex = _forEachIndex + 1; + + // Retrieving pylon magazine by index. If the pylon is empty, it is marked with "". + private _pylonMagazine = (getPylonMagazines _vehicle) select (_pylonIndex - 1); + + // Only care about pylons that have a magazine. + if (!(_pylonMagazine isEqualTo "")) then { + + private _maxRounds = getNumber (configFile >> "CfgMagazines" >> _pylonMagazine >> "count"); + private _currentRounds = _vehicle ammoOnPylon _pylonIndex; + + if (_currentRounds < _maxRounds) then { + // getPylonTurret expects 0 based index, and returns driver turret as [-1] + private _pylonTurret = [_vehicle, (_pylonIndex - 1)] call EFUNC(common,getPylonTurret); - if (_magazineClass in _magazines) then { - private _currentMagazines = {_x == _magazineClass} count (_vehicle magazinesTurret _x); - - if ((_vehicle magazineTurretAmmo [_magazineClass, _x]) < getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count")) exitWith { - _return = [true, _x, _currentMagazines, -1]; - }; - - if (_currentMagazines < ([_vehicle, _x, _magazineClass] call FUNC(getMaxMagazines))) exitWith { - _return = [true, _x, _currentMagazines, -1]; + _magazineInfo pushBack [_pylonMagazine, _pylonTurret, true, _pylonIndex, 1, 1, _maxRounds, [_currentRounds]]; }; }; +} forEach _pylonConfigs; - if (_return select 0) exitWith {}; - false -} count REARM_TURRET_PATHS; +private _turrets = [_vehicle] call FUNC(getAllRearmTurrets); +{ + private _turretPath = _x; + private _magazines = [_vehicle, _turretPath] call FUNC(getTurretConfigMagazines); -if (!(_return select 0)) then { - // 1.70 pylons - private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; + // _magazines without duplicates + private _magazineClasses = _magazines arrayIntersect _magazines; + { - private _pylonName = configName _x; - private _pylonIndex = _forEachIndex + 1; // WTF BIS - private _pylonAmmo = _vehicle ammoOnPylon _pylonName; - private _pylonMagazine = (getPylonMagazines _vehicle) select _forEachIndex; - private _pylonTurret = getArray (_x >> "turret"); - if (_pylonTurret isEqualTo []) then {_pylonTurret = [-1];}; // convert to expected array for driver - TRACE_4("",_pylonName,_pylonAmmo,_pylonMagazine,_pylonTurret); + private _magazineClass = _x; + + private _maxMagazines = [_vehicle, _turretPath, _magazineClass] call FUNC(getMaxMagazines); + private _maxRoundsPerMag = getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count"); + + /* Array of ammo counts in every magazine. Example: [200, 200, 152] means 2 mags with 200 + * rounds and 1 mag with 152 rounds. */ + private _currentRounds = [_vehicle, _turretPath, _magazineClass] call FUNC(getTurretMagazineAmmo); + private _currentMagazines = count _currentRounds; - if (_pylonAmmo > 0) then { - if (_magazineClass == _pylonMagazine) then { // Try to refill current pylon: - private _magAmmo = getNumber (configFile >> "CfgMagazines" >> _pylonMagazine >> "count"); - if (_pylonAmmo < _magAmmo) then { - _return = [true, _pylonTurret, 0, _pylonIndex]; - }; - }; - } else { - // See what we magazines can add to the empty pylon: - private _hardpointMags = [_x] call FUNC(getHardpointMagazines); - { - if (_x == _magazineClass) then { - _return = [true, _pylonTurret, 0, _pylonIndex]; - }; - } forEach _hardpointMags; + /* If there is space for new magazines or if some magazines are not full, add the magazine + * type to _magazineInfo. */ + if ((_currentMagazines < _maxMagazines) || {({_x < _maxRoundsPerMag} count _currentRounds) > 0}) then { + _magazineInfo pushBack [_magazineClass, _turretPath, false, -1, _maxMagazines, _currentMagazines, _maxRoundsPerMag, _currentRounds]; }; - if (_return select 0) exitWith {}; - } forEach _pylonConfigs; -}; + + } forEach _magazineClasses; +} forEach _turrets; -TRACE_3("getNeedRearmMagazines",_vehicle,_magazineClass,_return); -_return +TRACE_2("getNeedRearmMagazines",_vehicle,_magazineInfo); +_magazineInfo diff --git a/addons/rearm/functions/fnc_getVehicleMagazines.sqf b/addons/rearm/functions/fnc_getTurretConfigMagazines.sqf similarity index 86% rename from addons/rearm/functions/fnc_getVehicleMagazines.sqf rename to addons/rearm/functions/fnc_getTurretConfigMagazines.sqf index 6a0932d908..0421e1ed1a 100644 --- a/addons/rearm/functions/fnc_getVehicleMagazines.sqf +++ b/addons/rearm/functions/fnc_getTurretConfigMagazines.sqf @@ -10,7 +10,7 @@ * Magazine classes in TurretPath * * Example: - * [vehicle, [0]] call ace_rearm_fnc_getVehicleMagazines + * [vehicle, [0]] call ace_rearm_fnc_getTurretConfigMagazines * * Public: No */ diff --git a/addons/rearm/functions/fnc_getTurretMagazineAmmo.sqf b/addons/rearm/functions/fnc_getTurretMagazineAmmo.sqf new file mode 100644 index 0000000000..53107dd7b0 --- /dev/null +++ b/addons/rearm/functions/fnc_getTurretMagazineAmmo.sqf @@ -0,0 +1,27 @@ +/* + * Author: Tuupertunut + * Returns the current ammo counts in all magazines of given class in turret. + * + * BIS command "magazineTurretAmmo" is broken at the time of writing (2017-06-24) + * (https://feedback.bistudio.com/T79689). This function is intended as a workaround for it, + * extracting the data from the array returned by "magazinesAllTurrets". + * + * Arguments: + * 0: Vehicle + * 1: Turret Path + * 2: Magazine Classname + * + * Return Value: + * Current ammo counts in magazines. + * + * Example: + * [vehicle, [0], "200Rnd_127x99_mag_Tracer_Red"] call ace_rearm_fnc_getTurretMagazineAmmo + * + * Public: No + */ +#include "script_component.hpp" + +params ["_vehicle", "_turretPath", "_magazineClass"]; + +private _ammo = magazinesAllTurrets _vehicle select {(_x select 0) isEqualTo _magazineClass && {(_x select 1) isEqualTo _turretPath}} apply {_x select 2}; +_ammo diff --git a/addons/rearm/functions/fnc_grabAmmo.sqf b/addons/rearm/functions/fnc_grabAmmo.sqf index a77a17284b..7dc22ebfdb 100644 --- a/addons/rearm/functions/fnc_grabAmmo.sqf +++ b/addons/rearm/functions/fnc_grabAmmo.sqf @@ -16,10 +16,7 @@ */ #include "script_component.hpp" -params [ - ["_dummy", objNull, [objNull]], - ["_unit", objNull, [objNull]] -]; +params ["_dummy", "_unit"]; REARM_HOLSTER_WEAPON; [_unit, "forceWalk", QGVAR(vehRearm), true] call EFUNC(common,statusEffect_set); diff --git a/addons/rearm/functions/fnc_handleKilled.sqf b/addons/rearm/functions/fnc_handleKilled.sqf index 3e39dc727e..b0cdabaed5 100644 --- a/addons/rearm/functions/fnc_handleKilled.sqf +++ b/addons/rearm/functions/fnc_handleKilled.sqf @@ -15,9 +15,7 @@ */ #include "script_component.hpp" -params [ - ["_unit", objNull, [objNull]] -]; +params ["_unit"]; if (!local _unit) exitWith {}; diff --git a/addons/rearm/functions/fnc_handleUnconscious.sqf b/addons/rearm/functions/fnc_handleUnconscious.sqf index 0fbf1b8f06..f9d703f4ec 100644 --- a/addons/rearm/functions/fnc_handleUnconscious.sqf +++ b/addons/rearm/functions/fnc_handleUnconscious.sqf @@ -16,10 +16,7 @@ */ #include "script_component.hpp" -params [ - ["_unit", objNull, [objNull]], - ["_isUnconscious", false, [false]] -]; +params ["_unit", "_isUnconscious"]; if (!local _unit || {!_isUnconscious}) exitWith {}; diff --git a/addons/rearm/functions/fnc_hasEnoughSupply.sqf b/addons/rearm/functions/fnc_hasEnoughSupply.sqf index a2944db014..93f1f9ea3a 100644 --- a/addons/rearm/functions/fnc_hasEnoughSupply.sqf +++ b/addons/rearm/functions/fnc_hasEnoughSupply.sqf @@ -16,9 +16,7 @@ */ #include "script_component.hpp" -params [["_truck", objNull, [objNull]], ["_magazineClass", "", [""]]]; - -if (isNull _truck || {_magazineClass isEqualTo ""}) exitWith {false}; +params ["_truck", "_magazineClass"]; // With infinite supply, there is always enough if (GVAR(supply) == 0) exitWith {true}; diff --git a/addons/rearm/functions/fnc_makeDummy.sqf b/addons/rearm/functions/fnc_makeDummy.sqf index fbdd336a0d..574944a974 100644 --- a/addons/rearm/functions/fnc_makeDummy.sqf +++ b/addons/rearm/functions/fnc_makeDummy.sqf @@ -16,10 +16,7 @@ */ #include "script_component.hpp" -params [ - ["_obj", objNull, [objNull]], - ["_dirAndUp", [[1,0,0],[0,0,1]], [[]]] -]; +params ["_obj", "_dirAndUp"]; _obj setVectorDirAndUp _dirAndUp; _obj allowDamage false; diff --git a/addons/rearm/functions/fnc_moduleRearmSettings.sqf b/addons/rearm/functions/fnc_moduleRearmSettings.sqf index 2d498c8b57..61b6016c9d 100644 --- a/addons/rearm/functions/fnc_moduleRearmSettings.sqf +++ b/addons/rearm/functions/fnc_moduleRearmSettings.sqf @@ -1,6 +1,6 @@ /* * Author: GitHawk - * Module for adjusting the refuel settings. + * Module for adjusting the rearm settings. * * Arguments: * 0: The module logic @@ -28,4 +28,4 @@ if (!_activated) exitWith {}; [_logic, QGVAR(level), "level"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(supply), "supply"] call EFUNC(common,readSettingFromModule); -INFO_2("Module Initialized [level: %1][supply: %2]", GVAR(level), GVAR(supply)); +INFO_2("Module Initialized [level: %1][supply: %2]",GVAR(level),GVAR(supply)); diff --git a/addons/rearm/functions/fnc_pickUpAmmo.sqf b/addons/rearm/functions/fnc_pickUpAmmo.sqf index ee2845336b..0f47325a13 100644 --- a/addons/rearm/functions/fnc_pickUpAmmo.sqf +++ b/addons/rearm/functions/fnc_pickUpAmmo.sqf @@ -16,10 +16,7 @@ */ #include "script_component.hpp" -params [ - ["_dummy", objNull, [objNull]], - ["_unit", objNull, [objNull]] -]; +params ["_dummy", "_unit"]; private _attachedDummy = _unit getVariable [QGVAR(dummy), objNull]; if !(isNull _attachedDummy) exitWith {}; diff --git a/addons/rearm/functions/fnc_readSupplyCounter.sqf b/addons/rearm/functions/fnc_readSupplyCounter.sqf index cfcdb1b865..a1b46862b9 100644 --- a/addons/rearm/functions/fnc_readSupplyCounter.sqf +++ b/addons/rearm/functions/fnc_readSupplyCounter.sqf @@ -16,7 +16,7 @@ */ #include "script_component.hpp" -params [["_truck", objNull, [objNull]],["_unit", objNull, [objNull]]]; +params ["_truck", "_unit"]; TRACE_2("readSupplyCounter",_truck,_unit); if (GVAR(supply) == 0) exitWith {WARNING("Supply is unlimited");}; @@ -31,7 +31,7 @@ if (GVAR(supply) == 1) then { if (_supplyCount > 0 ) then { [[LSTRING(Hint_RemainingSupplyPoints), _supplyCount], 2, _unit] call EFUNC(common,displayTextStructured); } else { - [LSTRING(Hint_EmptySupplyPoints), 2, _unit] call EFUNC(common,displayTextStructured); + [LSTRING(Hint_Empty), 2, _unit] call EFUNC(common,displayTextStructured); }; true }, diff --git a/addons/rearm/functions/fnc_rearm.sqf b/addons/rearm/functions/fnc_rearm.sqf index 363a4905c7..bca193f621 100644 --- a/addons/rearm/functions/fnc_rearm.sqf +++ b/addons/rearm/functions/fnc_rearm.sqf @@ -16,7 +16,7 @@ */ #include "script_component.hpp" -params [["_target", objNull, [objNull]],["_unit", objNull, [objNull]]]; +params ["_target", "_unit"]; TRACE_2("rearm",_target,_unit); private _attachedDummy = _unit getVariable [QGVAR(dummy), objNull]; @@ -27,21 +27,24 @@ if (isNil "_magazineClass") exitWith {ERROR_1("magazineClass nil",_attachedDummy ([_magazineClass] call FUNC(getCaliber)) params ["_cal", "_idx"]; // Get magazines that can be rearmed -private _needRearmMags = [_target, _magazineClass] call FUNC(getNeedRearmMagazines); -_needRearmMags params ["_needRearm", "_turretPath", "_cnt", "_pylon"]; +private _needRearmMags = [_target] call FUNC(getNeedRearmMagazines); +private _needRearmMagsOfClass = _needRearmMags select {(_x select 0) isEqualTo _magazineClass}; // Exit if no magazines need rearming -if (!_needRearm) exitWith {ERROR_2("Could not find turret for %1 in %2", _magazineClass, typeOf _target);}; +if ((count _needRearmMagsOfClass) == 0) exitWith {ERROR_2("Could not find turret for %1 in %2",_magazineClass,typeOf _target);}; + +private _currentRearmableMag = _needRearmMagsOfClass select 0; +_currentRearmableMag params ["", "_turretPath", "", "_pylon", "", "_magazineCount"]; private _magazineDisplayName = getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"); if (_magazineDisplayName == "") then { _magazineDisplayName = _magazineClass; - ERROR_1("Magazine is missing display name [%1]", _magazineClass); + ERROR_1("Magazine is missing display name [%1]",_magazineClass); }; [ TIME_PROGRESSBAR(REARM_DURATION_REARM select _idx), - [_target, _unit, _turretPath, _cnt, _magazineClass, (REARM_COUNT select _idx), _pylon], + [_target, _unit, _turretPath, _magazineCount, _magazineClass, (REARM_COUNT select _idx), _pylon], {(_this select 0) call FUNC(rearmSuccess)}, "", format [localize LSTRING(RearmAction), getText(configFile >> "CfgVehicles" >> (typeOf _target) >> "displayName"), _magazineDisplayName], diff --git a/addons/rearm/functions/fnc_rearmEntireVehicle.sqf b/addons/rearm/functions/fnc_rearmEntireVehicle.sqf index 8fddb4ab85..b0fe9f7ccf 100644 --- a/addons/rearm/functions/fnc_rearmEntireVehicle.sqf +++ b/addons/rearm/functions/fnc_rearmEntireVehicle.sqf @@ -17,11 +17,7 @@ */ #include "script_component.hpp" -params [ - ["_truck", objNull, [objNull]], - "", - ["_vehicle", objNull, [objNull]] -]; +params ["_truck", "", "_vehicle"]; [ TIME_PROGRESSBAR(10), diff --git a/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf b/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf index dda3ff9ca7..2ad70f9626 100644 --- a/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf +++ b/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf @@ -5,7 +5,7 @@ * Arguments: * 0: Rearm information * 0: Ammo Truck - * 1: Vehicle * * Return Value: * None @@ -18,10 +18,11 @@ #include "script_component.hpp" params ["_args"]; -_args params [["_truck", objNull, [objNull]], ["_vehicle", objNull, [objNull]]]; +_args params ["_truck", "_vehicle"]; TRACE_2("rearmEntireVehicleSuccess",_truck,_vehicle); if (isServer) then { + private _turrets = [_vehicle] call FUNC(getAllRearmTurrets); { private _turretOwnerID = _vehicle turretOwner _x; if (_turretOwnerID == 0) then { @@ -30,7 +31,7 @@ if (isServer) then { [QGVAR(rearmEntireVehicleSuccessLocalEH), [_truck, _vehicle, _x], _turretOwnerID] call CBA_fnc_ownerEvent; }; false - } count REARM_TURRET_PATHS; + } count _turrets; } else { [QGVAR(rearmEntireVehicleSuccessEH), _this] call CBA_fnc_serverEvent; }; diff --git a/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf b/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf index 01901fdf87..031c1d1f4d 100644 --- a/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf +++ b/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf @@ -1,5 +1,5 @@ /* - * Author: GitHawk + * Author: Tuupertunut * Rearm an entire turret locally. * * Arguments: @@ -17,60 +17,42 @@ */ #include "script_component.hpp" -params [["_truck", objNull, [objNull]], ["_vehicle", objNull, [objNull]], ["_turretPath", [], [[]]]]; +params ["_truck", "_vehicle", "_turretPath"]; TRACE_3("rearmEntireVehicleSuccessLocal",_truck,_vehicle,_turretPath); -// 1.70 pylons -private _pylonConfigs = configProperties [configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]; +// Fetching all rearmable magazines in this turret +private _magazines = ([_vehicle] call FUNC(getNeedRearmMagazines)) select {(_x select 1) isEqualTo _turretPath}; { - private _pylonTurret = getArray (_x >> "turret"); - if (_pylonTurret isEqualTo []) then {_pylonTurret = [-1];}; // convert to expected array for driver - if (_pylonTurret isEqualTo _turretPath) then { - private _pylonIndex = _forEachIndex + 1; // GJ BIS - private _pylonAmmo = _vehicle ammoOnPylon _pylonIndex; - private _pylonMagazine = (getPylonMagazines _vehicle) select _forEachIndex; - private _maxRounds = getNumber (configFile >> "CfgMagazines" >> _pylonMagazine >> "count"); - TRACE_4("",_pylonIndex,_pylonAmmo,_maxRounds,_pylonMagazine); - if (_pylonAmmo < _maxRounds) then { - if ((GVAR(supply) == 0) || {[_truck, _pylonMagazine, (_maxRounds - _pylonAmmo)] call FUNC(removeMagazineFromSupply)}) then { - TRACE_3("Adding Rounds",_vehicle,_pylonIndex,_maxRounds); - _vehicle setAmmoOnPylon [_pylonIndex, _maxRounds]; + _x params ["_magazineClass", "_magTurretPath", "_isPylonMag", "_pylonIndex", "_maxMagazines", "_currentMagazines", "_maxRoundsPerMag", "_currentRounds"]; + + // Array of planned ammo counts in every magazine after the rearm is complete + private _plannedRounds = +_currentRounds; + + // Trying to fill all existing magazines. + { + if (_x < _maxRoundsPerMag) then { + if ((GVAR(supply) == 0) || {[_truck, _magazineClass, (_maxRoundsPerMag - _x)] call FUNC(removeMagazineFromSupply)}) then { + _plannedRounds set [_forEachIndex, _maxRoundsPerMag]; }; }; - }; -} forEach _pylonConfigs; - -private _magazines = [_vehicle, _turretPath] call FUNC(getVehicleMagazines); -if (isNil "_magazines") exitWith {}; -{ - private _magazine = _x; - private _currentMagazines = { _x == _magazine } count (_vehicle magazinesTurret _turretPath); - private _maxMagazines = [_vehicle, _turretPath, _magazine] call FUNC(getMaxMagazines); - private _maxRounds = getNumber (configFile >> "CfgMagazines" >> _magazine >> "count"); - private _currentRounds = _vehicle magazineTurretAmmo [_magazine, _turretPath]; - - TRACE_7("Rearmed Turret",_vehicle,_turretPath,_currentMagazines,_maxMagazines,_currentRounds,_maxRounds,_magazine); - - if (_turretPath isEqualTo [-1] && _currentMagazines == 0) then { - // On driver, the empty magazine is still there, but is not returned by magazinesTurret - _currentMagazines = _currentMagazines + 1; - }; + } forEach _currentRounds; + + // Trying to add new full magazines, if there is space left. if (_currentMagazines < _maxMagazines) then { - private _success = true; - if ((GVAR(supply) == 0) || {[_truck, _magazine, (_maxRounds - _currentRounds)] call FUNC(removeMagazineFromSupply)}) then { - _vehicle setMagazineTurretAmmo [_magazine, _maxRounds, _turretPath]; - }; - for "_idx" from 1 to (_maxMagazines - _currentMagazines) do { - if ((GVAR(supply) == 0) || {[_truck, _magazine, _maxRounds] call FUNC(removeMagazineFromSupply)}) then { - _vehicle addMagazineTurret [_magazine, _turretPath]; + if ((GVAR(supply) == 0) || {[_truck, _magazineClass, _maxRoundsPerMag] call FUNC(removeMagazineFromSupply)}) then { + _plannedRounds pushBack _maxRoundsPerMag; }; }; - } else { - if ((GVAR(supply) == 0) || {[_truck, _magazine, (_maxRounds - _currentRounds)] call FUNC(removeMagazineFromSupply)}) then { - _vehicle setMagazineTurretAmmo [_magazine, _maxRounds, _turretPath]; - }; }; - false -} count _magazines; + + TRACE_2("rearming",_x,_plannedRounds); + + // Updating new ammo counts to vehicle. + if (_isPylonMag) then { + _vehicle setAmmoOnPylon [_pylonIndex, (_plannedRounds select 0)]; + } else { + [_vehicle, _magTurretPath, _magazineClass, _plannedRounds] call FUNC(setTurretMagazineAmmo); + }; +} forEach _magazines; diff --git a/addons/rearm/functions/fnc_rearmSuccess.sqf b/addons/rearm/functions/fnc_rearmSuccess.sqf index c609117002..0fc8219180 100644 --- a/addons/rearm/functions/fnc_rearmSuccess.sqf +++ b/addons/rearm/functions/fnc_rearmSuccess.sqf @@ -21,7 +21,7 @@ */ #include "script_component.hpp" -params [["_vehicle", objNull, [objNull]], ["_unit", objNull, [objNull]], "_turretPath", "_numMagazines", "_magazineClass", "_numRounds", "_pylon"]; +params ["_vehicle", "_unit", "_turretPath", "_numMagazines", "_magazineClass", "_numRounds", "_pylon"]; TRACE_7("rearmSuccess",_vehicle,_unit,_turretPath,_numMagazines,_magazineClass,_numRounds,_pylon); if (local _unit) then { diff --git a/addons/rearm/functions/fnc_setSupplyCount.sqf b/addons/rearm/functions/fnc_setSupplyCount.sqf index d9d5194550..ef99a78416 100644 --- a/addons/rearm/functions/fnc_setSupplyCount.sqf +++ b/addons/rearm/functions/fnc_setSupplyCount.sqf @@ -23,6 +23,6 @@ if !(EGVAR(common,settingsInitFinished)) exitWith { // only run this after the s params [["_truck", objNull, [objNull]], ["_supply", 0, [0]]]; if (GVAR(supply) != 1) exitWith {WARNING("supply setting is not set to limited");}; -if (isNull _truck) exitWith {WARNING_1("Truck is null [%1]", _truck);}; +if (isNull _truck) exitWith {WARNING_1("Truck is null [%1]",_truck);}; _truck setVariable [QGVAR(currentSupply), (_supply max 0), true]; diff --git a/addons/rearm/functions/fnc_setTurretMagazineAmmo.sqf b/addons/rearm/functions/fnc_setTurretMagazineAmmo.sqf new file mode 100644 index 0000000000..2cc5e156d5 --- /dev/null +++ b/addons/rearm/functions/fnc_setTurretMagazineAmmo.sqf @@ -0,0 +1,89 @@ +/* + * Author: Tuupertunut + * Sets the ammo counts of all magazines of given class in turret. + * + * BIS command "setMagazineTurretAmmo" is broken at the time of writing (2017-06-24) + * (https://feedback.bistudio.com/T79689). This function is intended as a workaround for it. All + * magazines are removed and then added again with updated ammo counts. + * Note: As an unintended side effect, the turret reloads after running this function. + * + * Arguments: + * 0: Vehicle + * 1: Turret Path + * 2: Magazine Classname + * 3: Ammo Counts in Magazines + * + * Return Value: + * None + * + * Example: + * [vehicle, [0], "200Rnd_127x99_mag_Tracer_Red", [200, 152]] call ace_rearm_fnc_setTurretMagazineAmmo + * + * Public: No + */ +#include "script_component.hpp" + +params ["_vehicle", "_turretPath", "_magazineClass", "_ammoCounts"]; + +// Checking if a magazine of given class is currently loaded in any weapon. +private _magLoadedInWeapon = false; +private _loadedWeapon = ""; +{ + private _currentlyLoadedMag = (weaponState [_vehicle, _turretPath, _x]) select 3; + + if (_currentlyLoadedMag isEqualTo _magazineClass) exitWith { + _magLoadedInWeapon = true; + _loadedWeapon = _x; + }; +} forEach (_vehicle weaponsTurret _turretPath); + + +if (!_magLoadedInWeapon) then { + /* The easy case: + * The magazine class was not loaded, so we can just remove those magazines and + * add them back with updated ammo counts. */ + + _vehicle removeMagazinesTurret [_magazineClass, _turretPath]; + { + _vehicle addMagazineTurret [_magazineClass, _turretPath, _x]; + } forEach _ammoCounts; + +} else { + /* Special hack case: + * The magazine class was loaded into a weapon. If the weapon has more than one type of + * magazine (e.g. AP and HEAT in a cannon), then removing all magazines would trigger the + * weapon to load a different magazine type. For example, removing the HEAT shells while HEAT + * is loaded makes the cannon switch to AP. + * + * To prevent that, we must remove all magazines that would fit into the weapon and then add + * them back with the magazine-to-be-loaded being the first. */ + + private _allowedMagClassesInWeapon = getArray (configFile >> "CfgWeapons" >> _loadedWeapon >> "magazines"); + + /* Current ammo counts of all allowed magazine classes in weapon. + * Example: [["8Rnd_82mm_Mo_shells", [8, 8, 2]], ["8Rnd_82mm_Mo_Flare_white", [7]]] */ + private _ammoCountsByMagClass = _allowedMagClassesInWeapon apply {[_x, ([_vehicle, _turretPath, _x] call FUNC(getTurretMagazineAmmo))]}; + + // Removing all magazines that fit into the weapon. + { + _vehicle removeMagazinesTurret [_x, _turretPath]; + } forEach _allowedMagClassesInWeapon; + + // Adding the mags of the given class first with updated ammo counts. + { + _vehicle addMagazineTurret [_magazineClass, _turretPath, _x]; + } forEach _ammoCounts; + + // Adding back all other magazines with their original ammo counts. + { + _x params ["_loopMagClass", "_loopAmmoCounts"]; + + if (!(_loopMagClass isEqualTo _magazineClass)) then { + { + _vehicle addMagazineTurret [_loopMagClass, _turretPath, _x]; + } forEach _loopAmmoCounts; + }; + } forEach _ammoCountsByMagClass; +}; + +TRACE_5("setTurretMagazineAmmo",_vehicle,_turretPath,_magazineClass,_ammoCounts,_loadedWeapon); diff --git a/addons/rearm/functions/fnc_storeAmmo.sqf b/addons/rearm/functions/fnc_storeAmmo.sqf index c056421bba..0da99c081a 100644 --- a/addons/rearm/functions/fnc_storeAmmo.sqf +++ b/addons/rearm/functions/fnc_storeAmmo.sqf @@ -16,10 +16,7 @@ */ #include "script_component.hpp" -params [ - ["_truck", objNull, [objNull]], - ["_unit", objNull, [objNull]] -]; +params ["_truck", "_unit"]; private _attachedDummy = _unit getVariable [QGVAR(dummy), objNull]; if (isNull _attachedDummy) exitwith {}; diff --git a/addons/rearm/functions/fnc_takeAmmo.sqf b/addons/rearm/functions/fnc_takeAmmo.sqf index 23f19fedf4..69db94729d 100644 --- a/addons/rearm/functions/fnc_takeAmmo.sqf +++ b/addons/rearm/functions/fnc_takeAmmo.sqf @@ -19,11 +19,7 @@ */ #include "script_component.hpp" -params [ - ["_truck", objNull, [objNull]], - ["_unit", objNull, [objNull]], - ["_args", ["", objNull], [[]]] -]; +params ["_truck", "_unit", "_args"]; _args params ["_magazineClass", "_vehicle"]; TRACE_5("takeAmmo",_truck,_unit,_args,_magazineClass,_vehicle); diff --git a/addons/rearm/functions/fnc_takeSuccess.sqf b/addons/rearm/functions/fnc_takeSuccess.sqf index e458036176..e9d8b1daaa 100644 --- a/addons/rearm/functions/fnc_takeSuccess.sqf +++ b/addons/rearm/functions/fnc_takeSuccess.sqf @@ -18,7 +18,7 @@ */ #include "script_component.hpp" -params [["_args", [objNull, "", objNull], [[]], 3]]; +params ["_args"]; _args params ["_unit", "_magazineClass", "_truck"]; TRACE_3("takeSuccess",_unit,_magazineClass,_truck); diff --git a/addons/rearm/script_component.hpp b/addons/rearm/script_component.hpp index 3edfeda3f1..92e279950c 100644 --- a/addons/rearm/script_component.hpp +++ b/addons/rearm/script_component.hpp @@ -19,7 +19,6 @@ #define REARM_ACTION_DISTANCE 7 -#define REARM_TURRET_PATHS [[-1], [0], [0,0], [0,1], [1], [2], [0,2]] #define REARM_CALIBERS [ 6, 7, 8, 13, 19, 20, 25, 30, 35, 39, 40, 60, 70, 80, 82, 100, 105, 120, 122, 125, 155, 230, 250] #define REARM_DURATION_TAKE [ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 13, 10] diff --git a/addons/refuel/CfgVehicles.hpp b/addons/refuel/CfgVehicles.hpp index 4ca811bbbb..e7d77e4510 100644 --- a/addons/refuel/CfgVehicles.hpp +++ b/addons/refuel/CfgVehicles.hpp @@ -14,7 +14,7 @@ displayName = CSTRING(TakeNozzle); \ condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTakeNozzle)); \ statement = QUOTE([ARR_2(_player,_target)] call FUNC(takeNozzle)); \ - exceptions[] = {"isNotInside", "isNotOnLadder"}; \ + exceptions[] = {INTERACT_EXCEPTIONS_REFUELING}; \ icon = QPATHTOF(ui\icon_refuel_interact.paa); \ }; \ class GVAR(TurnOn) { \ @@ -35,7 +35,7 @@ displayName = CSTRING(Disconnect); \ condition = QUOTE([ARR_2(_player,_target)] call FUNC(canDisconnect)); \ statement = QUOTE([ARR_2(_player,_target)] call DFUNC(disconnect)); \ - exceptions[] = {"isNotInside", "isNotOnLadder"}; \ + exceptions[] = {INTERACT_EXCEPTIONS_REFUELING}; \ icon = QPATHTOF(ui\icon_refuel_interact.paa); \ }; \ }; \ diff --git a/addons/refuel/functions/fnc_makeJerryCan.sqf b/addons/refuel/functions/fnc_makeJerryCan.sqf index 782a63eb6d..96fc30adce 100644 --- a/addons/refuel/functions/fnc_makeJerryCan.sqf +++ b/addons/refuel/functions/fnc_makeJerryCan.sqf @@ -44,7 +44,7 @@ private _action = [QGVAR(Refuel), _action = [QGVAR(PickUpNozzle), localize LSTRING(TakeNozzle), QPATHTOF(ui\icon_refuel_interact.paa), - {[_player, _target] call FUNC(TakeNozzle)}, + {[_player, _target] call FUNC(takeNozzle)}, {[_player, _target] call FUNC(canTakeNozzle)}, {}, [], diff --git a/addons/refuel/functions/fnc_startNozzleInHandsPFH.sqf b/addons/refuel/functions/fnc_startNozzleInHandsPFH.sqf index 1360a8df86..fca638fc25 100644 --- a/addons/refuel/functions/fnc_startNozzleInHandsPFH.sqf +++ b/addons/refuel/functions/fnc_startNozzleInHandsPFH.sqf @@ -35,7 +35,7 @@ TRACE_2("start",_unit,_nozzle); if !( alive _unit - && {"" isEqualTo currentWeapon _unit} + && {"" isEqualTo currentWeapon _unit || {_unit call EFUNC(common,isSwimming)}} && {[_unit, objNull, [INTERACT_EXCEPTIONS, "notOnMap"]] call EFUNC(common,canInteractWith)} && {!("unconscious" isEqualTo toLower animationState _unit)} && {!(_unit getVariable ["ACE_isUnconscious", false])} diff --git a/addons/refuel/functions/fnc_takeNozzle.sqf b/addons/refuel/functions/fnc_takeNozzle.sqf index 570a16b1ba..1c2382c21c 100644 --- a/addons/refuel/functions/fnc_takeNozzle.sqf +++ b/addons/refuel/functions/fnc_takeNozzle.sqf @@ -94,5 +94,5 @@ params [ {}, localize LSTRING(TakeNozzleAction), {true}, - ["isNotInside", "isNotOnLadder"] + [INTERACT_EXCEPTIONS_REFUELING] ] call EFUNC(common,progressBar); diff --git a/addons/refuel/script_component.hpp b/addons/refuel/script_component.hpp index e46be9b72b..be346e0cca 100644 --- a/addons/refuel/script_component.hpp +++ b/addons/refuel/script_component.hpp @@ -30,4 +30,5 @@ #define TIME_PROGRESSBAR(X) (X) #endif -#define INTERACT_EXCEPTIONS "isNotInside", "isNotOnLadder", "isNotRefueling" +#define INTERACT_EXCEPTIONS_REFUELING "isNotInside", "isNotOnLadder", "isNotSwimming" +#define INTERACT_EXCEPTIONS INTERACT_EXCEPTIONS_REFUELING, "isNotRefueling" diff --git a/addons/refuel/stringtable.xml b/addons/refuel/stringtable.xml index 0284a23882..ef53dd91dc 100644 --- a/addons/refuel/stringtable.xml +++ b/addons/refuel/stringtable.xml @@ -274,6 +274,7 @@ Couldn't turn on fuel nozzle Impossibile iniziare il rifornimento + 給油を始められなかった %1 Liters fueled diff --git a/addons/reload/stringtable.xml b/addons/reload/stringtable.xml index 5cdbe3e9ba..d1f7e0318c 100644 --- a/addons/reload/stringtable.xml +++ b/addons/reload/stringtable.xml @@ -76,7 +76,7 @@ Töltényheveder összekötése Attacca la tracolla Ligar cintos de munição - ベルト リンク + ベルトをつなげる 벨트 연결 连接弹链 連接彈鏈 diff --git a/addons/repair/functions/fnc_repair.sqf b/addons/repair/functions/fnc_repair.sqf index 45d5b0a171..7d69f740a9 100644 --- a/addons/repair/functions/fnc_repair.sqf +++ b/addons/repair/functions/fnc_repair.sqf @@ -169,7 +169,7 @@ if (vehicle _caller == _caller && {_callerAnim != ""}) then { _caller selectWeapon (primaryWeapon _caller); // unit always has a primary weapon here }; - if (!underwater _caller) then { + if !(_caller call EFUNC(common,isSwimming)) then { if (stance _caller == "STAND") then { _caller setVariable [QGVAR(repairPrevAnimCaller), "amovpknlmstpsraswrfldnon"]; } else { diff --git a/addons/repair/functions/fnc_repair_failure.sqf b/addons/repair/functions/fnc_repair_failure.sqf index e0aab18d73..7a38282499 100644 --- a/addons/repair/functions/fnc_repair_failure.sqf +++ b/addons/repair/functions/fnc_repair_failure.sqf @@ -31,7 +31,7 @@ private ["_config","_callback", "_usersOfItems", "_weaponSelect"]; if (primaryWeapon _caller == "ACE_FakePrimaryWeapon") then { _caller removeWeapon "ACE_FakePrimaryWeapon"; }; -if (vehicle _caller == _caller && {!underwater _caller}) then { +if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) then { [_caller, _caller getVariable [QGVAR(repairPrevAnimCaller), ""], 2] call EFUNC(common,doAnimation); }; _caller setVariable [QGVAR(repairPrevAnimCaller), nil]; diff --git a/addons/repair/functions/fnc_repair_success.sqf b/addons/repair/functions/fnc_repair_success.sqf index e0be8f34cf..1cbe439d3e 100644 --- a/addons/repair/functions/fnc_repair_success.sqf +++ b/addons/repair/functions/fnc_repair_success.sqf @@ -31,7 +31,7 @@ private ["_config","_callback", "_weaponSelect"]; if (primaryWeapon _caller == "ACE_FakePrimaryWeapon") then { _caller removeWeapon "ACE_FakePrimaryWeapon"; }; -if (vehicle _caller == _caller && {!underwater _caller}) then { +if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) then { [_caller, _caller getVariable [QGVAR(repairPrevAnimCaller), ""], 2] call EFUNC(common,doAnimation); }; _caller setVariable [QGVAR(repairPrevAnimCaller), nil]; diff --git a/addons/repair/stringtable.xml b/addons/repair/stringtable.xml index 693e6be47a..9c2c39d9c5 100644 --- a/addons/repair/stringtable.xml +++ b/addons/repair/stringtable.xml @@ -439,7 +439,7 @@ Parte totalmente reparado Parte riparata completamente Pièce entièrement réparée - 部分的な完全な修理 + 完全に修理された部品 부분 완벽히 수리됨 完整维修部分 完整維修部分 @@ -577,7 +577,7 @@ Stabilizzatore Verticale Stabilisateur vertical Seitenleitwerk - 車両安定器 + 車両スタビライザ 수직 안정판 垂直稳定 垂直穩定 @@ -905,7 +905,7 @@ Ruota posteriore destra Jobb hátsó kerék Правое заднее колесо - 右の後 + 右の後輪 오른쪽 뒤쪽 바퀴 右后轮 右後輪 @@ -1031,7 +1031,7 @@ ERA ERA ДЗ - 爆発反応装甲 + ERA 폭발반응장갑 爆炸式反应装甲 爆炸式反應裝甲 @@ -1399,7 +1399,7 @@ Ningún Nessuna Aucun - 工兵 + なし 없음 @@ -1414,7 +1414,7 @@ Ingeniero Geniere Ingénieur - 専門兵 + 工兵 정비공 工兵 工兵 diff --git a/addons/respawn/stringtable.xml b/addons/respawn/stringtable.xml index e7af38bd8c..a8b93cba41 100644 --- a/addons/respawn/stringtable.xml +++ b/addons/respawn/stringtable.xml @@ -108,7 +108,7 @@ Gyülekezőpont, Nyugat (Bázis) Rallypoint Západ (Základna) Ponto de encontro Oeste (Base) - ラリーポイント ウエスト (ベース) + ラリーポイント 同盟軍 (ベース) 蓝方集合点 (基地) 藍方集合點 (基地) 청군 집결지 (기지) @@ -124,7 +124,7 @@ Gyülekezőpont, Kelet (Bázis) Ralllypoint Východ (Základna) Ponto de encontro Lest (Base) - ラリーポイント イースト (ベース) + ラリーポイント OPFOR軍 (ベース) 红方集合点 (基地) 紅方集合點 (基地) 대항군 집결지 (기지) @@ -140,7 +140,7 @@ Gyülekezőpont, Független (Bázis) Rallypoint Nezávislý (Základna) Ponto de encontro Independente (Base) - ラリーポイント インデペンデント (ベース) + ラリーポイント 独立軍 (ベース) 独立方集合点 (基地) 獨立方集合點 (基地) 독립군 집결지 (기지) @@ -156,7 +156,7 @@ Gyülekezőpont, Nyugat Rallypoint Západ Ponto de encontro Oeste - ラリーポイント ウエスト + ラリーポイント 同盟軍 蓝方集合点 藍方集合點 청군 집결지 @@ -172,7 +172,7 @@ Gyülekezőpont, Kelet Rallypoint Východ Ponto de encontro Leste - ラリーポイント イースト + ラリーポイント OPFOR軍 红方集合点 紅方集合點 대항군 집결지 @@ -188,7 +188,7 @@ Gyülekezőpont, Független Rallypoint Nezávislý Ponto de encontro Independente - ラリーポイント インデペンデント + ラリーポイント 独立軍 独立方集合点 獨立方集合點 독립군 집결지 diff --git a/addons/switchunits/stringtable.xml b/addons/switchunits/stringtable.xml index 02a1746474..ba8ca782d7 100644 --- a/addons/switchunits/stringtable.xml +++ b/addons/switchunits/stringtable.xml @@ -75,7 +75,7 @@ Átváltás BLUFOR-ra? На синих? Cambia per BLUFOR? - ウエストへ切り替えますか? + 同盟軍へ切り替えますか? 切换至蓝方? 切換至藍方? 청군으로 전환합니까? @@ -91,7 +91,7 @@ Nyugat-fakciós egységekre való váltás engedélyezése? Разрешить переключаться на синих юнитов? Consenti passaggio ad unità BLUFOR? - ウエスト側ユニットへ切り替えられるようにしますか? + 同盟軍側ユニットへ切り替えられるようにしますか? 允许切换至蓝方? 允許切換至藍方? 청군 인원으로 전환합니까? @@ -107,7 +107,7 @@ Átváltás OPFOR-ra? На красных? Cambia per OPFOR? - イースト側へ切り替えますか? + OPFOR軍側へ切り替えますか? 切换至红方? 切換至紅方? 대항군으로 전환합니까? @@ -123,7 +123,7 @@ Kelet-fakciós egységekre való váltás engedélyezése? Разрешить переключаться на красных юнитов? Consenti passaggio ad unità OPFOR? - イースト側ユニットへ切り替えられるようにしますか? + OPFOR軍側ユニットへ切り替えられるようにしますか? 允许切换至红方? 允許切換至紅方? 대항군 인원으로 전환합니까? @@ -139,7 +139,7 @@ Átváltás INDFOR-ra? На независимых? Cambia per INDFOR? - インデペンデントへ切り替えますか? + 独立軍へ切り替えますか? 切换至独立方? 切換至獨立方? 독립군 으로 전환합니까? @@ -155,7 +155,7 @@ Független egységekre való váltás engedélyezése? Разрешить переключаться на независимых юнитов? Consenti passaggio ad unità INDFOR? - インデペンデント側ユニットへ切り替えられるようにしますか? + 独立軍側ユニットへ切り替えられるようにしますか? 允许切换至独立方? 允許切換至獨立方? 독립군 인원으로 전환합니까? @@ -171,7 +171,7 @@ Átváltás civilre? На гражданских? Cambia per Civili? - シビリアンへ切り替えますか? + 市民へ切り替えますか? 민간인으로 전환합니까? 切换至平民方? 切換至平民方? @@ -187,7 +187,7 @@ Civil egységekre való váltás engedélyezése? Разрешить переключаться на гражданских юнитов? Consenti passaggio ad unità civili? - シビリアン側ユニットへ切り替えられるようにしますか? + 市民側ユニットへ切り替えられるようにしますか? 민간인으로 전환하는걸 허가합니까? 允许切换至平民方? 允許切換至平民方? @@ -251,7 +251,7 @@ A biztonságos zóna más csapatból lévő játékosok körül. Alapértelmezett: 200 Радиус безопасной зоны вокруг ироков из противоположной команды. По-умолчанию: 200 La zona sicura attorno ai giocatori di un team diverso. Default: 200 - 別のチームへのプレイヤーの周囲にある安全地帯の範囲。標準:200 + 別のチームへのプレイヤーの周囲にある安全地帯の範囲。標準: 200 다른 진영으로 부터의 플레이어 안전 지대. 기본설정: 200 安全区的范围. 预设值:200 安全區的範圍. 預設值:200 diff --git a/addons/zeus/stringtable.xml b/addons/zeus/stringtable.xml index 5dad48b793..5fa556c5d2 100644 --- a/addons/zeus/stringtable.xml +++ b/addons/zeus/stringtable.xml @@ -28,7 +28,7 @@ Különböző beállítási lehetőségeket biztosít a Zeus részeihez. Позволяет контролировать различные аспекты Зевса. Fornisce controllo su vari aspetti di Zeus. - Zeus のさまざまな側面を強化します。 + Zeus の操作性をさまざまな側面から強化します。 Zeus에게 다양한 방면의 조작을 제공해줍니다 提供宙斯各个方面的控制权 提供宙斯各個方面的控制權 @@ -236,7 +236,7 @@ Elfogott állapot váltása Пленный (вкл./выкл.) Attivatore Prigioniero - 捕虜としてトグル + 捕虜として切り替え 포로 토글 切换俘虏 切換俘虜 @@ -335,7 +335,7 @@ Change: general, commanding, courage Изменяет: general, commanding, courage Upravuje: general, commanding, courage - 変更:general, commanding, courage + 変更: general, commanding, courage Zmienia: ogólne, dowodzenie, odwaga Ändert: general, commanding, courage 변화: 전반적, 지휘, 사기 @@ -361,7 +361,7 @@ Change : aimingAccuracy Изменяет: aimingAccuracy Upravuje: aimingAccuracy - 変更:aimingAccuracy + 変更: aimingAccuracy Zmienia: precyzję celowania Ändert: aimingAccuracy 변화: 조준 명중률 @@ -387,7 +387,7 @@ Change : aimingShake, aimingSpeed, reloadSpeed Изменяет: aimingShake, aimingSpeed, reloadSpeed Upravuje: aimingShake, aimingSpeed, reloadSpeed - 変更:aimingShake, aimingSpeed, reloadSpeed + 変更: aimingShake, aimingSpeed, reloadSpeed Zmienia: drżenie broni, szybkość celowania, szybkość przeładowania Ändert: aimingShake, aimingSpeed, reloadSpeed 변화: 조준시 흔들림, 조준 속도, 재장전 속도 @@ -413,7 +413,7 @@ Change : spotDistance, spotTime Изменяет: spotDistance, spotTime Upravuje: spotDistance, spotTime - 変更:spotDistance, spotTime + 変更: spotDistance, spotTime Zmienia: zasięg rozpoznawania, czas rozpoznawania Ändert: spotDistance, spotTime 변화: 탐지 거리, 탐지까지의 시간 @@ -510,14 +510,14 @@ Kapituláló állapot váltása Сдавшийся (вкл./выкл.) Attivatore Resa - 捕虜としてトグル + 投降として切り替え 항복 토글 切换投降 切換投降 Add/Remove FRIES - FRUES の追加と削除 + FRIES の追加と削除 패스트로프 추가/제거 Dodaj/usuń FRIES Aj./Enlève FRIES @@ -576,7 +576,7 @@ Téléporter le joueur sélectionné à la position du module Телепортирует выбранного игрока к местоположению модуля Teleportuje vybraného hráče na pozici modulu - 選択したプレイヤーをプレイヤーをモジュール位置へ移動します + 選択したプレイヤーをモジュール位置へ移動します Teleportuje wybranego gracza na pozycję modułu Teleportiert ausgewählten Spieler zur Position des Moduls 모듈의 위치로 플레이어 순간이동 @@ -621,7 +621,7 @@ Eszméletlen állapot váltása Без сознания (вкл./выкл.) Attivatore Incoscienza - 気絶をトグル + 気絶を切り替え 기절 토글 切换昏迷 切換昏迷 @@ -644,7 +644,7 @@ Chercher le bâtiment proche Обыскать ближайшие здания Prohledat nejbližší budovu - 近くの建物を創作します + 近くの建物を捜索します Przeszukaj najbliższy budynek Durchsuche nahegelegenes Gebäude 근처 건물 수색 @@ -700,7 +700,7 @@ Toggle Simulation Przełącz symulację - シミュレーションをトグル + シミュレーションを切り替え 재현 토글 Bascule Simulation Attivatore Simulazione @@ -938,7 +938,7 @@ Cargo : Груз: Náklad: - カーゴ: + カーゴ: Ładunek: Ladung: 화물: @@ -951,7 +951,7 @@ Position de la tâche Местоположение задания Pozice úkolu - タスクの位置 + タスク位置 Pozycja zadania Position der Aufgabe 작업 위치 @@ -1038,51 +1038,61 @@ Load into Cargo Carica nel Cargo + カーゴに積み込み Toggle NVGs Basculer JVN Attiva NVGs + 暗視装置の切り替え NVG equipment Equipment de vision nocturne Attrezzatura NVG + 暗視装置 Add or remove NVGs from units Ajouter ou retirer JVN des unités Aggiunge o rimuove NVGs alle unità + ユニットから暗視装置の追加と削除 Toggle NVG target Cible du basculement Attiva obiettivo NVG + 選択先の暗視装置の切り替え Selected group Groupe sélectionné Gruppo selezionato + 選択されたグループ Toggle flashlights Basculer lampes torches Attiva torce + フラッシュライトの切り替え Toggle flashlight target Cible du basculement Attiva obiettivo torcia + 選択先のフラッシュライトの切り替え Flashlight Lampe torche Torcia + フラッシュライト Add gear Ajouter équipement Aggiungi equipaggiamento + 装備を追加 diff --git a/optionals/compat_rhs_usf3/CfgAmmo.hpp b/optionals/compat_rhs_usf3/CfgAmmo.hpp index 5125e268fa..a021fee820 100644 --- a/optionals/compat_rhs_usf3/CfgAmmo.hpp +++ b/optionals/compat_rhs_usf3/CfgAmmo.hpp @@ -192,8 +192,8 @@ class CfgAmmo { ACE_barrelLengths[] = {101.6, 127.0, 228.6}; }; - class M_Titan_AT; - class rhs_ammo_M_fgm148_AT: M_Titan_AT { + class MissileBase; + class rhs_ammo_M_fgm148_AT: MissileBase { irLock = 1; laserLock = 0; airLock = 0; diff --git a/optionals/compat_rhs_usf3/CfgWeapons.hpp b/optionals/compat_rhs_usf3/CfgWeapons.hpp index d67879916b..0ee56a8b35 100644 --- a/optionals/compat_rhs_usf3/CfgWeapons.hpp +++ b/optionals/compat_rhs_usf3/CfgWeapons.hpp @@ -371,12 +371,7 @@ class CfgWeapons { }; - class H_PilotHelmetHeli_B; - class H_CrewHelmetHeli_B; - class rhsusf_hgu56p: H_PilotHelmetHeli_B { - HEARING_PROTECTION_VICCREW - }; - class rhsusf_hgu56p_mask: H_CrewHelmetHeli_B { + class rhsusf_hgu56p: rhsusf_opscore_01 { HEARING_PROTECTION_VICCREW }; diff --git a/tools/generate_airfriction_config.py b/tools/generate_airfriction_config.py new file mode 100644 index 0000000000..2b6eb6de9d --- /dev/null +++ b/tools/generate_airfriction_config.py @@ -0,0 +1,554 @@ +import math + +def retard(dm, bc, v): + mach = v / 340.276 + CDs = [] + Ms = [] + if (dm) == 1: + CDs = [0.2629, 0.2558, 0.2487, 0.2413, 0.2344, 0.2278, 0.2214, 0.2155, 0.2104, 0.2061, 0.2032, 0.2020, 0.2034, 0.2165, 0.2230, 0.2313, 0.2417, 0.2546, 0.2706, 0.2901, 0.3136, 0.3415, 0.3734, 0.4084, 0.4448, 0.4805, 0.5136, 0.5427, 0.5677, 0.5883, 0.6053, 0.6191, 0.6393, 0.6518, 0.6589, 0.6621, 0.6625, 0.6607, 0.6573, 0.6528, 0.6474, 0.6413, 0.6347, 0.6280, 0.6210, 0.6141, 0.6072, 0.6003, 0.5934, 0.5867, 0.5804, 0.5743, 0.5685, 0.5630, 0.5577, 0.5527, 0.5481, 0.5438, 0.5397, 0.5325, 0.5264, 0.5211, 0.5168, 0.5133, 0.5105, 0.5084, 0.5067, 0.5054, 0.5040, 0.5030, 0.5022, 0.5016, 0.5010, 0.5006, 0.4998, 0.4995, 0.4992, 0.4990, 0.4988] + Ms = [0.00, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50, 0.55, 0.60, 0.70, 0.725, 0.75, 0.775, 0.80, 0.825, 0.85, 0.875, 0.90, 0.925, 0.95, 0.975, 1.0, 1.025, 1.05, 1.075, 1.10, 1.125, 1.15, 1.20, 1.25, 1.30, 1.35, 1.40, 1.45, 1.50, 1.55, 1.60, 1.65, 1.70, 1.75, 1.80, 1.85, 1.90, 1.95, 2.00, 2.05, 2.10, 2.15, 2.20, 2.25, 2.30, 2.35, 2.40, 2.45, 2.50, 2.60, 2.70, 2.80, 2.90, 3.00, 3.10, 3.20, 3.30, 3.40, 3.50, 3.60, 3.70, 3.80, 3.90, 4.00, 4.20, 4.40, 4.60, 4.80, 5.00] + elif (dm) == 2: + CDs = [0.2303, 0.2298, 0.2287, 0.2271, 0.2251, 0.2227, 0.2196, 0.2156, 0.2107, 0.2048, 0.1980, 0.1905, 0.1828, 0.1758, 0.1702, 0.1669, 0.1664, 0.1667, 0.1682, 0.1711, 0.1761, 0.1831, 0.2004, 0.2589, 0.3492, 0.3983, 0.4075, 0.4103, 0.4114, 0.4106, 0.4089, 0.4068, 0.4046, 0.4021, 0.3966, 0.3904, 0.3835, 0.3759, 0.3678, 0.3594, 0.3512, 0.3432, 0.3356, 0.3282, 0.3213, 0.3149, 0.3089, 0.3033, 0.2982, 0.2933, 0.2889, 0.2846, 0.2806, 0.2768, 0.2731, 0.2696, 0.2663, 0.2632, 0.2602, 0.2572, 0.2543, 0.2515, 0.2487, 0.2460, 0.2433, 0.2408, 0.2382, 0.2357, 0.2333, 0.2309, 0.2262, 0.2217, 0.2173, 0.2132, 0.2091, 0.2052, 0.2014, 0.1978, 0.1944, 0.1912, 0.1851, 0.1794, 0.1741, 0.1693, 0.1648] + Ms = [0.00, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50, 0.55, 0.60, 0.65, 0.70, 0.75, 0.775, 0.80, 0.825, 0.85, 0.875, 0.90, 0.925, 0.95, 0.975, 1.0, 1.025, 1.05, 1.075, 1.10, 1.125, 1.15, 1.175, 1.20, 1.25, 1.30, 1.35, 1.40, 1.45, 1.50, 1.55, 1.60, 1.65, 1.70, 1.75, 1.80, 1.85, 1.90, 1.95, 2.00, 2.05, 2.10, 2.15, 2.20, 2.25, 2.30, 2.35, 2.40, 2.45, 2.50, 2.55, 2.60, 2.65, 2.70, 2.75, 2.80, 2.85, 2.90, 2.95, 3.00, 3.10, 3.20, 3.30, 3.40, 3.50, 3.60, 3.70, 3.80, 3.90, 4.00, 4.20, 4.40, 4.60, 4.80, 5.00] + elif (dm) == 5: + CDs = [0.1710, 0.1719, 0.1727, 0.1732, 0.1734, 0.1730, 0.1718, 0.1696, 0.1668, 0.1637, 0.1603, 0.1566, 0.1529, 0.1497, 0.1473, 0.1463, 0.1489, 0.1583, 0.1672, 0.1815, 0.2051, 0.2413, 0.2884, 0.3379, 0.3785, 0.4032, 0.4147, 0.4201, 0.4278, 0.4338, 0.4373, 0.4392, 0.4403, 0.4406, 0.4401, 0.4386, 0.4362, 0.4328, 0.4286, 0.4237, 0.4182, 0.4121, 0.4057, 0.3991, 0.3926, 0.3861, 0.3800, 0.3741, 0.3684, 0.3630, 0.3578, 0.3529, 0.3481, 0.3435, 0.3391, 0.3349, 0.3269, 0.3194, 0.3125, 0.3060, 0.2999, 0.2942, 0.2889, 0.2838, 0.2790, 0.2745, 0.2703, 0.2662, 0.2624, 0.2588, 0.2553, 0.2488, 0.2429, 0.2376, 0.2326, 0.2280] + Ms = [0.00, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50, 0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.875, 0.90, 0.925, 0.95, 0.975, 1.0, 1.025, 1.05, 1.075, 1.10, 1.15, 1.20, 1.25, 1.30, 1.35, 1.40, 1.45, 1.50, 1.55, 1.60, 1.65, 1.70, 1.75, 1.80, 1.85, 1.90, 1.95, 2.00, 2.05, 2.10, 2.15, 2.20, 2.25, 2.30, 2.35, 2.40, 2.45, 2.50, 2.60, 2.70, 2.80, 2.90, 3.00, 3.10, 3.20, 3.30, 3.40, 3.50, 3.60, 3.70, 3.80, 3.90, 4.00, 4.20, 4.40, 4.60, 4.80, 5.00] + elif (dm) == 6: + CDs = [0.2617, 0.2553, 0.2491, 0.2432, 0.2376, 0.2324, 0.2278, 0.2238, 0.2205, 0.2177, 0.2155, 0.2138, 0.2126, 0.2121, 0.2122, 0.2132, 0.2154, 0.2194, 0.2229, 0.2297, 0.2449, 0.2732, 0.3141, 0.3597, 0.3994, 0.4261, 0.4402, 0.4465, 0.4490, 0.4497, 0.4494, 0.4482, 0.4464, 0.4441, 0.4390, 0.4336, 0.4279, 0.4221, 0.4162, 0.4102, 0.4042, 0.3981, 0.3919, 0.3855, 0.3788, 0.3721, 0.3652, 0.3583, 0.3515, 0.3447, 0.3381, 0.3314, 0.3249, 0.3185, 0.3122, 0.3060, 0.3000, 0.2941, 0.2883, 0.2772, 0.2668, 0.2574, 0.2487, 0.2407, 0.2333, 0.2265, 0.2202, 0.2144, 0.2089, 0.2039, 0.1991, 0.1947, 0.1905, 0.1866, 0.1794, 0.1730, 0.1673, 0.1621, 0.1574] + Ms = [0.00, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50, 0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.875, 0.90, 0.925, 0.95, 0.975, 1.0, 1.025, 1.05, 1.075, 1.10, 1.125, 1.15, 1.175, 1.20, 1.225, 1.25, 1.30, 1.35, 1.40, 1.45, 1.50, 1.55, 1.60, 1.65, 1.70, 1.75, 1.80, 1.85, 1.90, 1.95, 2.00, 2.05, 2.10, 2.15, 2.20, 2.25, 2.30, 2.35, 2.40, 2.45, 2.50, 2.60, 2.70, 2.80, 2.90, 3.00, 3.10, 3.20, 3.30, 3.40, 3.50, 3.60, 3.70, 3.80, 3.90, 4.00, 4.20, 4.40, 4.60, 4.80, 5.00] + elif (dm) == 7: + CDs = [0.1198, 0.1197, 0.1196, 0.1194, 0.1193, 0.1194, 0.1194, 0.1194, 0.1193, 0.1193, 0.1194, 0.1193, 0.1194, 0.1197, 0.1202, 0.1207, 0.1215, 0.1226, 0.1242, 0.1266, 0.1306, 0.1368, 0.1464, 0.1660, 0.2054, 0.2993, 0.3803, 0.4015, 0.4043, 0.4034, 0.4014, 0.3987, 0.3955, 0.3884, 0.3810, 0.3732, 0.3657, 0.3580, 0.3440, 0.3376, 0.3315, 0.3260, 0.3209, 0.3160, 0.3117, 0.3078, 0.3042, 0.3010, 0.2980, 0.2951, 0.2922, 0.2892, 0.2864, 0.2835, 0.2807, 0.2779, 0.2752, 0.2725, 0.2697, 0.2670, 0.2643, 0.2615, 0.2588, 0.2561, 0.2533, 0.2506, 0.2479, 0.2451, 0.2424, 0.2368, 0.2313, 0.2258, 0.2205, 0.2154, 0.2106, 0.2060, 0.2017, 0.1975, 0.1935, 0.1861, 0.1793, 0.1730, 0.1672, 0.1618] + Ms = [0.0, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50, 0.55, 0.60, 0.65, 0.70, 0.725, 0.75, 0.775, 0.80, 0.825, 0.85, 0.875, 0.90, 0.925, 0.95, 0.975, 1.0, 1.025, 1.05, 1.075, 1.10, 1.125, 1.15, 1.20, 1.25, 1.30, 1.35, 1.40, 1.50, 1.55, 1.60, 1.65, 1.70, 1.75, 1.80, 1.85, 1.90, 1.95, 2.00, 2.05, 2.10, 2.15, 2.20, 2.25, 2.30, 2.35, 2.40, 2.45, 2.50, 2.55, 2.60, 2.65, 2.70, 2.75, 2.80, 2.85, 2.90, 2.95, 3.00, 3.10, 3.20, 3.30, 3.40, 3.50, 3.60, 3.70, 3.80, 3.90, 4.00, 4.20, 4.40, 4.60, 4.80, 5.00] + elif (dm) == 8: + CDs = [0.2105, 0.2105, 0.2104, 0.2104, 0.2103, 0.2103, 0.2103, 0.2103, 0.2103, 0.2102, 0.2102, 0.2102, 0.2102, 0.2102, 0.2103, 0.2103, 0.2104, 0.2104, 0.2105, 0.2106, 0.2109, 0.2183, 0.2571, 0.3358, 0.4068, 0.4378, 0.4476, 0.4493, 0.4477, 0.4450, 0.4419, 0.4353, 0.4283, 0.4208, 0.4133, 0.4059, 0.3986, 0.3915, 0.3845, 0.3777, 0.3710, 0.3645, 0.3581, 0.3519, 0.3458, 0.3400, 0.3343, 0.3288, 0.3234, 0.3182, 0.3131, 0.3081, 0.3032, 0.2983, 0.2937, 0.2891, 0.2845, 0.2802, 0.2720, 0.2642, 0.2569, 0.2499, 0.2432, 0.2368, 0.2308, 0.2251, 0.2197, 0.2147, 0.2101, 0.2058, 0.2019, 0.1983, 0.1950, 0.1890, 0.1837, 0.1791, 0.1750, 0.1713] + Ms = [0.00, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50, 0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.825, 0.85, 0.875, 0.90, 0.925, 0.95, 0.975, 1.0, 1.025, 1.05, 1.075, 1.10, 1.125, 1.15, 1.20, 1.25, 1.30, 1.35, 1.40, 1.45, 1.50, 1.55, 1.60, 1.65, 1.70, 1.75, 1.80, 1.85, 1.90, 1.95, 2.00, 2.05, 2.10, 2.15, 2.20, 2.25, 2.30, 2.35, 2.40, 2.45, 2.50, 2.60, 2.70, 2.80, 2.90, 3.00, 3.10, 3.20, 3.30, 3.40, 3.50, 3.60, 3.70, 3.80, 3.90, 4.00, 4.20, 4.40, 4.60, 4.80, 5.00] + for i in range(len(Ms)): + if Ms[i] >= mach: + previousIdx = max(0, i - 1); + lc = CDs[previousIdx]; + lm = Ms[previousIdx]; + tc = lc + (CDs[i] - lc) * (mach - lm) / (Ms[i] - lm) + return 0.00068418 * (tc / bc) * pow(v, 2) + return 0 + +def distanceAtTOF2(tof, v, dM, bc): + lx = 0 + lt = 0 + dx = 0 + dy = 0 + vx = v + vy = 0 + drag = 0 + t = 0 + while t <= tof: + lx = dx + lt = t + drag = retard(dM, bc, v) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + vx = vx - (1/2000) * (vx/v) * drag + vy = vy - (1/2000) * (vy/v) * drag + vy = vy + (1/2000) * 9.8066 + v = math.sqrt(vx*vx+vy*vy) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + t = t+1/2 + return lx + (tof - lt) * (dx - lx) / (t - lt) + +def velocityAtM(m, v, a): + lx = 0 + lv = 0 + dx = 0 + dy = 0 + vx = v + vy = 0 + drag = 0 + while dx <= m: + lx = dx + lv = v + drag = a*pow(v,2) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + vx = vx - (1/2000) * (vx/v) * drag + vy = vy - (1/2000) * (vy/v) * drag + vy = vy + (1/2000) * 9.8066 + v = math.sqrt(vx*vx+vy*vy) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + return lv + (m - lx) * (v - lv) / (dx - lx) + +def velocityAtM2(m, v, dM, bc): + lx = 0 + lv = 0 + dx = 0 + dy = 0 + vx = v + vy = 0 + drag = 0 + while dx <= m: + lx = dx + lv = v + drag = retard(dM, bc, v) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + vx = vx - (1/2000) * (vx/v) * drag + vy = vy - (1/2000) * (vy/v) * drag + vy = vy + (1/2000) * 9.8066 + v = math.sqrt(vx*vx+vy*vy) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + return lv + (m - lx) * (v - lv) / (dx - lx) + +def velocityTillM(m, v, a, g): + velocities = [0] * round(m + 1) + dx = 0 + dy = 0 + vx = v + vy = 0 + drag = 0 + while dx <= m: + velocities[round(dx)] = v + drag = a*pow(v,2) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + vx = vx - (1/2000) * (vx/v) * drag + vy = vy - (1/2000) * (vy/v) * drag + vy = vy + (1/2000) * g + v = math.sqrt(vx*vx+vy*vy) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + + return velocities + +def velocityTillM2(m, v, dM, bc): + velocities = [0] * round(m + 1) + dx = 0 + dy = 0 + vx = v + vy = 0 + drag = 0 + while dx <= m: + velocities[round(dx)] = v + drag = retard(dM, bc, v) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + vx = vx - (1/2000) * (vx/v) * drag + vy = vy - (1/2000) * (vy/v) * drag + vy = vy + (1/2000) * 9.8066 + v = math.sqrt(vx*vx+vy*vy) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + + return velocities + +def tofAtM(m, v, a): + lx = 0 + lt = 0 + dx = 0 + dy = 0 + vx = v + vy = 0 + drag = 0 + t = 0 + while dx <= m: + lx = dx + lt = t + drag = a*pow(v,2) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + vx = vx - (1/2000) * (vx/v) * drag + vy = vy - (1/2000) * (vy/v) * drag + vy = vy + (1/2000) * 9.8066 + v = math.sqrt(vx*vx+vy*vy) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + t = t+1/2 + return lt + (m - lx) * (t - lt) / (dx - lx) + +def tofAtM2(m, v, dM, bc): + lx = 0 + lt = 0 + dx = 0 + dy = 0 + vx = v + vy = 0 + drag = 0 + t = 0 + while dx <= m: + lx = dx + lt = t + drag = retard(dM, bc, v) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + vx = vx - (1/2000) * (vx/v) * drag + vy = vy - (1/2000) * (vy/v) * drag + vy = vy + (1/2000) * 9.8066 + v = math.sqrt(vx*vx+vy*vy) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + t = t+1/2 + return lt + (m - lx) * (t - lt) / (dx - lx) + +def tofTillM(m, v, a, g): + times = [0] * round(m + 1) + dx = 0 + dy = 0 + vx = v + vy = 0 + drag = 0 + t = 0 + while dx <= m: + times[round(dx)] = t + drag = a*pow(v,2) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + vx = vx - (1/2000) * (vx/v) * drag + vy = vy - (1/2000) * (vy/v) * drag + vy = vy + (1/2000) * g + v = math.sqrt(vx*vx+vy*vy) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + t = t+1/2 + return times + +def tofTillM2(m, v, dM, bc): + times = [0] * round(m + 1) + dx = 0 + dy = 0 + vx = v + vy = 0 + drag = 0 + t = 0 + while dx <= m: + times[round(dx)] = t + drag = retard(dM, bc, v) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + vx = vx - (1/2000) * (vx/v) * drag + vy = vy - (1/2000) * (vy/v) * drag + vy = vy + (1/2000) * 9.8066 + v = math.sqrt(vx*vx+vy*vy) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + t = t+1/2 + return times + +def dropAtM(m, v, a): + lx = 0 + cly = 0 + dx = 0 + dy = 0 + vx = v + vy = 0 + drag = 0 + while dx <= m: + lx = dx + ly = dy + drag = a*pow(v,2) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + vx = vx - (1/2000) * (vx/v) * drag + vy = vy - (1/2000) * (vy/v) * drag + vy = vy + (1/2000) * 9.8066 + v = math.sqrt(vx*vx+vy*vy) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + return ly + (m - lx) * (dy - ly) / (dx - lx) + +def dropAtM2(m, v, dM, bc): + lx = 0 + cly = 0 + dx = 0 + dy = 0 + vx = v + vy = 0 + drag = 0 + while dx <= m: + lx = dx + ly = dy + drag = retard(dM, bc, v) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + vx = vx - (1/2000) * (vx/v) * drag + vy = vy - (1/2000) * (vy/v) * drag + vy = vy + (1/2000) * 9.8066 + v = math.sqrt(vx*vx+vy*vy) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + return ly + (m - lx) * (dy - ly) / (dx - lx) + +def dropTillM(m, v, a, g): + drops = [0] * round(m + 1) + dx = 0 + dy = 0 + vx = v + vy = 0 + drag = 0 + while dx < m: + drops[round(dx)] = dy + drag = a*v*v + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + vx = vx - (1/2000) * (vx/v) * drag + vy = vy - (1/2000) * (vy/v) * drag + vy = vy + (1/2000) * g + v = math.sqrt(vx*vx+vy*vy) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + + return drops + +def dropTillM2(m, v, dM, bc): + drops = [0] * round(m + 1) + dx = 0 + dy = 0 + vx = v + vy = 0 + drag = 0 + while dx < m: + drops[round(dx)] = dy + drag = retard(dM, bc, v) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + vx = vx - (1/2000) * (vx/v) * drag + vy = vy - (1/2000) * (vy/v) * drag + vy = vy + (1/2000) * 9.8066 + v = math.sqrt(vx*vx+vy*vy) + dx = dx+(1/2000)*vx*0.5 + dy = dy+(1/2000)*vy*0.5 + + return drops + +def tofAtMDiff(m, v, a, d, bc): + return tofAtM2(m, v, d, bc)-tofAtM(m, v, a) + +def tofAtMDiffBC(m, v, dM1, bc1, dM2, bc2): + return tofAtM2(m, v, dM1, bc1)-tofAtM2(m, v, dM2, bc2) + +def velocityAtMDiff(m, v, a, d, bc): + return velocityAtM2(m, v, d, bc)-velocityAtM(m, v, a) + +def velocityAtMDiffBC(m, v, dM1, bc1, dM2, bc2): + return velocityAtM2(m, v, dM1, bc1)-velocityAtM2(m, v, dM2, bc2) + +def dragAtV(v, a): + return a*v^2 + +def dragAtV2(v, d, bc): + return retard(d, bc, v) + +def dragAtVDiff(v, a, d, bc): + return retard(d, bc, v)-a*pow(v,2) + +def dropAtMDiff(m, v, a, d, bc): + return dropAtM2(m, v, d, bc)-dropAtM(m, v, a) + +def dropAtMDiffBC(m, v, dM1, bc1, dM2, bc2): + return dropAtM2(m, v, dM1, bc1)-dropAtM2(m, v, dM2, bc2) + +def airFrictionAtV(v, d, bc): + return retard(d, bc, v)/pow(v,2) + +def maxDropDiff(m, v, a, dM, bc): + maxDiff = 0 + drops1 = dropTillM(m, v, a, 9.8066) + drops2 = dropTillM2(m, v, dM, bc) + for d in range(0, m): + maxDiff = max(maxDiff, abs(drops2[d] - drops1[d])) + return maxDiff + +def maxDropDiffG(m, v, a, dM, bc, g): + maxDiff = 0 + drops1 = dropTillM(m, v, a, g) + drops2 = dropTillM2(m, v, dM, bc) + for d in range(0, m): + maxDiff = max(maxDiff, abs(drops2[d] - drops1[d])) + return maxDiff + +def maxDropDiffV(distances, velocities, a, dM, bc): + maxDiff = 0 + for m, v in zip(distances, velocities): + drops1 = dropTillM(m, v, a, 9.8066) + drops2 = dropTillM2(m, v, dM, bc) + for d in range(0, m): + maxDiff = max(maxDiff, abs(drops2[d] - drops1[d])) + return maxDiff + +def maxDropDiffBC(m, v, dM1, bc1, dM2, bc2): + maxDiff = 0 + drops1 = dropTillM2(m, v, dM1, bc1) + drops2 = dropTillM2(m, v, dM2, bc2) + for d in range(0, m): + maxDiff = max(maxDiff, abs(drops2[d] - drops1[d])) + return maxDiff + +def maxVelocityDiff(m, v, a, dM, bc): + maxDiff = 0 + velocities1 = velocityTillM(m, v, a, 9.8066) + velocities2 = velocityTillM2(m, v, dM, bc) + for d in range(0, m): + maxDiff = max(maxDiff, abs(velocities2[d] - velocities1[d])) + return maxDiff + +def maxVelocityDiffG(m, v, a, dM, bc, g): + maxDiff = 0 + velocities1 = velocityTillM(m, v, a, g) + velocities2 = velocityTillM2(m, v, dM, bc) + for d in range(0, m): + maxDiff = max(maxDiff, abs(velocities2[d] - velocities1[d])) + return maxDiff + +def maxVelocityDiffV(distances, velocities, a, dM, bc): + maxDiff = 0 + for m, v in zip(distances, velocities): + velocities1 = velocityTillM(m, v, a, 9.8066) + velocities2 = velocityTillM2(m, v, dM, bc) + for d in range(0, m): + maxDiff = max(maxDiff, abs(velocities2[d] - velocities1[d])) + return maxDiff + +def maxVelocityDiffBC(m, v, dM1, bc1, dM2, bc2): + maxDiff = 0 + velocities1 = velocityTillM2(m, v, dM1, bc1) + velocities2 = velocityTillM2(m, v, dM2, bc2) + for d in range(0, m): + maxDiff = max(maxDiff, abs(velocities2[d] - velocities1[d])) + return maxDiff + +def maxTOFDiff(m, v, a, dM, bc): + maxDiff = 0 + times1 = tofTillM(m, v, a, 9.8066) + times2 = tofTillM2(m, v, dM, bc) + for d in range(0, m): + maxDiff = max(maxDiff, abs(times2[d] - times1[d])) + return maxDiff + +def maxTOFDiffG(m, v, a, dM, bc, g): + maxDiff = 0 + times1 = tofTillM(m, v, a, g) + times2 = tofTillM2(m, v, dM, bc) + for d in range(0, m): + maxDiff = max(maxDiff, abs(times2[d] - times1[d])) + return maxDiff + +def maxTOFDiffV(distances, velocities, a, dM, bc): + maxDiff = 0 + for m, v in zip(distances, velocities): + times1 = tofTillM(m, v, a, 9.8066) + times2 = tofTillM2(m, v, dM, bc) + for d in range(0, m): + maxDiff = max(maxDiff, abs(times2[d] - times1[d])) + return maxDiff + +def maxTOFDiffBC(m, v, dM1, bc1, dM2, bc2): + maxDiff = 0 + times1 = tofTillM2(m, v, dM1, bc1) + times2 = tofTillM2(m, v, dM2, bc2) + for d in range(0, m): + maxDiff = max(maxDiff, abs(times2[d] - times1[d])) + return maxDiff + +def predictAirFriction(mv, thresholdVelocity, dragModel, bc): + airFrictions = [] + for v in range(1,1000): + airFrictions.append(retard(dragModel, bc, v) / pow(v, 2)) + + arr = airFrictions[thresholdVelocity:mv] + return sum(arr)/len(arr) + +def calculateAirFriction(v, dragModel, bc): + return retard(dragModel, bc, v) / pow(v, 2) + +# Each list entry needs to be in the following form: +# [ammo name, list of engagement ranges, list of muzzle velocities, drag model, ballistic coefficient] +ammoList = [["B_556x45_Ball", [300, 500, 500], [750, 870, 910], 7, 0.151], + ["ACE_556x45_Ball_Mk262", [600, 600], [810, 840], 1, 0.361], + ["ACE_556x45_Ball_Mk318", [300, 500, 500], [780, 880, 950], 1, 0.307], + ["ACE_556x45_Ball_M995_AP", [400, 500], [820, 880], 1, 0.310], + ["B_545x39_Ball_F", [400, 500], [735, 892], 7, 0.168], + ["B_580x42_Ball_F", [500, 500], [930, 970], 7, 0.156], + ["B_65x39_Caseless", [400, 800, 800], [730, 800, 830], 7, 0.263], + ["ACE_65x47_Ball_Scenar", [500, 800], [730, 830], 7, 0.290], + ["ACE_65_Creedmor_Ball", [600, 1000], [750, 860], 7, 0.317], + ["B_762x51_Ball", [500, 800], [700, 833], 7, 0.2], + ["ACE_762x51_Ball_M118LR", [600, 800], [750, 795], 7, 0.243], + ["ACE_762x51_Ball_Mk316_Mod_0", [600, 800], [780, 810], 7, 0.243], + ["ACE_762x51_Ball_Mk319_Mod_0", [600, 800], [840, 910], 1, 0.377], + ["ACE_762x51_Ball_M993_AP", [600, 800], [875, 930], 1, 0.359], + ["ACE_30_06_M1_Ball", [600, 800, 900], [700, 800, 840], 1, 0.494], + ["ACE_7_Remington_Magnum_Ball", [600, 800, 1000], [720, 812, 830], 7, 0.345], + ["ACE_243_Winchester_Ball", [700, 900, 900], [830, 900, 920], 7, 0.278], + ["ACE_762x67_Ball_Mk248_Mod_0", [800, 900, 900], [865, 900, 924], 7, 0.268], + ["ACE_762x67_Ball_Mk248_Mod_1", [800, 900, 900], [847, 867, 877], 7, 0.310], + ["ACE_762x67_Ball_Berger_Hybrid_OTM", [900, 1000, 1000], [800, 853, 884], 7, 0.358], + ["B_762x54_Ball", [500, 800, 800], [700, 820, 833], 1, 0.4], + ["ACE_762x35_Ball", [400, 500], [620, 675], 1, 0.330], + ["ACE_762x39_Ball", [400, 600], [650, 750], 1, 0.275], + ["ACE_762x54_Ball_7T2", [500, 800, 800], [680, 750, 800], 1, 0.395], + ["ACE_303_Ball", [900, 1000], [748, 765], 1, 0.493], + ["B_93x64_Ball", [900, 1000], [850, 880], 1, 0.368], + ["B_408_Ball", [1600,1600], [862, 872], 7, 0.434], + ["ACE_408_Ball", [1200,1200], [1057, 1067], 7, 0.279], + ["ACE_106x83mm_Ball", [1500, 1500], [955, 965], 1, 0.72], + ["B_338_Ball", [1100, 1300], [880, 925], 7, 0.322], + ["B_338_NM_Ball", [1100, 1300], [790, 820], 7, 0.381], + ["ACE_338_Ball", [1200, 1300], [800, 830], 7, 0.381], + ["ACE_338_Ball_API526", [1200, 1300], [880, 920], 7, 0.29], + ["B_50BW_Ball_F", [300, 400], [510, 596], 1, 0.21], + ["B_127x99_Ball", [1300, 1300], [895, 905], 1, 0.67], + ["ACE_127x99_Ball_AMAX", [1600, 1600], [855, 865], 1, 1.05], + ["B_127x108_Ball", [1300, 1300], [815, 825], 1, 0.63], + ["ACE_762x51_Ball_Subsonic", [200, 300], [305, 340], 7, 0.235], + ["B_9x21_Ball", [200, 300], [380, 420], 1, 0.165], + ["ACE_9x18_Ball_57N181S", [100, 200, 200], [298, 330, 350], 1, 0.125], + ["ACE_9x19_Ball", [100, 200, 200], [340, 370, 400], 1, 0.165], + ["ACE_10x25_Ball", [200, 300, 300], [360, 400, 430], 1, 0.189], + ["ACE_765x17_Ball", [100, 200, 200], [282, 300, 320], 1, 0.118], + ["B_127x54_Ball", [500, 500], [295, 305], 1, 1.050], + ["B_45ACP_Ball", [100, 200, 200], [230, 250, 285], 1, 0.195]] + +print ("Calculating ...") +print ("") + +open('../extras/airFrictionAnalysis.txt', 'w').close() + +for ammo in ammoList: + name = ammo[0] + maxRanges = ammo[1] + mvs = ammo[2] + dragModel = ammo[3] + BC = ammo[4] + + mv = round(sum(mvs) / len(mvs)) + bestA = calculateAirFriction(mv, dragModel, BC) + if (mv < 360): + bestA = predictAirFriction(mv, mv - 20, dragModel, BC) + else: + bestA = predictAirFriction(mv, 340, dragModel, BC) + minDropDiff = 100 + interval = 0.0003 + + while interval > 0.0000001: + low = bestA - interval + high = bestA + interval + a = low + while a < high: + dropDiff = maxDropDiffV(maxRanges, mvs, a, dragModel, BC) + if dropDiff < minDropDiff: + minDropDiff = dropDiff + bestA = a + a = a + interval / 10 + + interval = interval / 2 + + print (str(name) + " -> " + str(round(bestA, 8))) + with open('../extras/airFrictionAnalysis.txt', 'a') as f: + print ("##########################################", file=f) + print ("Ammo Class: " + name, file=f) + print ("MaxRanges (m): " + str(maxRanges), file=f) + print ("MuzzleVelocities (m/s): " + str(mvs), file=f) + print ("Max. Velocity diff (m/s): " + str(round(maxVelocityDiffV(maxRanges, mvs, bestA, dragModel, BC), 2)), file=f) + print ("Max. Drop diff (cm): " + str(round(minDropDiff * 100, 2)), file=f) + print ("Max. Tof diff (ms): " + str(maxTOFDiffV(maxRanges, mvs, bestA, dragModel, BC)), file=f) + print ("Optimal airFriction: " + str(round(bestA, 8)), file=f) +