diff --git a/addons/advanced_ballistics/functions/fnc_calculateAmmoTemperatureVelocityShift.sqf b/addons/advanced_ballistics/functions/fnc_calculateAmmoTemperatureVelocityShift.sqf index 8b0c78e86c..fefdbb16e4 100644 --- a/addons/advanced_ballistics/functions/fnc_calculateAmmoTemperatureVelocityShift.sqf +++ b/addons/advanced_ballistics/functions/fnc_calculateAmmoTemperatureVelocityShift.sqf @@ -18,7 +18,8 @@ private ["_muzzleVelocityShiftTableUpperLimit", "_temperatureIndexFunction", "_temperatureIndexA", "_temperatureIndexB", "_interpolationRatio"]; params["_muzzleVelocityShiftTable", "_temperature"]; -// Check if muzzleVelocityShiftTable is Larger Than 11 Entrys +// Check if muzzleVelocityShiftTable is Less Than 11 Entrys +if ((count _muzzleVelocityShiftTable) < 11) exitWith {0}; _muzzleVelocityShiftTableUpperLimit = _muzzleVelocityShiftTable select 10; if (isNil "_muzzleVelocityShiftTableUpperLimit") exitWith { 0 }; diff --git a/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf b/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf index 7a432831ad..5874de96c4 100644 --- a/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf +++ b/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf @@ -26,19 +26,19 @@ _aceTimeSecond = floor ACE_time; _bulletSpeed = vectorMagnitude _bulletVelocity; - if (!alive _bullet || _bulletSpeed < 100) exitWith { - GVAR(allBullets) deleteAt (_forEachIndex - _deleted); - _deleted = _deleted + 1; + if (!alive _bullet || _bulletSpeed < 100) then { + GVAR(allBullets) deleteAt (GVAR(allBullets) find _x); + } else { + _bulletPosition = getPosASL _bullet; + + if (_bulletTraceVisible && _bulletSpeed > 500) then { + drop ["\A3\data_f\ParticleEffects\Universal\Refract","","Billboard",1,0.1,getPos _bullet,[0,0,0],0,1.275,1,0,[0.02*_caliber,0.01*_caliber],[[0,0,0,0.65],[0,0,0,0.2]],[1,0],0,0,"","",""]; + }; + + call compile ("ace_advanced_ballistics" callExtension format["simulate:%1:%2:%3:%4:%5:%6:%7", _index, _bulletVelocity, _bulletPosition, ACE_wind, ASLToATL(_bulletPosition) select 2, _aceTimeSecond, ACE_time - _aceTimeSecond]); }; - - _bulletPosition = getPosASL _bullet; - - if (_bulletTraceVisible && _bulletSpeed > 500) then { - drop ["\A3\data_f\ParticleEffects\Universal\Refract","","Billboard",1,0.1,getPos _bullet,[0,0,0],0,1.275,1,0,[0.02*_caliber,0.01*_caliber],[[0,0,0,0.65],[0,0,0,0.2]],[1,0],0,0,"","",""]; - }; - - call compile ("ace_advanced_ballistics" callExtension format["simulate:%1:%2:%3:%4:%5:%6:%7", _index, _bulletVelocity, _bulletPosition, ACE_wind, ASLToATL(_bulletPosition) select 2, _aceTimeSecond, ACE_time - _aceTimeSecond]); -} forEach GVAR(allBullets); + nil +} count +GVAR(allBullets); if (GVAR(allBullets) isEqualTo []) then { [_this select 1] call CBA_fnc_removePerFrameHandler; diff --git a/addons/advanced_ballistics/functions/fnc_handleFired.sqf b/addons/advanced_ballistics/functions/fnc_handleFired.sqf index d97c9b952a..8d9cb73509 100644 --- a/addons/advanced_ballistics/functions/fnc_handleFired.sqf +++ b/addons/advanced_ballistics/functions/fnc_handleFired.sqf @@ -24,12 +24,12 @@ if (!hasInterface) exitWith {}; if (!GVAR(enabled)) exitWith {}; // Parameterization -private ["_abort", "_AmmoCacheEntry", "_WeaponCacheEntry", "_opticsName", "_opticType", "_bulletTraceVisible", "_temperature", "_barometricPressure", "_bulletMass", "_bulletLength", "_muzzleVelocity", "_muzzleVelocityShift", "_bulletVelocity", "_bulletSpeed", "_bulletLength", "_barrelTwist", "_stabilityFactor"]; +private ["_abort", "_AmmoCacheEntry", "_WeaponCacheEntry", "_opticsName", "_opticType", "_bulletTraceVisible", "_temperature", "_barometricPressure", "_bulletMass", "_bulletLength", "_muzzleVelocity", "_muzzleVelocityShift", "_bulletVelocity", "_bulletLength", "_barrelTwist", "_stabilityFactor", "_aceTimeSecond", "_barrelVelocityShift", "_ammoTemperatureVelocityShift"]; + params ["_unit", "_weapon", "", "_mode", "_ammo", "_magazine", "_bullet"]; _abort = false; - if (!(_ammo isKindOf "BulletBase")) exitWith {}; if (!alive _bullet) exitWith {}; if (!([_unit] call EFUNC(common,isPlayer))) exitWith {}; @@ -75,22 +75,22 @@ _WeaponCacheEntry params ["_barrelTwist", "_twistDirection", "_barrelLength"]; _bulletVelocity = velocity _bullet; _muzzleVelocity = vectorMagnitude _bulletVelocity; +_barrelVelocityShift = 0; if (GVAR(barrelLengthInfluenceEnabled)) then { - _barrelVelocityShift = uiNamespace getVariable [format [QGVAR(%1_muzzleVelocityShift),_weapon],nil]; - if (isNil "_barrelVelocityShift") then { - _barrelVelocityShift = [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, _muzzleVelocity] call FUNC(calculateBarrelLengthVelocityShift); - uiNamespace setVariable [format [QGVAR(%1_muzzleVelocityShift),_weapon],_muzzleVelocityShift]; - }; + _barrelVelocityShift = [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, _muzzleVelocity] call FUNC(calculateBarrelLengthVelocityShift); }; +_ammoTemperatureVelocityShift = 0; if (GVAR(ammoTemperatureEnabled)) then { _temperature = ((getPosASL _unit) select 2) call EFUNC(weather,calculateTemperatureAtHeight); - _temperatureVelocityShift = ([_ammoTempMuzzleVelocityShifts, _temperature] call FUNC(calculateAmmoTemperatureVelocityShift)); + _ammoTemperatureVelocityShift = ([_ammoTempMuzzleVelocityShifts, _temperature] call FUNC(calculateAmmoTemperatureVelocityShift)); }; if (GVAR(ammoTemperatureEnabled) || GVAR(barrelLengthInfluenceEnabled)) then { + _muzzleVelocityShift = _barrelVelocityShift + _ammoTemperatureVelocityShift; + TRACE_4("shift",_muzzleVelocity,_muzzleVelocityShift, _barrelVelocityShift, _ammoTemperatureVelocityShift); if (_muzzleVelocityShift != 0) then { - _muzzleVelocity = _muzzleVelocity + (_barrelVelocityShift + _ammoTemperatureVelocityShift); + _muzzleVelocity = _muzzleVelocity + _muzzleVelocityShift; _bulletVelocity = _bulletVelocity vectorAdd ((vectorNormalized _bulletVelocity) vectorMultiply (_muzzleVelocityShift)); _bullet setVelocity _bulletVelocity; }; diff --git a/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf b/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf index 8e13dc04dc..ec6f3a6212 100644 --- a/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf +++ b/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf @@ -20,9 +20,11 @@ _weaponConfig = (configFile >> "CfgWeapons" >> _this); _barrelTwist = getNumber(_weaponConfig >> "ACE_barrelTwist"); _twistDirection = 1; -_twistDirection = getNumber(_weaponConfig >> "ACE_twistDirection"); -if !(_twistDirection in [-1, 0, 1]) then { - _twistDirection = 1; +if (isNumber (_weaponConfig >> "ACE_twistDirection")) then { + _twistDirection = getNumber (_weaponConfig >> "ACE_twistDirection"); + if !(_twistDirection in [-1, 0, 1]) then { + _twistDirection = 1; + }; }; _barrelLength = getNumber(_weaponConfig >> "ACE_barrelLength"); diff --git a/addons/captives/CfgVehicles.hpp b/addons/captives/CfgVehicles.hpp index eff1cf4c52..0cfda46128 100644 --- a/addons/captives/CfgVehicles.hpp +++ b/addons/captives/CfgVehicles.hpp @@ -192,6 +192,7 @@ class CfgVehicles { scope = 2; icon = QUOTE(PATHTOF(UI\Icon_Module_settings_ca.paa)); isGlobal = 1; + isSingular = 1; class Arguments { class allowHandcuffOwnSide { displayName = CSTRING(ModuleSettings_handcuffSide_name); diff --git a/addons/captives/functions/fnc_handlePlayerChanged.sqf b/addons/captives/functions/fnc_handlePlayerChanged.sqf index aea91b5e11..3ff0e00752 100644 --- a/addons/captives/functions/fnc_handlePlayerChanged.sqf +++ b/addons/captives/functions/fnc_handlePlayerChanged.sqf @@ -21,10 +21,10 @@ params ["_newUnit","_oldUnit"]; //set showHUD based on new unit status: if ((_newUnit getVariable [QGVAR(isHandcuffed), false]) || {_newUnit getVariable [QGVAR(isSurrendering), false]}) then { TRACE_1("Player Change (showHUD false)",_newUnit); - showHUD false; + ["captive", [false, false, false, false, false, false, false, false]] call EFUNC(common,showHud); } else { TRACE_1("Player Change (showHUD true)",_newUnit); - showHUD true; + ["captive", []] call EFUNC(common,showHud); //same as showHud true; }; //If old player was escorting, stop diff --git a/addons/captives/functions/fnc_handleZeusDisplayChanged.sqf b/addons/captives/functions/fnc_handleZeusDisplayChanged.sqf index 7b30199caf..ef8aedbbe1 100644 --- a/addons/captives/functions/fnc_handleZeusDisplayChanged.sqf +++ b/addons/captives/functions/fnc_handleZeusDisplayChanged.sqf @@ -23,9 +23,9 @@ params ["_unit","_zeusIsOpen"]; if (!_zeusIsOpen) then { if ((_unit getVariable [QGVAR(isHandcuffed), false]) || {_unit getVariable [QGVAR(isSurrendering), false]}) then { TRACE_1("Player Change (showHUD false)",_unit); - showHUD false; + ["captive", [false, false, false, false, false, false, false, false]] call EFUNC(common,showHud); } else { TRACE_1("Player Change (showHUD true)",_unit); - showHUD true; + ["captive", []] call EFUNC(common,showHud); //same as showHud true; }; }; diff --git a/addons/captives/functions/fnc_setHandcuffed.sqf b/addons/captives/functions/fnc_setHandcuffed.sqf index 0bc2e85c52..b6061418d8 100644 --- a/addons/captives/functions/fnc_setHandcuffed.sqf +++ b/addons/captives/functions/fnc_setHandcuffed.sqf @@ -38,7 +38,7 @@ if (_state) then { _unit setVariable [QGVAR(CargoIndex), ((vehicle _unit) getCargoIndex _unit), true]; if (_unit == ACE_player) then { - showHUD false; + ["captive", [false, false, false, false, false, false, false, false]] call EFUNC(common,showHud); }; // fix anim on mission start (should work on dedicated servers) @@ -56,7 +56,7 @@ if (_state) then { //Adds an animation changed eh //If we get a change in animation then redo the animation (handles people vaulting to break the animation chain) - local _animChangedEHID = _unit getVariable [QGVAR(handcuffAnimEHID), -1]; + private _animChangedEHID = _unit getVariable [QGVAR(handcuffAnimEHID), -1]; if (_animChangedEHID != -1) then { TRACE_1("removing animChanged EH",_animChangedEHID); _unit removeEventHandler ["AnimChanged", _animChangedEHID]; @@ -92,7 +92,7 @@ if (_state) then { [_unit, QGVAR(Handcuffed), false] call EFUNC(common,setCaptivityStatus); //remove AnimChanged EH - local _animChangedEHID = _unit getVariable [QGVAR(handcuffAnimEHID), -1]; + private _animChangedEHID = _unit getVariable [QGVAR(handcuffAnimEHID), -1]; TRACE_1("removing animChanged EH",_animChangedEHID); _unit removeEventHandler ["AnimChanged", _animChangedEHID]; _unit setVariable [QGVAR(handcuffAnimEHID), -1]; @@ -107,7 +107,7 @@ if (_state) then { }; if (_unit == ACE_player) then { - showHUD true; + ["captive", []] call EFUNC(common,showHud); //same as showHud true; }; }; diff --git a/addons/captives/functions/fnc_setSurrendered.sqf b/addons/captives/functions/fnc_setSurrendered.sqf index 171455f3b1..995b0c613d 100644 --- a/addons/captives/functions/fnc_setSurrendered.sqf +++ b/addons/captives/functions/fnc_setSurrendered.sqf @@ -36,7 +36,7 @@ if (_state) then { [_unit, QGVAR(Surrendered), true] call EFUNC(common,setCaptivityStatus); if (_unit == ACE_player) then { - showHUD false; + ["captive", [false, false, false, false, false, false, false, false]] call EFUNC(common,showHud); }; [_unit] call EFUNC(common,fixLoweredRifleAnimation); @@ -48,7 +48,7 @@ if (_state) then { if (_unit getVariable [QGVAR(isSurrendering), false] && {(vehicle _unit) == _unit}) then { //Adds an animation changed eh //If we get a change in animation then redo the animation (handles people vaulting to break the animation chain) - local _animChangedEHID = _unit getVariable [QGVAR(surrenderAnimEHID), -1]; + private _animChangedEHID = _unit getVariable [QGVAR(surrenderAnimEHID), -1]; if (_animChangedEHID != -1) then { TRACE_1("removing animChanged EH",_animChangedEHID); _unit removeEventHandler ["AnimChanged", _animChangedEHID]; @@ -68,14 +68,14 @@ if (_state) then { [_unit, QGVAR(Surrendered), false] call EFUNC(common,setCaptivityStatus); //remove AnimChanged EH - local _animChangedEHID = _unit getVariable [QGVAR(surrenderAnimEHID), -1]; + private _animChangedEHID = _unit getVariable [QGVAR(surrenderAnimEHID), -1]; _unit removeEventHandler ["AnimChanged", _animChangedEHID]; _unit setVariable [QGVAR(surrenderAnimEHID), -1]; if (_unit == ACE_player) then { //only re-enable HUD if not handcuffed if (!(_unit getVariable [QGVAR(isHandcuffed), false])) then { - showHUD true; + ["captive", []] call EFUNC(common,showHud); //same as showHud true; }; }; diff --git a/addons/captives/stringtable.xml b/addons/captives/stringtable.xml index 4d2eae2fd2..2d202ed852 100644 --- a/addons/captives/stringtable.xml +++ b/addons/captives/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -166,7 +166,7 @@ Fazer unidade se render Faire capituler l'unité Egység kapitulálása - Сделать юнита пленным + Заставить юнита сдаться Sync a unit to make them surrender.<br />Source: ace_captives @@ -177,15 +177,19 @@ Sincroniza uma unidade para fazer com que ela se renda. <br/>Fonte: ace_captives Synchronise une unité pour la rendre captive. <br/>Source: ace_captives Egység szinkronizálása, hogy kapituláljon.<br />Forrás: ace_captives - Синхронизируйте с юнитами, чтобы сделать их пленными.<br />Источник: ace_captives + Синхронизируйте с юнитами, чтобы заставить их сдаться в плен.<br />Источник: ace_captives Make Unit Handcuffed Skuj jednostkę + Fazer unidade algemada + Связать юнита Sync a unit to make them handcuffed.<br />Source: ace_captives Zsynchronizuj z jednostką, aby została skuta.<br />Źródło: ace_captives + Sincronizar uma unidade para deixá-la algemada.<br/>Source: ace_captives + Синхронизируйте с юнитами, чтобы сделать их связанными.<br />Источник: ace_captives Captives Settings diff --git a/addons/cargo/CfgVehicles.hpp b/addons/cargo/CfgVehicles.hpp index 56e3aee2c2..1204c35496 100644 --- a/addons/cargo/CfgVehicles.hpp +++ b/addons/cargo/CfgVehicles.hpp @@ -8,6 +8,7 @@ class CfgVehicles { function = QFUNC(moduleSettings); functionPriority = 1; isGlobal = 1; + isSingular = 1; isTriggerActivated = 0; author = ECSTRING(common,ACETeam); diff --git a/addons/cargo/XEH_postInit.sqf b/addons/cargo/XEH_postInit.sqf index 6501044c9d..2aeb3ab630 100644 --- a/addons/cargo/XEH_postInit.sqf +++ b/addons/cargo/XEH_postInit.sqf @@ -1,5 +1,45 @@ #include "script_component.hpp" -["LoadCargo", {_this call FUNC(loadItem)}] call EFUNC(common,addEventHandler); -["UnloadCargo", {_this call FUNC(unloadItem)}] call EFUNC(common,addEventHandler); ["AddCargoByClass", {_this call FUNC(addCargoItem)}] call EFUNC(common,addEventHandler); + +["LoadCargo", { + (_this select 0) params ["_item","_vehicle"]; + private ["_loaded", "_hint", "_itemName", "_vehicleName"]; + + _loaded = [_item, _vehicle] call FUNC(loadItem); + + // Show hint as feedback + _hint = [LSTRING(LoadingFailed), LSTRING(LoadedItem)] select _loaded; + _itemName = getText (configFile >> "CfgVehicles" >> typeOf _item >> "displayName"); + _vehicleName = getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName"); + + ["displayTextStructured", [[_hint, _itemName, _vehicleName], 3.0]] call EFUNC(common,localEvent); + + if (_loaded) then { + // Invoke listenable event + ["cargoLoaded", [_item, _vehicle]] call EFUNC(common,globalEvent); + }; +}] call EFUNC(common,addEventHandler); + +["UnloadCargo", { + (_this select 0) params ["_item","_vehicle"]; + private ["_unloaded", "_itemClass", "_hint", "_itemName", "_vehicleName"]; + + _unloaded = [_item, _vehicle] call FUNC(unloadItem); + + _itemClass = if (typeName _item == "STRING") then {_item} else {typeOf _item}; + + // Show hint as feedback + _hint = [LSTRING(UnloadingFailed), LSTRING(UnloadedItem)] select _unloaded; + _itemName = getText (configFile >> "CfgVehicles" >> _itemClass >> "displayName"); + _vehicleName = getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName"); + + ["displayTextStructured", [[_hint, _itemName, _vehicleName], 3.0]] call EFUNC(common,localEvent); + + if (_unloaded) then { + // Invoke listenable event + ["cargoUnloaded", [_item, _vehicle]] call EFUNC(common,globalEvent); + }; + + // TOOO maybe drag/carry the unloaded item? +}] call EFUNC(common,addEventHandler); diff --git a/addons/cargo/functions/fnc_addCargoItem.sqf b/addons/cargo/functions/fnc_addCargoItem.sqf index 9f349153c0..a44cd0ebcf 100644 --- a/addons/cargo/functions/fnc_addCargoItem.sqf +++ b/addons/cargo/functions/fnc_addCargoItem.sqf @@ -18,24 +18,12 @@ */ #include "script_component.hpp" -private ["_position", "_item", "_i"]; params ["_itemClass", "_vehicle", ["_amount", 1], ["_showHint", false, [false]] ]; TRACE_3("params",_itemClass,_vehicle,_amount); -_position = getPos _vehicle; -_position set [1, (_position select 1) + 1]; -_position set [2, (_position select 2) + 7.5]; - for "_i" from 1 to _amount do { - _item = createVehicle [_itemClass, _position, [], 0, "CAN_COLLIDE"]; - - // Load item or delete it if no space left - if !([_item, _vehicle, _showHint] call FUNC(loadItem)) exitWith { - TRACE_1("no room to load item - deleting",_item); - deleteVehicle _item; - }; - TRACE_1("Item Loaded",_item); - - // Invoke listenable event - ["cargoAddedByClass", [_itemClass, _vehicle, _amount]] call EFUNC(common,globalEvent); + [_itemClass, _vehicle] call FUNC(loadItem); }; + +// Invoke listenable event +["cargoAddedByClass", [_itemClass, _vehicle, _amount]] call EFUNC(common,globalEvent); diff --git a/addons/cargo/functions/fnc_canLoadItemIn.sqf b/addons/cargo/functions/fnc_canLoadItemIn.sqf index 8cfe9e194b..fda60aaf65 100644 --- a/addons/cargo/functions/fnc_canLoadItemIn.sqf +++ b/addons/cargo/functions/fnc_canLoadItemIn.sqf @@ -3,7 +3,7 @@ * Check if item can be loaded into other Object. * * Arguments: - * 0: Item Object + * 0: Item * 1: Holder Object (Vehicle) * * Return value: @@ -16,14 +16,24 @@ */ #include "script_component.hpp" -params ["_item", "_vehicle"]; +params [["_item", "", [objNull,""]], "_vehicle"]; if (speed _vehicle > 1 || (((getPos _vehicle) select 2) > 3)) exitWith {false}; -private "_itemSize"; -_itemSize = ([_item] call FUNC(getSizeItem)); +private ["_itemSize", "_validItem"]; +_itemSize = [_item] call FUNC(getSizeItem); -(_itemSize > 0) && -{alive _item && alive _vehicle} && -{(_item distance _vehicle <= MAX_LOAD_DISTANCE)} && +if (typeName _item == "STRING") then { + _validItem = + isClass (configFile >> "CfgVehicles" >> _item) && + {getNumber (configFile >> "CfgVehicles" >> _item >> QGVAR(canLoad)) == 1}; +} else { + _validItem = + (alive _item) && + {(_item distance _vehicle) <= MAX_LOAD_DISTANCE}; +}; + +_validItem && +{_itemSize > 0} && +{alive _vehicle} && {_itemSize <= ([_vehicle] call FUNC(getCargoSpaceLeft))} diff --git a/addons/cargo/functions/fnc_canUnloadItem.sqf b/addons/cargo/functions/fnc_canUnloadItem.sqf index 779a7533a9..8c741a5448 100644 --- a/addons/cargo/functions/fnc_canUnloadItem.sqf +++ b/addons/cargo/functions/fnc_canUnloadItem.sqf @@ -16,18 +16,19 @@ */ #include "script_component.hpp" -private ["_loaded", "_validVehiclestate", "_emptyPos"]; - params ["_item", "_vehicle"]; +private ["_loaded", "_itemClass", "_validVehiclestate", "_emptyPos"]; _loaded = _vehicle getVariable [QGVAR(loaded), []]; if !(_item in _loaded) exitWith {false}; +_itemClass = if (typeName _item == "STRING") then {_item} else {typeOf _item}; + _validVehiclestate = true; _emptyPos = []; if (_vehicle isKindOf "Ship" ) then { if !(speed _vehicle <1 && {(((getPosATL _vehicle) select 2) < 2)}) then {_validVehiclestate = false}; - _emptyPos = ((getPosASL _vehicle) call EFUNC(common,ASLtoPosition) findEmptyPosition [0, 15, typeOf _item]); // TODO: if spot is underwater pick another spot. + _emptyPos = ((getPosASL _vehicle) call EFUNC(common,ASLtoPosition) findEmptyPosition [0, 15, _itemClass]); // TODO: if spot is underwater pick another spot. } else { if (_vehicle isKindOf "Air" ) then { if !(speed _vehicle <1 && {isTouchingGround _vehicle}) then {_validVehiclestate = false}; @@ -35,7 +36,7 @@ if (_vehicle isKindOf "Ship" ) then { _emptyPos = [(_emptyPos select 0) + random(5), (_emptyPos select 1) + random(5), _emptyPos select 2 ]; } else { if !(speed _vehicle <1 && {(((getPosATL _vehicle) select 2) < 2)}) then {_validVehiclestate = false}; - _emptyPos = ((getPosASL _vehicle) call EFUNC(common,ASLtoPosition) findEmptyPosition [0, 15, typeOf _item]); + _emptyPos = ((getPosASL _vehicle) call EFUNC(common,ASLtoPosition) findEmptyPosition [0, 15, _itemClass]); }; }; diff --git a/addons/cargo/functions/fnc_getSizeItem.sqf b/addons/cargo/functions/fnc_getSizeItem.sqf index dacd6a4982..807251365c 100644 --- a/addons/cargo/functions/fnc_getSizeItem.sqf +++ b/addons/cargo/functions/fnc_getSizeItem.sqf @@ -3,7 +3,7 @@ * Get the cargo size of an object. * * Arguments: - * 0: Object + * 0: Item * * Return value: * Cargo size (default: -1) @@ -15,14 +15,24 @@ */ #include "script_component.hpp" -private "_config"; - params ["_item"]; +private ["_isVirtual","_itemClass","_config"]; +scopeName "return"; -_config = (configFile >> "CfgVehicles" >> typeOf _item >> QGVAR(size)); +_isVirtual = (typeName _item == "STRING"); +_itemClass = if (_isVirtual) then {_item} else {typeOf _item}; +_config = (configFile >> "CfgVehicles" >> _itemClass >> QGVAR(size)); -if (isNumber (_config)) exitWith { - _item getVariable [QGVAR(size), getNumber (_config)] +if (_isVirtual) then { + if (isNumber _config) then { + (getNumber _config) breakOut "return"; + }; +} else { + _config = (configFile >> "CfgVehicles" >> typeOf _item >> QGVAR(size)); + + if (isNumber _config) then { + (_item getVariable [QGVAR(size), getNumber _config]) breakOut "return"; + }; }; -1 diff --git a/addons/cargo/functions/fnc_handleDestroyed.sqf b/addons/cargo/functions/fnc_handleDestroyed.sqf index c11dd3bfad..1022497719 100644 --- a/addons/cargo/functions/fnc_handleDestroyed.sqf +++ b/addons/cargo/functions/fnc_handleDestroyed.sqf @@ -20,12 +20,13 @@ params ["_vehicle"]; private["_loaded"]; _loaded = _vehicle getVariable [QGVAR(loaded), []]; -if (count _loaded == 0) exitWith {}; +if (_loaded isEqualTo []) exitWith {}; { - // TODO deleteVehicle or just delete vehicle? Do we want to be able to recover destroyed equipment? - deleteVehicle _x; - //_x setDamage 1; + // TODO Do we want to be able to recover destroyed equipment? + if (typeName _x == "OBJECT") then { + deleteVehicle _x; + }; } count _loaded; [_vehicle] call FUNC(validateCargoSpace); diff --git a/addons/cargo/functions/fnc_loadItem.sqf b/addons/cargo/functions/fnc_loadItem.sqf index 11e7638f1b..45746a93fd 100644 --- a/addons/cargo/functions/fnc_loadItem.sqf +++ b/addons/cargo/functions/fnc_loadItem.sqf @@ -1,9 +1,10 @@ /* * Author: Glowbal * Load object into vehicle. + * Objects loaded via classname remain virtual until unloaded. * * Arguments: - * 0: Object + * 0: Item * 1: Vehicle * 2: Show Hint (default: true) * @@ -17,15 +18,10 @@ */ #include "script_component.hpp" +params [["_item","",[objNull,""]], ["_vehicle",objNull,[objNull]]]; private ["_loaded", "_space", "_itemSize"]; -params ["_item", "_vehicle", ["_showHint", true, [true]] ]; -TRACE_2("params",_item,_vehicle); - -if !([_item, _vehicle] call FUNC(canLoadItemIn)) exitWith { - TRACE_2("canLoadItemIn failed",_item,_vehicle); - false -}; +if !([_item, _vehicle] call FUNC(canLoadItemIn)) exitWith {false}; _loaded = _vehicle getVariable [QGVAR(loaded), []]; _loaded pushback _item; @@ -37,21 +33,10 @@ _space = [_vehicle] call FUNC(getCargoSpaceLeft); _itemSize = [_item] call FUNC(getSizeItem); _vehicle setVariable [QGVAR(space), _space - _itemSize, true]; -detach _item; -_item attachTo [_vehicle,[0,0,100]]; -["hideObjectGlobal", [_item, true]] call EFUNC(common,serverEvent); - -// show hint -private ["_itemName", "_vehicleName"]; - -_itemName = getText (configFile >> "CfgVehicles" >> typeOf _item >> "displayName"); -_vehicleName = getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName"); - -if (_showHint) then { - ["displayTextStructured", [[localize LSTRING(LoadedItem), _itemName, _vehicleName], 3.0]] call EFUNC(common,localEvent); +if (typeName _item == "OBJECT") then { + detach _item; + _item attachTo [_vehicle,[0,0,-100]]; + ["hideObjectGlobal", [_item, true]] call EFUNC(common,serverEvent); }; -// Invoke listenable event -["cargoLoaded", [_item, _vehicle]] call EFUNC(common,globalEvent); - true diff --git a/addons/cargo/functions/fnc_onMenuOpen.sqf b/addons/cargo/functions/fnc_onMenuOpen.sqf index 031bea01cc..85557835bf 100644 --- a/addons/cargo/functions/fnc_onMenuOpen.sqf +++ b/addons/cargo/functions/fnc_onMenuOpen.sqf @@ -22,7 +22,7 @@ params ["_display"]; uiNamespace setVariable [QGVAR(menuDisplay), _display]; [{ - private ["_display","_loaded", "_ctrl", "_label"]; + private ["_display","_loaded", "_ctrl", "_class", "_label"]; disableSerialization; _display = uiNamespace getVariable QGVAR(menuDisplay); if (isnil "_display") exitWith { @@ -40,7 +40,8 @@ uiNamespace setVariable [QGVAR(menuDisplay), _display]; lbClear _ctrl; { - _ctrl lbAdd (getText(configfile >> "CfgVehicles" >> typeOf _x >> "displayName")); + _class = if (typeName _x == "STRING") then {_x} else {typeOf _x}; + _ctrl lbAdd (getText(configfile >> "CfgVehicles" >> _class >> "displayName")); true } count _loaded; diff --git a/addons/cargo/functions/fnc_startLoadIn.sqf b/addons/cargo/functions/fnc_startLoadIn.sqf index b4ba50fbb6..1ce5d62407 100644 --- a/addons/cargo/functions/fnc_startLoadIn.sqf +++ b/addons/cargo/functions/fnc_startLoadIn.sqf @@ -16,16 +16,25 @@ #include "script_component.hpp" params ["_player", "_object"]; +private ["_vehicle", "_size", "_displayName"]; -private ["_nearestVehicle"]; -_nearestVehicle = [_player] call FUNC(findNearestVehicle); +_vehicle = [_player] call FUNC(findNearestVehicle); -if (isNull _nearestVehicle || _nearestVehicle isKindOf "Cargo_Base_F") then { +if (isNull _vehicle || _vehicle isKindOf "Cargo_Base_F") then { { - if ([_object, _x] call FUNC(canLoadItemIn)) exitWith {_nearestVehicle = _x}; + if ([_object, _x] call FUNC(canLoadItemIn)) exitWith {_vehicle = _x}; } foreach (nearestObjects [_player, ["Cargo_base_F", "Land_PaperBox_closed_F"], MAX_LOAD_DISTANCE]); }; -if (isNull _nearestVehicle) exitWith {false}; +if (isNull _vehicle) exitWith {false}; -[_object, _nearestVehicle] call FUNC(loadItem) +// Start progress bar +if ([_object, _vehicle] call FUNC(canLoadItemIn)) then { + _size = [_object] call FUNC(getSizeItem); + + [5 * _size, [_object,_vehicle], "LoadCargo", {}, localize LSTRING(LoadingItem)] call EFUNC(common,progressBar); +} else { + _displayName = getText (configFile >> "CfgVehicles" >> typeOf _object >> "displayName"); + + ["displayTextStructured", [[LSTRING(LoadingFailed), _displayName], 3.0]] call EFUNC(common,localEvent); +}; diff --git a/addons/cargo/functions/fnc_startUnload.sqf b/addons/cargo/functions/fnc_startUnload.sqf index 28ae034167..013de1dc64 100644 --- a/addons/cargo/functions/fnc_startUnload.sqf +++ b/addons/cargo/functions/fnc_startUnload.sqf @@ -20,7 +20,7 @@ private ["_display", "_loaded", "_ctrl", "_selected", "_item"]; disableSerialization; _display = uiNamespace getVariable QGVAR(menuDisplay); -if (isnil "_display") exitWith {}; +if (isNil "_display") exitWith {}; _loaded = GVAR(interactionVehicle) getVariable [QGVAR(loaded), []]; if (count _loaded == 0) exitWith {}; @@ -32,4 +32,17 @@ _selected = (lbCurSel _ctrl) max 0; if (count _loaded <= _selected) exitWith {}; _item = _loaded select _selected; -[_item, GVAR(interactionVehicle)] call FUNC(unloadItem); + +// Start progress bar +private ["_size", "_itemClass", "_displayName"]; + +if ([_item, GVAR(interactionVehicle)] call FUNC(canUnloadItem)) then { + _size = [_item] call FUNC(getSizeItem); + + [5 * _size, [_item, GVAR(interactionVehicle)], "UnloadCargo", {}, localize LSTRING(UnloadingItem)] call EFUNC(common,progressBar); +} else { + _itemClass = if (typeName _item == "STRING") then {_item} else {typeOf _item}; + _displayName = getText (configFile >> "CfgVehicles" >> _itemClass >> "displayName"); + + ["displayTextStructured", [[LSTRING(UnloadingFailed), _displayName], 3.0]] call EFUNC(common,localEvent); +}; diff --git a/addons/cargo/functions/fnc_unloadItem.sqf b/addons/cargo/functions/fnc_unloadItem.sqf index 2630f2104a..81cca7154b 100644 --- a/addons/cargo/functions/fnc_unloadItem.sqf +++ b/addons/cargo/functions/fnc_unloadItem.sqf @@ -3,7 +3,7 @@ * Unload object from vehicle. * * Arguments: - * 0: Object + * 0: Item * 1: Vehicle * * Return value: @@ -16,20 +16,21 @@ */ #include "script_component.hpp" -private ["_loaded", "_space", "_itemSize", "_emptyPos", "_validVehiclestate"]; - params ["_item", "_vehicle"]; +private ["_loaded", "_space", "_itemSize", "_emptyPos", "_validVehiclestate"]; if !([_item, _vehicle] call FUNC(canUnloadItem)) exitWith { false }; +_itemClass = if (typeName _item == "STRING") then {_item} else {typeOf _item}; + _validVehiclestate = true; _emptyPos = []; if (_vehicle isKindOf "Ship" ) then { if !(speed _vehicle <1 && {(((getPosATL _vehicle) select 2) < 2)}) then {_validVehiclestate = false}; TRACE_1("SHIP Ground Check", getPosATL _vehicle ); - _emptyPos = ((getPosASL _vehicle) call EFUNC(common,ASLtoPosition) findEmptyPosition [0, 15, typeOf _item]); // TODO: if spot is underwater pick another spot. + _emptyPos = ((getPosASL _vehicle) call EFUNC(common,ASLtoPosition) findEmptyPosition [0, 15, _itemClass]); // TODO: if spot is underwater pick another spot. } else { if (_vehicle isKindOf "Air" ) then { if !(speed _vehicle <1 && {isTouchingGround _vehicle}) then {_validVehiclestate = false}; @@ -39,38 +40,29 @@ if (_vehicle isKindOf "Ship" ) then { } else { if !(speed _vehicle <1 && {(((getPosATL _vehicle) select 2) < 2)}) then {_validVehiclestate = false}; TRACE_1("Vehicle Ground Check", isTouchingGround _vehicle); - _emptyPos = ((getPosASL _vehicle) call EFUNC(common,ASLtoPosition) findEmptyPosition [0, 13, typeOf _item]); + _emptyPos = ((getPosASL _vehicle) call EFUNC(common,ASLtoPosition) findEmptyPosition [0, 13, _itemClass]); }; }; TRACE_1("getPosASL Vehicle Check", getPosASL _vehicle); if (!_validVehiclestate) exitWith {false}; -if (count _emptyPos == 0) exitWith {false}; //consider displaying text saying there are no safe places to exit the vehicle +if (count _emptyPos == 0) exitWith {false}; _loaded = _vehicle getVariable [QGVAR(loaded), []]; -_loaded = _loaded - [_item]; +_loaded deleteAt (_loaded find _item); _vehicle setVariable [QGVAR(loaded), _loaded, true]; _space = [_vehicle] call FUNC(getCargoSpaceLeft); _itemSize = [_item] call FUNC(getSizeItem); _vehicle setVariable [QGVAR(space), (_space + _itemSize), true]; -detach _item; -_item setPosASL (_emptyPos call EFUNC(common,PositiontoASL)); -["hideObjectGlobal", [_item, false]] call EFUNC(common,serverEvent); - -// show hint -private ["_itemName", "_vehicleName"]; - -_itemName = getText (configFile >> "CfgVehicles" >> typeOf _item >> "displayName"); -_vehicleName = getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName"); - -["displayTextStructured", [[localize LSTRING(UnloadedItem), _itemName, _vehicleName], 3.0]] call EFUNC(common,localEvent); - -// TOOO maybe drag/carry the unloaded item? - -// Invoke listenable event -["cargoUnloaded", [_item, _vehicle]] call EFUNC(common,globalEvent); +if (typeName _item == "OBJECT") then { + detach _item; + _item setPosASL (_emptyPos call EFUNC(common,PositiontoASL)); + ["hideObjectGlobal", [_item, false]] call EFUNC(common,serverEvent); +} else { + createVehicle [_item, _emptyPos, [], 0, ""]; +}; true diff --git a/addons/cargo/functions/fnc_validateCargoSpace.sqf b/addons/cargo/functions/fnc_validateCargoSpace.sqf index 6caf664ca5..7634b131e6 100644 --- a/addons/cargo/functions/fnc_validateCargoSpace.sqf +++ b/addons/cargo/functions/fnc_validateCargoSpace.sqf @@ -24,7 +24,7 @@ _loaded = _vehicle getVariable [QGVAR(loaded), []]; _newLoaded = []; _totalSpaceOccupied = 0; { - if !(isNull _x) then { + if ((typeName _x == "STRING") || {!isNull _x}) then { _newLoaded pushback _x; _totalSpaceOccupied = _totalSpaceOccupied + ([_x] call FUNC(getSizeItem)); }; @@ -35,4 +35,4 @@ if (count _loaded != count _newLoaded) then { _vehicle setVariable [QGVAR(loaded), _newLoaded, true]; }; -_vehicle setVariable [QGVAR(space), getNumber (configFile >> "CfgVehicles" >> typeof _vehicle >> QGVAR(space)) - _totalSpaceOccupied, true]; +_vehicle setVariable [QGVAR(space), getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> QGVAR(space)) - _totalSpaceOccupied, true]; diff --git a/addons/cargo/stringtable.xml b/addons/cargo/stringtable.xml index 7f9ac40a15..4b33f9826b 100644 --- a/addons/cargo/stringtable.xml +++ b/addons/cargo/stringtable.xml @@ -95,5 +95,21 @@ 1%<br/>kirakodva ebből:<br/>%2 %1<br/>разгружен из<br/>%2 + + Loading Cargo + Carregando carga + + + Unloading Cargo + Descarregando carga + + + %1<br/>could not be loaded + %1<br/>não pode ser carregado + + + %1<br/>could not be unloaded + %1<br/>não pode ser descarregado + - + \ No newline at end of file diff --git a/addons/common/CfgVehicles.hpp b/addons/common/CfgVehicles.hpp index 7c5c9295f9..de1f7f7cf4 100644 --- a/addons/common/CfgVehicles.hpp +++ b/addons/common/CfgVehicles.hpp @@ -35,6 +35,7 @@ class CfgVehicles { function = QFUNC(moduleCheckPBOs); scope = 2; isGlobal = 1; + isSingular = 1; icon = QUOTE(PATHTOF(UI\Icon_Module_CheckPBO_ca.paa)); class Arguments { class Action { diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index 032b6148be..0ca9f51329 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -13,7 +13,7 @@ //Handle the waitAndExec array: while {!(GVAR(waitAndExecArray) isEqualTo []) && {GVAR(waitAndExecArray) select 0 select 0 <= ACE_Time}} do { - local _entry = GVAR(waitAndExecArray) deleteAt 0; + private _entry = GVAR(waitAndExecArray) deleteAt 0; (_entry select 2) call (_entry select 1); }; @@ -29,17 +29,16 @@ GVAR(nextFrameNo) = diag_frameno + 1; //Handle the waitUntilAndExec array: - local _deleted = 0; { // if condition is satisifed call statement if ((_x select 2) call (_x select 0)) then { // make sure to delete the correct handle when multiple conditions are met in one frame - GVAR(waitUntilAndExecArray) deleteAt (_forEachIndex - _deleted); - _deleted = _deleted + 1; + GVAR(waitUntilAndExecArray) deleteAt (GVAR(waitUntilAndExecArray) find _x); (_x select 2) call (_x select 1); }; - } forEach GVAR(waitUntilAndExecArray); - + nil + } count +GVAR(waitUntilAndExecArray); + END_COUNTER(waitAndExec); }, 0, []] call CBA_fnc_addPerFrameHandler; @@ -98,7 +97,6 @@ ["setFuel", {(_this select 0) setFuel (_this select 1)}] call FUNC(addEventhandler); ["setSpeaker", {(_this select 0) setSpeaker (_this select 1)}] call FUNC(addEventhandler); ["selectLeader", {(_this select 0) selectLeader (_this select 1)}] call FUNC(addEventHandler); -["assignTeam", {(_this select 0) assignTeam (_this select 1)}] call FUNC(addEventHandler); ["setVelocity", {(_this select 0) setVelocity (_this select 1)}] call FUNC(addEventHandler); if (isServer) then { @@ -194,9 +192,17 @@ call FUNC(checkFiles); ACE_LOGINFO("Settings received from server."); + if (isServer) then { //read settings from paramsArray + [] call FUNC(readSettingsFromParamsArray); + }; // Event so that ACE_Modules have their settings loaded: ["InitSettingsFromModules", []] call FUNC(localEvent); + if (isServer) then { + // Publish all settings data after all configs and modules are read + publicVariable QGVAR(settings); + }; + // Load user settings from profile if (hasInterface) then { call FUNC(loadSettingsFromProfile); diff --git a/addons/common/XEH_preInit.sqf b/addons/common/XEH_preInit.sqf index a9b10c4896..3180eacb86 100644 --- a/addons/common/XEH_preInit.sqf +++ b/addons/common/XEH_preInit.sqf @@ -115,6 +115,7 @@ PREP(isInBuilding); PREP(isModLoaded); PREP(isPlayer); PREP(isTurnedOut); +PREP(isUnderwater); PREP(letterToCode); PREP(lightIntensityFromObject); PREP(loadPerson); @@ -139,6 +140,7 @@ PREP(playerSide); PREP(positionToASL); PREP(progressBar); PREP(readSettingFromModule); +PREP(readSettingsFromParamsArray); PREP(receiveRequest); PREP(removeCanInteractWithCondition); PREP(removeSpecificMagazine); @@ -166,6 +168,7 @@ PREP(setVariableJIP); PREP(setVariablePublic); PREP(setVolume); PREP(sortAlphabeticallyBy); +PREP(showHud); PREP(stringCompare); PREP(stringToColoredText); PREP(stringRemoveWhiteSpace); @@ -290,6 +293,7 @@ PREP(hashListSet); PREP(hashListPush); GVAR(syncedEvents) = HASH_CREATE; +GVAR(showHudHash) = [] call FUNC(hashCreate); //GVARS for execNextFrame and waitAndExec and waitUntilAndExecute GVAR(waitAndExecArray) = []; diff --git a/addons/common/functions/fnc_dumpArray.sqf b/addons/common/functions/fnc_dumpArray.sqf index 010736d3a9..026b08501e 100644 --- a/addons/common/functions/fnc_dumpArray.sqf +++ b/addons/common/functions/fnc_dumpArray.sqf @@ -18,7 +18,7 @@ params ["_var", ["_depth", 0, [0]]]; -local _pad = ""; +private _pad = ""; for "_i" from 0 to _depth do { _pad = _pad + toString [9]; diff --git a/addons/common/functions/fnc_getHitPointsWithSelections.sqf b/addons/common/functions/fnc_getHitPointsWithSelections.sqf index b0b9867cf7..aef415a54f 100644 --- a/addons/common/functions/fnc_getHitPointsWithSelections.sqf +++ b/addons/common/functions/fnc_getHitPointsWithSelections.sqf @@ -24,7 +24,7 @@ _hitPointsWithSelections = getAllHitPointsDamage _vehicle; // get correct format on vehicles without any hitpoints if (_hitPointsWithSelections isEqualTo []) then { - _hitPointsWithSelections = [[],[],[]]; + _hitPointsWithSelections = [[],[],[]]; }; _hitPointsWithSelections resize 2; diff --git a/addons/common/functions/fnc_getTurretIndex.sqf b/addons/common/functions/fnc_getTurretIndex.sqf index 050f3e1c4f..20ee178bf1 100644 --- a/addons/common/functions/fnc_getTurretIndex.sqf +++ b/addons/common/functions/fnc_getTurretIndex.sqf @@ -17,7 +17,7 @@ params ["_unit"]; -local _vehicle = vehicle _unit; +private _vehicle = vehicle _unit; if (_unit == _vehicle) exitWith {[]}; scopeName "main"; diff --git a/addons/common/functions/fnc_hasHatch.sqf b/addons/common/functions/fnc_hasHatch.sqf index 124eed78a5..a67ad0b0d3 100644 --- a/addons/common/functions/fnc_hasHatch.sqf +++ b/addons/common/functions/fnc_hasHatch.sqf @@ -14,11 +14,11 @@ params ["_unit"]; -local _vehicle = vehicle _unit; +private _vehicle = vehicle _unit; if (_unit == _vehicle) exitWith {false}; -local _config = configFile >> "CfgVehicles" >> typeOf _vehicle; +private _config = configFile >> "CfgVehicles" >> typeOf _vehicle; if (getNumber (_config >> "hideProxyInCombat") != 1) exitWith {false}; @@ -26,10 +26,10 @@ if (_unit == driver _vehicle) exitWith { getNumber (_config >> "forceHideDriver") == 0; // return }; -local _turret = [_unit] call FUNC(getTurretIndex); +private _turret = [_unit] call FUNC(getTurretIndex); if (_turret isEqualTo []) exitWith {false}; -local _turretConfig = [_config, _turret] call FUNC(getTurretConfigPath); +private _turretConfig = [_config, _turret] call FUNC(getTurretConfigPath); getNumber (_turretConfig >> "forceHideGunner") == 0; // return diff --git a/addons/common/functions/fnc_inWater.sqf b/addons/common/functions/fnc_inWater.sqf index 7c8e2eee21..3b323469fc 100644 --- a/addons/common/functions/fnc_inWater.sqf +++ b/addons/common/functions/fnc_inWater.sqf @@ -1,29 +1,19 @@ /* * Author: Glowbal - * Check if unit is underwater + * Check if unit's head is underwater * * Arguments: * 0: Unit * * Return Value: - * if unit is in the water (BOOLEAN) + * If unit's head is underwater * * Public: Yes + * + * Deprecated */ #include "script_component.hpp" -params ["_unit"]; +ACE_DEPRECATED("ace_common_fnc_inWater","3.5.0","ace_common_fnc_isUnderwater"); -private "_return"; -_return = false; - -if (surfaceIsWater getPosASL _unit) then { - private "_pos"; - _pos = _unit modelToWorldVisual (_unit selectionPosition "head"); - - if (_pos select 2 < 0) then { - _return = true; - }; -}; - -_return +_this call FUNC(isUnderwater) diff --git a/addons/common/functions/fnc_isEngineer.sqf b/addons/common/functions/fnc_isEngineer.sqf index 9018149c27..a3c9191c4f 100644 --- a/addons/common/functions/fnc_isEngineer.sqf +++ b/addons/common/functions/fnc_isEngineer.sqf @@ -8,10 +8,17 @@ * Return Value: * is the unit an engineer * + * Example: + * [player] call ace_common_fnc_isEngineer + * * Public: Yes */ #include "script_component.hpp" params ["_unit"]; -_unit getVariable ["ACE_isEngineer", getNumber (configFile >> "CfgVehicles" >> typeOf _unit >> "engineer") == 1] // return +private _isEngineer = _unit getVariable ["ACE_isEngineer", getNumber (configFile >> "CfgVehicles" >> typeOf _unit >> "engineer") == 1]; +//Handle ace_repair modules setting this to a number +if ((typeName _isEngineer) == "SCALAR") then {_isEngineer = _isEngineer > 0}; + +_isEngineer diff --git a/addons/common/functions/fnc_isUnderwater.sqf b/addons/common/functions/fnc_isUnderwater.sqf new file mode 100644 index 0000000000..d2f399b770 --- /dev/null +++ b/addons/common/functions/fnc_isUnderwater.sqf @@ -0,0 +1,29 @@ +/* + * Author: Glowbal + * Check if unit's head is underwater + * + * Arguments: + * 0: Unit + * + * Return Value: + * If unit's head is underwater + * + * Public: Yes + */ +#include "script_component.hpp" + +params ["_unit"]; + +private "_return"; +_return = false; + +if (surfaceIsWater getPosASL _unit) then { + private "_pos"; + _pos = _unit modelToWorldVisual (_unit selectionPosition "head"); + + if (_pos select 2 < 0) then { + _return = true; + }; +}; + +_return diff --git a/addons/common/functions/fnc_loadSettingsLocalizedText.sqf b/addons/common/functions/fnc_loadSettingsLocalizedText.sqf index 1e43359379..7b05902862 100644 --- a/addons/common/functions/fnc_loadSettingsLocalizedText.sqf +++ b/addons/common/functions/fnc_loadSettingsLocalizedText.sqf @@ -35,12 +35,23 @@ _fnc_parseConfigForDisplayNames = { _values set [_forEachIndex, _text]; }; } forEach _values; + + if (!(_values isEqualTo [])) then { + if (_typeOf != "SCALAR") then { + ACE_LOGWARNING_2("Setting [%1] has values[] but is not SCALAR (%2)", _name, _typeOf); + } else { + private _value = missionNamespace getVariable [_name, -1]; + if ((_value < 0) || {_value >= (count _values)}) then { + ACE_LOGWARNING_3("Setting [%1] out of bounds %2 (values[] count is %3)(", _name, _value, count _values); + }; + }; + }; true }; // Iterate through settings { - _x params ["_name"]; + _x params ["_name", "_typeOf"]; if !([configFile >> "ACE_Settings" >> _name] call _fnc_parseConfigForDisplayNames) then { if !([configFile >> "ACE_ServerSettings" >> _name] call _fnc_parseConfigForDisplayNames) then { diff --git a/addons/common/functions/fnc_loadSettingsOnServer.sqf b/addons/common/functions/fnc_loadSettingsOnServer.sqf index ea8257ec23..cdf8b48041 100644 --- a/addons/common/functions/fnc_loadSettingsOnServer.sqf +++ b/addons/common/functions/fnc_loadSettingsOnServer.sqf @@ -51,8 +51,6 @@ _fnc_parseConfigForSettings = { // mission side settings [missionConfigFile >> "ACE_Settings"] call _fnc_parseConfigForSettings; -// Publish all settings data -publicVariable QGVAR(settings); // Publish all setting values { publicVariable (_x select 0); diff --git a/addons/common/functions/fnc_readSettingsFromParamsArray.sqf b/addons/common/functions/fnc_readSettingsFromParamsArray.sqf new file mode 100644 index 0000000000..d1fdb30b29 --- /dev/null +++ b/addons/common/functions/fnc_readSettingsFromParamsArray.sqf @@ -0,0 +1,63 @@ +/* + * Author: PabstMirror + * Read settins from paramsArray that have a ACE_setting = 1. + * Happens before modules but after all other configs (for force priority) + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_common_fnc_readSettingsFromParamsArray + * + * Public: No + */ +#include "script_component.hpp" + +//paramsArray is a normal variable not a command +private _paramsArray = missionnamespace getvariable ["paramsArray", []]; + +TRACE_1("Reading missionConfigFile params",_paramsArray); + +{ + private _config = (missionConfigFile >> "params") select _forEachIndex; + if ((getNumber (_config >> "ACE_setting")) > 0) then { + private _settingName = configName _config; + private _settingValue = _x; + private _title = getText (_config >> "title"); + + TRACE_3("ace_setting",_title,_settingName,_settingValue); + + // Check if the variable is already defined + if (isNil _settingName) exitWith { + ACE_LOGERROR_1("readSettingsFromParamsArray - param [%1] is not an ace_setting", _settingName); + }; + + private _settingData = [_settingName] call FUNC(getSettingData); + _settingData params ["", "_typeName", "", "", "", "", "_isForced"]; + + // Check if it's already forced and quit + if (_isForced) exitWith {ACE_LOGWARNING_1("readSettingsFromParamsArray - param [%1] is already set and forced", _settingName);}; + + // The setting is not forced, so update the value + // Read entry and cast it to the correct type from the existing variable + private _validValue = false; + switch (true) do { + case (_typeName == "SCALAR"): {_validValue = true;}; + case (_typeName == "BOOL"): { + _settingValue = _settingValue > 0; + _validValue = true; + }; + //TODO: Handle ARRAY,COLOR,STRING??? (bool/scalar covers most important settings) + }; + + if (!_validValue) exitWith { + ACE_LOGWARNING_3("readSettingsFromParamsArray - param [%1] type not valid [%2] - expected type [%3]", _settingName,_settingValue,_typeName); + }; + + // Update the variable globaly and Force + [_settingName, _settingValue, true, true] call FUNC(setSetting); + }; +} foreach _paramsArray; diff --git a/addons/common/functions/fnc_selectWeaponMode.sqf b/addons/common/functions/fnc_selectWeaponMode.sqf index f255c63e98..582f6fd4b2 100644 --- a/addons/common/functions/fnc_selectWeaponMode.sqf +++ b/addons/common/functions/fnc_selectWeaponMode.sqf @@ -19,7 +19,7 @@ params ["_unit", "_muzzle", "_mode"]; -local _index = 0; +private _index = 0; while { _index < 100 && {currentMuzzle _unit != _muzzle || {currentWeaponMode _unit != _mode}} diff --git a/addons/common/functions/fnc_setAllGear.sqf b/addons/common/functions/fnc_setAllGear.sqf index e25045a685..2b5a2a9cc7 100644 --- a/addons/common/functions/fnc_setAllGear.sqf +++ b/addons/common/functions/fnc_setAllGear.sqf @@ -148,7 +148,7 @@ if (_backpack != "") then { _unit addBackpack _backpack; if (_clearBackpack) then { - local _backpackObject = unitBackpack _unit; + private _backpackObject = unitBackpack _unit; clearMagazineCargoGlobal _backpackObject; clearWeaponCargoGlobal _backpackObject; diff --git a/addons/common/functions/fnc_setSetting.sqf b/addons/common/functions/fnc_setSetting.sqf index 60b64e31d4..9d3a42326c 100644 --- a/addons/common/functions/fnc_setSetting.sqf +++ b/addons/common/functions/fnc_setSetting.sqf @@ -13,27 +13,39 @@ * Return Value: * None * + * Example: + * ["ace_map_gestures_enabled", true, false, true] call ace_common_fnc_setSetting + * * Public: No */ #include "script_component.hpp" params ["_name", "_value", ["_force", false], ["_broadcastChanges", false]]; -private ["_settingData", "_failed"]; - -_settingData = [_name] call FUNC(getSettingData); +private _settingData = [_name] call FUNC(getSettingData); // Exit if the setting does not exist -if (count _settingData == 0) exitWith {}; +if (_settingData isEqualTo []) exitWith { + ACE_LOGERROR_1("SetSetting [%1] setting does not exist", _name); +}; + +_settingData params ["", "_typeName", "_isClientSetable", "", "", "", "_isForced"]; // Exit if the setting is already forced -if (_settingData select 6) exitWith {}; +if (_isForced) exitWith { + ACE_LOGINFO_1("SetSetting [%1] Trying to set forced setting", _name); +}; + +//This does NOT broadcast changes to GVAR(settings), so clients would not get updated force status +if ((missionNamespace getVariable [QEGVAR(modules,serverModulesRead), false]) && {!(_isForced isEqualTo _force)}) then { + ACE_LOGWARNING_3("SetSetting [%1] attempting to broadcast a change to force (%2 to %3)", _name, _isForced, _force); +}; // If the type is not equal, try to cast it -_failed = false; +private _failed = false; if (typeName _value != _settingData select 1) then { _failed = true; - if (_settingData select 1 == "BOOL" && typeName _value == "SCALAR") then { + if ((_typeName == "BOOL") && {typeName _value == "SCALAR"}) then { // If value is not 0 or 1 consider it invalid and don't set anything if (_value isEqualTo 0) then { _value = false; @@ -44,12 +56,12 @@ if (typeName _value != _settingData select 1) then { _failed = false; }; }; - if (_settingData select 1 == "COLOR" && typeName _value == "ARRAY") then { + if ((_typeName == "COLOR") && {typeName _value == "ARRAY"}) then { _failed = false; }; }; -if (_failed) exitWith {}; +if (_failed) exitWith {ACE_LOGERROR_3("SetSetting [%1] bad data type expected %2 got %3", _name, _typeName, typeName _value);}; // Force it if it was required _settingData set [6, _force]; diff --git a/addons/common/functions/fnc_setVariablePublic.sqf b/addons/common/functions/fnc_setVariablePublic.sqf index 67dbd5fd2f..8dbaeffbd6 100644 --- a/addons/common/functions/fnc_setVariablePublic.sqf +++ b/addons/common/functions/fnc_setVariablePublic.sqf @@ -38,19 +38,16 @@ GVAR(setVariablePublicArray) pushBack [_object, _varName, _syncTime, _idName]; if (isNil QGVAR(setVariablePublicPFH)) exitWith {}; GVAR(setVariablePublicPFH) = [{ - private "_delete"; - _delete = 0; - { _x params ["_object", "_varName", "_syncTime", "_idName"]; if (ACE_diagTime > _syncTime) then { // set value public _object setVariable [_varName, _object getVariable _varName, true]; - GVAR(setVariablePublicArray) deleteAt _forEachIndex - _delete; - GVAR(setVariableNames) deleteAt _forEachIndex - _delete; - _delete = _delete + 1; + GVAR(setVariablePublicArray) deleteAt (GVAR(setVariablePublicArray) find _x); + GVAR(setVariableNames) deleteAt (GVAR(setVariableNames) find _x); }; - } forEach GVAR(setVariablePublicArray); + nil + } count +GVAR(setVariablePublicArray); if (GVAR(setVariablePublicArray) isEqualTo []) then { [GVAR(setVariablePublicPFH)] call CBA_fnc_removePerFrameHandler; diff --git a/addons/common/functions/fnc_showHud.sqf b/addons/common/functions/fnc_showHud.sqf new file mode 100644 index 0000000000..723c2436ed --- /dev/null +++ b/addons/common/functions/fnc_showHud.sqf @@ -0,0 +1,66 @@ +/* + * Author: PabstMirror + * Allows multiple sources to not overwrite showHud command + * Bitwise AND Logic (a single false in a mask will make it false) + * + * Arguments: + * 0: Source ID + * 1: Show Hud Bool Array (8 to set, empty to remove) + * - [hud, info, radar, compass, direction, menu, group, cursors] + * - hud: Boolean - show scripted HUD (same as normal showHUD true/false) + * - info: Boolean - show vehicle + soldier info (hides weapon info from the HUD as well) + * - radar: Boolean - show vehicle radar + * - compass: Boolean - show vehicle compass + * - direction: Boolean - show tank direction indicator (not present in vanilla Arma 3) + * - menu: Boolean - show commanding menu (hides HC related menus) + * - group: Boolean - show group info bar (hides squad leader info bar) + * - cursors: Boolean - show HUD weapon cursors (connected with scripted HUD) + * + * Return Value: + * Resulting ShowHud Array + * + * Example: + * ["hideHud", [false, true, true, true, true, true, true, false]] call ace_common_fnc_showHud; //This is equivalent to the old showHud false + * [] call ace_common_fnc_showHud; //sets `showHud` and returns the result array used + * + * Public: Yes + */ +#include "script_component.hpp" + +if (!hasInterface) exitWith {[-1]}; + +params [["_reason", "", [""]], ["_mask", [], [[]], [0,8]]]; + +if (isArray (missionConfigFile >> "showHUD")) then { + //(showHud = 0;) is fine - the array is the problem + ACE_LOGWARNING("showHUD[] in Description.ext breaks the showHud command"); +}; + +if (_reason != "") then { + _reason = toLower _reason; + if (_mask isEqualTo []) then { + TRACE_2("Setting", _reason, _mask); + [GVAR(showHudHash), _reason] call FUNC(hashRem); + } else { + TRACE_2("Removing", _reason, _mask); + [GVAR(showHudHash), _reason, _mask] call FUNC(hashSet); + }; +}; + +GVAR(showHudHash) params ["_reasons", "_masks"]; +private _resultMask = []; + +for "_index" from 0 to 7 do { + private _set = true; //Default to true + { + if (!(_x select _index)) exitWith { + _set = false; //Any false will make it false + }; + } forEach _masks; + _resultMask pushBack _set; +}; + +TRACE_2("showHud", _resultMask, _reasons); +showHud _resultMask; + +_resultMask diff --git a/addons/common/functions/fnc_timePFH.sqf b/addons/common/functions/fnc_timePFH.sqf index 152eceee3f..e5366d331e 100644 --- a/addons/common/functions/fnc_timePFH.sqf +++ b/addons/common/functions/fnc_timePFH.sqf @@ -14,13 +14,13 @@ BEGIN_COUNTER(timePFH); -local _lastTickTime = ACE_diagTime; -local _lastGameTime = ACE_gameTime; +private _lastTickTime = ACE_diagTime; +private _lastGameTime = ACE_gameTime; ACE_gameTime = time; ACE_diagTime = diag_tickTime; -local _delta = ACE_diagTime - _lastTickTime; +private _delta = ACE_diagTime - _lastTickTime; if (ACE_gameTime <= _lastGameTime) then { TRACE_1("paused",_delta); diff --git a/addons/dagr/XEH_postInit.sqf b/addons/dagr/XEH_postInit.sqf index 39f2a7ea28..883a73d418 100644 --- a/addons/dagr/XEH_postInit.sqf +++ b/addons/dagr/XEH_postInit.sqf @@ -30,4 +30,4 @@ GVAR(vectorConnected) = false; GVAR(noVectorData) = true; GVAR(vectorGrid) = "00000000"; -["RangerfinderData", {_this call FUNC(handleRangeFinderData)}] call EFUNC(common,addEventHandler); +["RangerfinderData", FUNC(handleRangeFinderData)] call EFUNC(common,addEventHandler); diff --git a/addons/dagr/functions/fnc_menuInit.sqf b/addons/dagr/functions/fnc_menuInit.sqf index 739f41df0b..e4fb341537 100644 --- a/addons/dagr/functions/fnc_menuInit.sqf +++ b/addons/dagr/functions/fnc_menuInit.sqf @@ -74,13 +74,13 @@ GVAR(menuRun) = true; GVAR(menuRun) = false; [_this select 1] call CBA_fnc_removePerFrameHandler; }; - + if (GVAR(MENU_B)) then { GVAR(menu) = "main"; GVAR(selection) = 0; GVAR(numSelections) = 5; }; - + if (!GVAR(add) && !GVAR(edit)) then { if (GVAR(DOWN)) then { GVAR(selection) = (GVAR(numSelections) + GVAR(selection) + 1); @@ -90,7 +90,7 @@ GVAR(menuRun) = true; }; GVAR(selection) = if (GVAR(numSelections) > 0) then { GVAR(selection) % GVAR(numSelections) } else { 0 }; }; - + if (GVAR(LEFT)) then { GVAR(pointer) = (8 + GVAR(pointer) - 1); }; @@ -98,7 +98,7 @@ GVAR(menuRun) = true; GVAR(pointer) = (8 + GVAR(pointer) + 1); }; GVAR(pointer) = GVAR(pointer) % 8; - + (__dsp displayCtrl __PSelection1) ctrlSetText ""; (__dsp displayCtrl __PSelection2) ctrlSetText ""; (__dsp displayCtrl __PSelection3) ctrlSetText ""; @@ -113,7 +113,7 @@ GVAR(menuRun) = true; (__dsp displayCtrl __Selection2) ctrlSetText ""; (__dsp displayCtrl __Selection3) ctrlSetText ""; (__dsp displayCtrl __Selection4) ctrlSetText ""; - + (__dsp displayCtrl __F1) ctrlSetText ""; (__dsp displayCtrl __F2) ctrlSetText ""; (__dsp displayCtrl __F3) ctrlSetText ""; @@ -124,7 +124,7 @@ GVAR(menuRun) = true; (__dsp displayCtrl __Option2) ctrlSetText ""; (__dsp displayCtrl __Option3) ctrlSetText ""; (__dsp displayCtrl __Option4) ctrlSetText ""; - + switch (GVAR(menu)) do { case "main": { if (GVAR(SEL)) then { @@ -500,7 +500,7 @@ GVAR(menuRun) = true; case 6: { GVAR(digit6) = (10 + GVAR(digit6) - 1) % 10 }; case 7: { GVAR(digit7) = (10 + GVAR(digit7) - 1) % 10 }; case 8: { GVAR(digit8) = (10 + GVAR(digit8) - 1) % 10 }; - }; + }; }; }; }; @@ -590,7 +590,7 @@ GVAR(menuRun) = true; }; }; }; - + if (!GVAR(busy)) then { GVAR(F3) = false; GVAR(F2) = false; diff --git a/addons/dagr/functions/fnc_outputData.sqf b/addons/dagr/functions/fnc_outputData.sqf index 9bcf244fbc..63350c71a3 100644 --- a/addons/dagr/functions/fnc_outputData.sqf +++ b/addons/dagr/functions/fnc_outputData.sqf @@ -31,18 +31,19 @@ if (GVAR(outputPFH) != -1) exitWith {}; GVAR(outputPFH) = [{ private["_dagrElevation", "_dagrGrid", "_dagrHeading", "_dagrSpeed", "_dagrTime", "_elevation", "_gridArray", "_speed"]; - + // Abort Condition if !(GVAR(run) && [ACE_player, "ACE_DAGR"] call EFUNC(common,hasItem)) exitWith { GVAR(outputPFH) = -1; 135471 cutText ["", "PLAIN"]; [_this select 1] call CBA_fnc_removePerFrameHandler; }; - + // GRID _gridArray = [(getPos ACE_player), false] call EFUNC(common,getMapGridFromPos); - _dagrGrid = format ["%1 %2", ((_gridArray select 0) select [0,4]), ((_gridArray select 1) select [0,4])]; - + _gridArray params ["_gridArrayX","_gridArrayY"]; + _dagrGrid = format ["%1 %2", ((_gridArrayX) select [0,4]), ((_gridArrayY) select [0,4])]; + // SPEED _speed = speed (vehicle ACE_player); _speed = floor (_speed * 10) / 10; @@ -68,7 +69,7 @@ GVAR(outputPFH) = [{ __gridControl ctrlSetText format ["%1", _dagrGrid]; __speedControl ctrlSetText format ["%1", _dagrSpeed]; __elevationControl ctrlSetText format ["%1", _dagrElevation]; - __headingControl ctrlSetText (if (!GVAR(useDegrees)) then { format ["%1", _dagrHeading] } else { format ["%1 ", _dagrHeading] }); + __headingControl ctrlSetText (if (!GVAR(useDegrees)) then { format ["%1", _dagrHeading] } else { format ["%1 �", _dagrHeading] }); __timeControl ctrlSetText format ["%1", _dagrTime]; - + }, GVAR(updateInterval), []] call CBA_fnc_addPerFrameHandler; diff --git a/addons/dagr/functions/fnc_outputVector.sqf b/addons/dagr/functions/fnc_outputVector.sqf index ad9068344f..7f36facae8 100644 --- a/addons/dagr/functions/fnc_outputVector.sqf +++ b/addons/dagr/functions/fnc_outputVector.sqf @@ -1,4 +1,4 @@ -/* +/* * Author: Rosuto * DAGR vector output loop * @@ -14,7 +14,7 @@ */ #include "script_component.hpp" -private ["_pos", "_xGrid", "_yGrid", "_dagrGrid", "_bearing", "_dagrDist", "_dagrElevation", "_dagrTime", "_elevation", "_xCoord", "_yCoord"]; +private ["_xGrid", "_yGrid", "_dagrGrid", "_bearing", "_dagrDist", "_dagrElevation", "_dagrTime", "_elevation", "_xCoord", "_yCoord"]; 135471 cutRsc ["DAGR_DISPLAY", "plain down"]; @@ -30,15 +30,14 @@ private ["_pos", "_xGrid", "_yGrid", "_dagrGrid", "_bearing", "_dagrDist", "_dag __background ctrlSetText QUOTE(PATHTOF(UI\dagr_vector.paa)); if (GVAR(noVectorData)) exitwith {}; - -_pos = [GVAR(LAZPOS) select 0, GVAR(LAZPOS) select 1]; +GVAR(LAZPOS) params ["_lazPosX", "_lazPosY", "_lazPosZ"]; // Incase grids go neg due to 99-00 boundry -if (_pos select 0 < 0) then {_pos set [0, (_pos select 0) + 99999];}; -if (_pos select 1 < 0) then {_pos set [1, (_pos select 1) + 99999];}; - +if (_lazPosX < 0) then { _lazPosX = _lazPosX + 99999;}; +if (_lazPosY < 0) then {_lazPosY = _lazPosY + 99999;}; + // Find laser position -_xGrid = toArray Str(round(_pos select 0)); +_xGrid = toArray Str(round _lazPosX); while {count _xGrid < 5} do { _xGrid = [48] + _xGrid; @@ -47,7 +46,7 @@ _xGrid resize 4; _xGrid = toString _xGrid; _xGrid = parseNumber _xGrid; -_yGrid = toArray Str(round(_pos select 1)); +_yGrid = toArray Str(round _lazPosY); while {count _yGrid < 5} do { _yGrid = [48] + _yGrid; }; @@ -72,7 +71,7 @@ _yCoord = switch true do { _dagrGrid = _xCoord + " " + _yCoord; // Find target elevation -_elevation = floor ((GVAR(LAZPOS) select 2) + EGVAR(common,mapAltitude)); +_elevation = floor ((_lazPosZ) + EGVAR(common,mapAltitude)); _dagrElevation = str _elevation + "m"; // Time @@ -94,5 +93,5 @@ GVAR(vectorGrid) = _dagrGrid; __gridControl ctrlSetText format ["%1", _dagrGrid]; __speedControl ctrlSetText format ["%1", _dagrDist]; __elevationControl ctrlSetText format ["%1", _dagrElevation]; -__headingControl ctrlSetText (if (!GVAR(useDegrees)) then { format ["%1", _bearing] } else { format ["%1", _bearing] }); +__headingControl ctrlSetText (if (!GVAR(useDegrees)) then { format ["%1", _bearing] } else { format ["%1°", _bearing] }); __timeControl ctrlSetText format ["%1", _dagrTime]; diff --git a/addons/dagr/functions/fnc_outputWP.sqf b/addons/dagr/functions/fnc_outputWP.sqf index 71c3e7c1a7..204a5ef556 100644 --- a/addons/dagr/functions/fnc_outputWP.sqf +++ b/addons/dagr/functions/fnc_outputWP.sqf @@ -1,4 +1,4 @@ -/* +/* * Author: Rosuto * DAGR waypoint output loop * @@ -31,22 +31,23 @@ if (GVAR(outputPFH) != -1) exitWith {}; GVAR(outputPFH) = [{ private["_MYpos", "_WPpos", "_bearing", "_dagrDistance", "_dagrGrid", "_dagrHeading", "_distance", "_gridArray"]; - + // Abort Condition if !(GVAR(run) && [ACE_player, "ACE_DAGR"] call EFUNC(common,hasItem)) exitWith { GVAR(outputPFH) = -1; 135471 cutText ["", "PLAIN"]; [_this select 1] call CBA_fnc_removePerFrameHandler; }; - + // GRID _gridArray = [(getPos ACE_player), false] call EFUNC(common,getMapGridFromPos); - _dagrGrid = format ["%1 %2", ((_gridArray select 0) select [0,4]), ((_gridArray select 1) select [0,4])]; + _gridArray params ["_gridArrayX","_gridArrayY"]; + _dagrGrid = format ["%1 %2", (_gridArrayX select [0,4]), (_gridArrayY select [0,4])]; // WP Grid _xGrid2 = floor (DAGR_WP_INFO / 10000); _yGrid2 = DAGR_WP_INFO - _xGrid2 * 10000; - + _xCoord2 = switch true do { case (_xGrid2 >= 1000): { "" + Str(_xGrid2) }; case (_xGrid2 >= 100): { "0" + Str(_xGrid2) }; @@ -60,7 +61,7 @@ GVAR(outputPFH) = [{ case (_yGrid2 >= 10): { "00" + Str(_yGrid2) }; default { "000" + Str(_yGrid2) }; }; - + _dagrGrid2 = _xCoord2 + " " + _yCoord2; // Distance @@ -69,7 +70,7 @@ GVAR(outputPFH) = [{ _distance = _MYpos distance _WPpos; _distance = floor (_distance * 10) / 10; _dagrDistance = str _distance + "m"; - + // Heading _dagrHeading = floor (if (GVAR(useDegrees)) then { direction (vehicle ACE_player) @@ -79,12 +80,12 @@ GVAR(outputPFH) = [{ // WP Heading _bearing = floor ((_WPpos vectorDiff _MYpos) call CBA_fnc_vectDir); - + // Output __gridControl ctrlSetText format ["%1", _dagrGrid]; __speedControl ctrlSetText format ["%1", _bearing]; __elevationControl ctrlSetText format ["%1", _dagrGrid2]; - __headingControl ctrlSetText (if (!GVAR(useDegrees)) then { format ["%1", _dagrHeading] } else { format ["%1", _dagrHeading] }); + __headingControl ctrlSetText (if (!GVAR(useDegrees)) then { format ["%1", _dagrHeading] } else { format ["%1°", _dagrHeading] }); __timeControl ctrlSetText format ["%1", _dagrDistance]; - + }, GVAR(updateInterval), []] call CBA_fnc_addPerFrameHandler; diff --git a/addons/dagr/functions/fnc_toggleOverlay.sqf b/addons/dagr/functions/fnc_toggleOverlay.sqf index 1fcb87d0ff..d48a83ae51 100644 --- a/addons/dagr/functions/fnc_toggleOverlay.sqf +++ b/addons/dagr/functions/fnc_toggleOverlay.sqf @@ -23,11 +23,12 @@ if (GVAR(run)) then { }; GVAR(hidden) = true; [{ - EXPLODE_1_PVT(_this select 0,_vehicle); + params ["_args", "_idPFH"]; + _args params ["_vehicle"]; if (!GVAR(run) || (!alive ACE_player) || (vehicle ACE_player != _vehicle)) exitWith { GVAR(run) = false; 135471 cutText ["", "PLAIN"]; - [_this select 1] call CBA_fnc_removePerFrameHandler; + [_idPFH] call CBA_fnc_removePerFrameHandler; }; if (cameraView == "GUNNER") then { if (!GVAR(hidden)) then { diff --git a/addons/dragging/stringtable.xml b/addons/dragging/stringtable.xml index 417493fc75..be80801e57 100644 --- a/addons/dragging/stringtable.xml +++ b/addons/dragging/stringtable.xml @@ -54,6 +54,7 @@ Heben/Senken Wyżej/Niżej Levantar/Abaixar + Поднять/Опустить \ No newline at end of file diff --git a/addons/explosives/CfgModule.hpp b/addons/explosives/CfgModule.hpp index a27efae704..b651903f59 100644 --- a/addons/explosives/CfgModule.hpp +++ b/addons/explosives/CfgModule.hpp @@ -6,6 +6,7 @@ class ACE_ModuleExplosive: ACE_Module { function = QUOTE(FUNC(module)); scope = 2; isGlobal = 1; + isSingular = 1; icon = PATHTOF(UI\Icon_Module_Explosives_ca.paa); class Arguments { class RequireSpecialist { diff --git a/addons/fcs/functions/fnc_keyUp.sqf b/addons/fcs/functions/fnc_keyUp.sqf index 1b2443b44a..37390c0b47 100644 --- a/addons/fcs/functions/fnc_keyUp.sqf +++ b/addons/fcs/functions/fnc_keyUp.sqf @@ -210,3 +210,11 @@ if(_playSound) then { if(_showHint) then { [format ["%1: %2", localize LSTRING(ZeroedTo), _distance]] call EFUNC(common,displayTextStructured); }; + +//Update the hud's distance display to the new value or "----" if out of range +//(10m fudge because of EFUNC(common,getTargetDistance)) +if ((_distance + 10) >= (getNumber (_turretConfig >> QGVAR(MaxDistance)))) then { + ((uiNamespace getVariable ["ACE_dlgRangefinder", displayNull]) displayCtrl 1713151) ctrlSetText "----"; +} else { + ((uiNamespace getVariable ["ACE_dlgRangefinder", displayNull]) displayCtrl 1713151) ctrlSetText ([_distance, 4, 0] call CBA_fnc_formatNumber); +}; diff --git a/addons/fcs/functions/script_component.hpp b/addons/fcs/functions/script_component.hpp index 8ada0f7a71..179c66c15e 100644 --- a/addons/fcs/functions/script_component.hpp +++ b/addons/fcs/functions/script_component.hpp @@ -1,12 +1 @@ -#define COMPONENT fcs -#include "\z\ace\addons\main\script_mod.hpp" - -#ifdef DEBUG_ENABLED_FCS - #define DEBUG_MODE_FULL -#endif - -#ifdef DEBUG_SETTINGS_FCS - #define DEBUG_SETTINGS DEBUG_SETTINGS_FCS -#endif - -#include "\z\ace\addons\main\script_macros.hpp" +#include "\z\ace\addons\fcs\script_component.hpp" \ No newline at end of file diff --git a/addons/finger/CfgVehicles.hpp b/addons/finger/CfgVehicles.hpp index 99d9713f00..e78ef50123 100644 --- a/addons/finger/CfgVehicles.hpp +++ b/addons/finger/CfgVehicles.hpp @@ -7,6 +7,7 @@ class CfgVehicles { icon = QUOTE(PATHTOF(UI\Icon_Module_finger_ca.paa)); function = QFUNC(moduleSettings); isGlobal = 0; + isSingular = 1; author = ECSTRING(common,ACETeam); class Arguments { class enabled { diff --git a/addons/frag/CfgAmmoReflections.hpp b/addons/frag/CfgAmmoReflections.hpp index f59d67f89a..0331dd41dd 100644 --- a/addons/frag/CfgAmmoReflections.hpp +++ b/addons/frag/CfgAmmoReflections.hpp @@ -1,6 +1,65 @@ //CfgAmmoReflections.hpp -#define ACE_EXPLOSION_REFLECTION(range, hit) class ace_explosion_reflection_##range##_##hit : ace_explosion_reflection_base { indirectHitRange = range; indirectHit = hit; dangerRadiusHit = range*3; suppressionRadiusHit = range*2; }; +#define ACE_EXPLOSION_REFLECTION(range, hit)\ +class ace_explosion_reflection_##range##_##hit : ace_explosion_reflection_base {\ + indirectHitRange = range;\ + indirectHit = hit;\ + dangerRadiusHit = range*3;\ + suppressionRadiusHit = range*2;\ +} + +#define ACE_EXPLOSION_RANGE(range)\ + ACE_EXPLOSION_REFLECTION(range,10);\ + ACE_EXPLOSION_REFLECTION(range,20);\ + ACE_EXPLOSION_REFLECTION(range,30);\ + ACE_EXPLOSION_REFLECTION(range,40);\ + ACE_EXPLOSION_REFLECTION(range,50);\ + ACE_EXPLOSION_REFLECTION(range,60);\ + ACE_EXPLOSION_REFLECTION(range,70);\ + ACE_EXPLOSION_REFLECTION(range,80);\ + ACE_EXPLOSION_REFLECTION(range,90);\ + ACE_EXPLOSION_REFLECTION(range,100);\ + ACE_EXPLOSION_REFLECTION(range,110);\ + ACE_EXPLOSION_REFLECTION(range,120);\ + ACE_EXPLOSION_REFLECTION(range,130);\ + ACE_EXPLOSION_REFLECTION(range,140);\ + ACE_EXPLOSION_REFLECTION(range,150);\ + ACE_EXPLOSION_REFLECTION(range,160);\ + ACE_EXPLOSION_REFLECTION(range,170);\ + ACE_EXPLOSION_REFLECTION(range,180);\ + ACE_EXPLOSION_REFLECTION(range,190);\ + ACE_EXPLOSION_REFLECTION(range,200);\ + ACE_EXPLOSION_REFLECTION(range,210);\ + ACE_EXPLOSION_REFLECTION(range,220);\ + ACE_EXPLOSION_REFLECTION(range,230);\ + ACE_EXPLOSION_REFLECTION(range,240);\ + ACE_EXPLOSION_REFLECTION(range,250);\ + ACE_EXPLOSION_REFLECTION(range,260);\ + ACE_EXPLOSION_REFLECTION(range,270);\ + ACE_EXPLOSION_REFLECTION(range,280);\ + ACE_EXPLOSION_REFLECTION(range,290);\ + ACE_EXPLOSION_REFLECTION(range,300);\ + ACE_EXPLOSION_REFLECTION(range,310);\ + ACE_EXPLOSION_REFLECTION(range,320);\ + ACE_EXPLOSION_REFLECTION(range,330);\ + ACE_EXPLOSION_REFLECTION(range,340);\ + ACE_EXPLOSION_REFLECTION(range,350);\ + ACE_EXPLOSION_REFLECTION(range,360);\ + ACE_EXPLOSION_REFLECTION(range,370);\ + ACE_EXPLOSION_REFLECTION(range,380);\ + ACE_EXPLOSION_REFLECTION(range,390);\ + ACE_EXPLOSION_REFLECTION(range,400);\ + ACE_EXPLOSION_REFLECTION(range,410);\ + ACE_EXPLOSION_REFLECTION(range,420);\ + ACE_EXPLOSION_REFLECTION(range,430);\ + ACE_EXPLOSION_REFLECTION(range,440);\ + ACE_EXPLOSION_REFLECTION(range,450);\ + ACE_EXPLOSION_REFLECTION(range,460);\ + ACE_EXPLOSION_REFLECTION(range,470);\ + ACE_EXPLOSION_REFLECTION(range,480);\ + ACE_EXPLOSION_REFLECTION(range,490);\ + ACE_EXPLOSION_REFLECTION(range,500) + class ace_explosion_reflection_base : Sh_120mm_HE { CraterWaterEffects = ""; CraterEffects = ""; @@ -19,2504 +78,53 @@ class ace_explosion_reflection_base : Sh_120mm_HE { craterShape = "\A3\weapons_f\empty.p3d"; }; -ACE_EXPLOSION_REFLECTION(2,10); -ACE_EXPLOSION_REFLECTION(2,20); -ACE_EXPLOSION_REFLECTION(2,30); -ACE_EXPLOSION_REFLECTION(2,40); -ACE_EXPLOSION_REFLECTION(2,50); -ACE_EXPLOSION_REFLECTION(2,60); -ACE_EXPLOSION_REFLECTION(2,70); -ACE_EXPLOSION_REFLECTION(2,80); -ACE_EXPLOSION_REFLECTION(2,90); -ACE_EXPLOSION_REFLECTION(2,100); -ACE_EXPLOSION_REFLECTION(2,110); -ACE_EXPLOSION_REFLECTION(2,120); -ACE_EXPLOSION_REFLECTION(2,130); -ACE_EXPLOSION_REFLECTION(2,140); -ACE_EXPLOSION_REFLECTION(2,150); -ACE_EXPLOSION_REFLECTION(2,160); -ACE_EXPLOSION_REFLECTION(2,170); -ACE_EXPLOSION_REFLECTION(2,180); -ACE_EXPLOSION_REFLECTION(2,190); -ACE_EXPLOSION_REFLECTION(2,200); -ACE_EXPLOSION_REFLECTION(2,210); -ACE_EXPLOSION_REFLECTION(2,220); -ACE_EXPLOSION_REFLECTION(2,230); -ACE_EXPLOSION_REFLECTION(2,240); -ACE_EXPLOSION_REFLECTION(2,250); -ACE_EXPLOSION_REFLECTION(2,260); -ACE_EXPLOSION_REFLECTION(2,270); -ACE_EXPLOSION_REFLECTION(2,280); -ACE_EXPLOSION_REFLECTION(2,290); -ACE_EXPLOSION_REFLECTION(2,300); -ACE_EXPLOSION_REFLECTION(2,310); -ACE_EXPLOSION_REFLECTION(2,320); -ACE_EXPLOSION_REFLECTION(2,330); -ACE_EXPLOSION_REFLECTION(2,340); -ACE_EXPLOSION_REFLECTION(2,350); -ACE_EXPLOSION_REFLECTION(2,360); -ACE_EXPLOSION_REFLECTION(2,370); -ACE_EXPLOSION_REFLECTION(2,380); -ACE_EXPLOSION_REFLECTION(2,390); -ACE_EXPLOSION_REFLECTION(2,400); -ACE_EXPLOSION_REFLECTION(2,410); -ACE_EXPLOSION_REFLECTION(2,420); -ACE_EXPLOSION_REFLECTION(2,430); -ACE_EXPLOSION_REFLECTION(2,440); -ACE_EXPLOSION_REFLECTION(2,450); -ACE_EXPLOSION_REFLECTION(2,460); -ACE_EXPLOSION_REFLECTION(2,470); -ACE_EXPLOSION_REFLECTION(2,480); -ACE_EXPLOSION_REFLECTION(2,490); -ACE_EXPLOSION_REFLECTION(2,500); -ACE_EXPLOSION_REFLECTION(4,10); -ACE_EXPLOSION_REFLECTION(4,20); -ACE_EXPLOSION_REFLECTION(4,30); -ACE_EXPLOSION_REFLECTION(4,40); -ACE_EXPLOSION_REFLECTION(4,50); -ACE_EXPLOSION_REFLECTION(4,60); -ACE_EXPLOSION_REFLECTION(4,70); -ACE_EXPLOSION_REFLECTION(4,80); -ACE_EXPLOSION_REFLECTION(4,90); -ACE_EXPLOSION_REFLECTION(4,100); -ACE_EXPLOSION_REFLECTION(4,110); -ACE_EXPLOSION_REFLECTION(4,120); -ACE_EXPLOSION_REFLECTION(4,130); -ACE_EXPLOSION_REFLECTION(4,140); -ACE_EXPLOSION_REFLECTION(4,150); -ACE_EXPLOSION_REFLECTION(4,160); -ACE_EXPLOSION_REFLECTION(4,170); -ACE_EXPLOSION_REFLECTION(4,180); -ACE_EXPLOSION_REFLECTION(4,190); -ACE_EXPLOSION_REFLECTION(4,200); -ACE_EXPLOSION_REFLECTION(4,210); -ACE_EXPLOSION_REFLECTION(4,220); -ACE_EXPLOSION_REFLECTION(4,230); -ACE_EXPLOSION_REFLECTION(4,240); -ACE_EXPLOSION_REFLECTION(4,250); -ACE_EXPLOSION_REFLECTION(4,260); -ACE_EXPLOSION_REFLECTION(4,270); -ACE_EXPLOSION_REFLECTION(4,280); -ACE_EXPLOSION_REFLECTION(4,290); -ACE_EXPLOSION_REFLECTION(4,300); -ACE_EXPLOSION_REFLECTION(4,310); -ACE_EXPLOSION_REFLECTION(4,320); -ACE_EXPLOSION_REFLECTION(4,330); -ACE_EXPLOSION_REFLECTION(4,340); -ACE_EXPLOSION_REFLECTION(4,350); -ACE_EXPLOSION_REFLECTION(4,360); -ACE_EXPLOSION_REFLECTION(4,370); -ACE_EXPLOSION_REFLECTION(4,380); -ACE_EXPLOSION_REFLECTION(4,390); -ACE_EXPLOSION_REFLECTION(4,400); -ACE_EXPLOSION_REFLECTION(4,410); -ACE_EXPLOSION_REFLECTION(4,420); -ACE_EXPLOSION_REFLECTION(4,430); -ACE_EXPLOSION_REFLECTION(4,440); -ACE_EXPLOSION_REFLECTION(4,450); -ACE_EXPLOSION_REFLECTION(4,460); -ACE_EXPLOSION_REFLECTION(4,470); -ACE_EXPLOSION_REFLECTION(4,480); -ACE_EXPLOSION_REFLECTION(4,490); -ACE_EXPLOSION_REFLECTION(4,500); -ACE_EXPLOSION_REFLECTION(6,10); -ACE_EXPLOSION_REFLECTION(6,20); -ACE_EXPLOSION_REFLECTION(6,30); -ACE_EXPLOSION_REFLECTION(6,40); -ACE_EXPLOSION_REFLECTION(6,50); -ACE_EXPLOSION_REFLECTION(6,60); -ACE_EXPLOSION_REFLECTION(6,70); -ACE_EXPLOSION_REFLECTION(6,80); -ACE_EXPLOSION_REFLECTION(6,90); -ACE_EXPLOSION_REFLECTION(6,100); -ACE_EXPLOSION_REFLECTION(6,110); -ACE_EXPLOSION_REFLECTION(6,120); -ACE_EXPLOSION_REFLECTION(6,130); -ACE_EXPLOSION_REFLECTION(6,140); -ACE_EXPLOSION_REFLECTION(6,150); -ACE_EXPLOSION_REFLECTION(6,160); -ACE_EXPLOSION_REFLECTION(6,170); -ACE_EXPLOSION_REFLECTION(6,180); -ACE_EXPLOSION_REFLECTION(6,190); -ACE_EXPLOSION_REFLECTION(6,200); -ACE_EXPLOSION_REFLECTION(6,210); -ACE_EXPLOSION_REFLECTION(6,220); -ACE_EXPLOSION_REFLECTION(6,230); -ACE_EXPLOSION_REFLECTION(6,240); -ACE_EXPLOSION_REFLECTION(6,250); -ACE_EXPLOSION_REFLECTION(6,260); -ACE_EXPLOSION_REFLECTION(6,270); -ACE_EXPLOSION_REFLECTION(6,280); -ACE_EXPLOSION_REFLECTION(6,290); -ACE_EXPLOSION_REFLECTION(6,300); -ACE_EXPLOSION_REFLECTION(6,310); -ACE_EXPLOSION_REFLECTION(6,320); -ACE_EXPLOSION_REFLECTION(6,330); -ACE_EXPLOSION_REFLECTION(6,340); -ACE_EXPLOSION_REFLECTION(6,350); -ACE_EXPLOSION_REFLECTION(6,360); -ACE_EXPLOSION_REFLECTION(6,370); -ACE_EXPLOSION_REFLECTION(6,380); -ACE_EXPLOSION_REFLECTION(6,390); -ACE_EXPLOSION_REFLECTION(6,400); -ACE_EXPLOSION_REFLECTION(6,410); -ACE_EXPLOSION_REFLECTION(6,420); -ACE_EXPLOSION_REFLECTION(6,430); -ACE_EXPLOSION_REFLECTION(6,440); -ACE_EXPLOSION_REFLECTION(6,450); -ACE_EXPLOSION_REFLECTION(6,460); -ACE_EXPLOSION_REFLECTION(6,470); -ACE_EXPLOSION_REFLECTION(6,480); -ACE_EXPLOSION_REFLECTION(6,490); -ACE_EXPLOSION_REFLECTION(6,500); -ACE_EXPLOSION_REFLECTION(8,10); -ACE_EXPLOSION_REFLECTION(8,20); -ACE_EXPLOSION_REFLECTION(8,30); -ACE_EXPLOSION_REFLECTION(8,40); -ACE_EXPLOSION_REFLECTION(8,50); -ACE_EXPLOSION_REFLECTION(8,60); -ACE_EXPLOSION_REFLECTION(8,70); -ACE_EXPLOSION_REFLECTION(8,80); -ACE_EXPLOSION_REFLECTION(8,90); -ACE_EXPLOSION_REFLECTION(8,100); -ACE_EXPLOSION_REFLECTION(8,110); -ACE_EXPLOSION_REFLECTION(8,120); -ACE_EXPLOSION_REFLECTION(8,130); -ACE_EXPLOSION_REFLECTION(8,140); -ACE_EXPLOSION_REFLECTION(8,150); -ACE_EXPLOSION_REFLECTION(8,160); -ACE_EXPLOSION_REFLECTION(8,170); -ACE_EXPLOSION_REFLECTION(8,180); -ACE_EXPLOSION_REFLECTION(8,190); -ACE_EXPLOSION_REFLECTION(8,200); -ACE_EXPLOSION_REFLECTION(8,210); -ACE_EXPLOSION_REFLECTION(8,220); -ACE_EXPLOSION_REFLECTION(8,230); -ACE_EXPLOSION_REFLECTION(8,240); -ACE_EXPLOSION_REFLECTION(8,250); -ACE_EXPLOSION_REFLECTION(8,260); -ACE_EXPLOSION_REFLECTION(8,270); -ACE_EXPLOSION_REFLECTION(8,280); -ACE_EXPLOSION_REFLECTION(8,290); -ACE_EXPLOSION_REFLECTION(8,300); -ACE_EXPLOSION_REFLECTION(8,310); -ACE_EXPLOSION_REFLECTION(8,320); -ACE_EXPLOSION_REFLECTION(8,330); -ACE_EXPLOSION_REFLECTION(8,340); -ACE_EXPLOSION_REFLECTION(8,350); -ACE_EXPLOSION_REFLECTION(8,360); -ACE_EXPLOSION_REFLECTION(8,370); -ACE_EXPLOSION_REFLECTION(8,380); -ACE_EXPLOSION_REFLECTION(8,390); -ACE_EXPLOSION_REFLECTION(8,400); -ACE_EXPLOSION_REFLECTION(8,410); -ACE_EXPLOSION_REFLECTION(8,420); -ACE_EXPLOSION_REFLECTION(8,430); -ACE_EXPLOSION_REFLECTION(8,440); -ACE_EXPLOSION_REFLECTION(8,450); -ACE_EXPLOSION_REFLECTION(8,460); -ACE_EXPLOSION_REFLECTION(8,470); -ACE_EXPLOSION_REFLECTION(8,480); -ACE_EXPLOSION_REFLECTION(8,490); -ACE_EXPLOSION_REFLECTION(8,500); -ACE_EXPLOSION_REFLECTION(10,10); -ACE_EXPLOSION_REFLECTION(10,20); -ACE_EXPLOSION_REFLECTION(10,30); -ACE_EXPLOSION_REFLECTION(10,40); -ACE_EXPLOSION_REFLECTION(10,50); -ACE_EXPLOSION_REFLECTION(10,60); -ACE_EXPLOSION_REFLECTION(10,70); -ACE_EXPLOSION_REFLECTION(10,80); -ACE_EXPLOSION_REFLECTION(10,90); -ACE_EXPLOSION_REFLECTION(10,100); -ACE_EXPLOSION_REFLECTION(10,110); -ACE_EXPLOSION_REFLECTION(10,120); -ACE_EXPLOSION_REFLECTION(10,130); -ACE_EXPLOSION_REFLECTION(10,140); -ACE_EXPLOSION_REFLECTION(10,150); -ACE_EXPLOSION_REFLECTION(10,160); -ACE_EXPLOSION_REFLECTION(10,170); -ACE_EXPLOSION_REFLECTION(10,180); -ACE_EXPLOSION_REFLECTION(10,190); -ACE_EXPLOSION_REFLECTION(10,200); -ACE_EXPLOSION_REFLECTION(10,210); -ACE_EXPLOSION_REFLECTION(10,220); -ACE_EXPLOSION_REFLECTION(10,230); -ACE_EXPLOSION_REFLECTION(10,240); -ACE_EXPLOSION_REFLECTION(10,250); -ACE_EXPLOSION_REFLECTION(10,260); -ACE_EXPLOSION_REFLECTION(10,270); -ACE_EXPLOSION_REFLECTION(10,280); -ACE_EXPLOSION_REFLECTION(10,290); -ACE_EXPLOSION_REFLECTION(10,300); -ACE_EXPLOSION_REFLECTION(10,310); -ACE_EXPLOSION_REFLECTION(10,320); -ACE_EXPLOSION_REFLECTION(10,330); -ACE_EXPLOSION_REFLECTION(10,340); -ACE_EXPLOSION_REFLECTION(10,350); -ACE_EXPLOSION_REFLECTION(10,360); -ACE_EXPLOSION_REFLECTION(10,370); -ACE_EXPLOSION_REFLECTION(10,380); -ACE_EXPLOSION_REFLECTION(10,390); -ACE_EXPLOSION_REFLECTION(10,400); -ACE_EXPLOSION_REFLECTION(10,410); -ACE_EXPLOSION_REFLECTION(10,420); -ACE_EXPLOSION_REFLECTION(10,430); -ACE_EXPLOSION_REFLECTION(10,440); -ACE_EXPLOSION_REFLECTION(10,450); -ACE_EXPLOSION_REFLECTION(10,460); -ACE_EXPLOSION_REFLECTION(10,470); -ACE_EXPLOSION_REFLECTION(10,480); -ACE_EXPLOSION_REFLECTION(10,490); -ACE_EXPLOSION_REFLECTION(10,500); -ACE_EXPLOSION_REFLECTION(12,10); -ACE_EXPLOSION_REFLECTION(12,20); -ACE_EXPLOSION_REFLECTION(12,30); -ACE_EXPLOSION_REFLECTION(12,40); -ACE_EXPLOSION_REFLECTION(12,50); -ACE_EXPLOSION_REFLECTION(12,60); -ACE_EXPLOSION_REFLECTION(12,70); -ACE_EXPLOSION_REFLECTION(12,80); -ACE_EXPLOSION_REFLECTION(12,90); -ACE_EXPLOSION_REFLECTION(12,100); -ACE_EXPLOSION_REFLECTION(12,110); -ACE_EXPLOSION_REFLECTION(12,120); -ACE_EXPLOSION_REFLECTION(12,130); -ACE_EXPLOSION_REFLECTION(12,140); -ACE_EXPLOSION_REFLECTION(12,150); -ACE_EXPLOSION_REFLECTION(12,160); -ACE_EXPLOSION_REFLECTION(12,170); -ACE_EXPLOSION_REFLECTION(12,180); -ACE_EXPLOSION_REFLECTION(12,190); -ACE_EXPLOSION_REFLECTION(12,200); -ACE_EXPLOSION_REFLECTION(12,210); -ACE_EXPLOSION_REFLECTION(12,220); -ACE_EXPLOSION_REFLECTION(12,230); -ACE_EXPLOSION_REFLECTION(12,240); -ACE_EXPLOSION_REFLECTION(12,250); -ACE_EXPLOSION_REFLECTION(12,260); -ACE_EXPLOSION_REFLECTION(12,270); -ACE_EXPLOSION_REFLECTION(12,280); -ACE_EXPLOSION_REFLECTION(12,290); -ACE_EXPLOSION_REFLECTION(12,300); -ACE_EXPLOSION_REFLECTION(12,310); -ACE_EXPLOSION_REFLECTION(12,320); -ACE_EXPLOSION_REFLECTION(12,330); -ACE_EXPLOSION_REFLECTION(12,340); -ACE_EXPLOSION_REFLECTION(12,350); -ACE_EXPLOSION_REFLECTION(12,360); -ACE_EXPLOSION_REFLECTION(12,370); -ACE_EXPLOSION_REFLECTION(12,380); -ACE_EXPLOSION_REFLECTION(12,390); -ACE_EXPLOSION_REFLECTION(12,400); -ACE_EXPLOSION_REFLECTION(12,410); -ACE_EXPLOSION_REFLECTION(12,420); -ACE_EXPLOSION_REFLECTION(12,430); -ACE_EXPLOSION_REFLECTION(12,440); -ACE_EXPLOSION_REFLECTION(12,450); -ACE_EXPLOSION_REFLECTION(12,460); -ACE_EXPLOSION_REFLECTION(12,470); -ACE_EXPLOSION_REFLECTION(12,480); -ACE_EXPLOSION_REFLECTION(12,490); -ACE_EXPLOSION_REFLECTION(12,500); -ACE_EXPLOSION_REFLECTION(14,10); -ACE_EXPLOSION_REFLECTION(14,20); -ACE_EXPLOSION_REFLECTION(14,30); -ACE_EXPLOSION_REFLECTION(14,40); -ACE_EXPLOSION_REFLECTION(14,50); -ACE_EXPLOSION_REFLECTION(14,60); -ACE_EXPLOSION_REFLECTION(14,70); -ACE_EXPLOSION_REFLECTION(14,80); -ACE_EXPLOSION_REFLECTION(14,90); -ACE_EXPLOSION_REFLECTION(14,100); -ACE_EXPLOSION_REFLECTION(14,110); -ACE_EXPLOSION_REFLECTION(14,120); -ACE_EXPLOSION_REFLECTION(14,130); -ACE_EXPLOSION_REFLECTION(14,140); -ACE_EXPLOSION_REFLECTION(14,150); -ACE_EXPLOSION_REFLECTION(14,160); -ACE_EXPLOSION_REFLECTION(14,170); -ACE_EXPLOSION_REFLECTION(14,180); -ACE_EXPLOSION_REFLECTION(14,190); -ACE_EXPLOSION_REFLECTION(14,200); -ACE_EXPLOSION_REFLECTION(14,210); -ACE_EXPLOSION_REFLECTION(14,220); -ACE_EXPLOSION_REFLECTION(14,230); -ACE_EXPLOSION_REFLECTION(14,240); -ACE_EXPLOSION_REFLECTION(14,250); -ACE_EXPLOSION_REFLECTION(14,260); -ACE_EXPLOSION_REFLECTION(14,270); -ACE_EXPLOSION_REFLECTION(14,280); -ACE_EXPLOSION_REFLECTION(14,290); -ACE_EXPLOSION_REFLECTION(14,300); -ACE_EXPLOSION_REFLECTION(14,310); -ACE_EXPLOSION_REFLECTION(14,320); -ACE_EXPLOSION_REFLECTION(14,330); -ACE_EXPLOSION_REFLECTION(14,340); -ACE_EXPLOSION_REFLECTION(14,350); -ACE_EXPLOSION_REFLECTION(14,360); -ACE_EXPLOSION_REFLECTION(14,370); -ACE_EXPLOSION_REFLECTION(14,380); -ACE_EXPLOSION_REFLECTION(14,390); -ACE_EXPLOSION_REFLECTION(14,400); -ACE_EXPLOSION_REFLECTION(14,410); -ACE_EXPLOSION_REFLECTION(14,420); -ACE_EXPLOSION_REFLECTION(14,430); -ACE_EXPLOSION_REFLECTION(14,440); -ACE_EXPLOSION_REFLECTION(14,450); -ACE_EXPLOSION_REFLECTION(14,460); -ACE_EXPLOSION_REFLECTION(14,470); -ACE_EXPLOSION_REFLECTION(14,480); -ACE_EXPLOSION_REFLECTION(14,490); -ACE_EXPLOSION_REFLECTION(14,500); -ACE_EXPLOSION_REFLECTION(16,10); -ACE_EXPLOSION_REFLECTION(16,20); -ACE_EXPLOSION_REFLECTION(16,30); -ACE_EXPLOSION_REFLECTION(16,40); -ACE_EXPLOSION_REFLECTION(16,50); -ACE_EXPLOSION_REFLECTION(16,60); -ACE_EXPLOSION_REFLECTION(16,70); -ACE_EXPLOSION_REFLECTION(16,80); -ACE_EXPLOSION_REFLECTION(16,90); -ACE_EXPLOSION_REFLECTION(16,100); -ACE_EXPLOSION_REFLECTION(16,110); -ACE_EXPLOSION_REFLECTION(16,120); -ACE_EXPLOSION_REFLECTION(16,130); -ACE_EXPLOSION_REFLECTION(16,140); -ACE_EXPLOSION_REFLECTION(16,150); -ACE_EXPLOSION_REFLECTION(16,160); -ACE_EXPLOSION_REFLECTION(16,170); -ACE_EXPLOSION_REFLECTION(16,180); -ACE_EXPLOSION_REFLECTION(16,190); -ACE_EXPLOSION_REFLECTION(16,200); -ACE_EXPLOSION_REFLECTION(16,210); -ACE_EXPLOSION_REFLECTION(16,220); -ACE_EXPLOSION_REFLECTION(16,230); -ACE_EXPLOSION_REFLECTION(16,240); -ACE_EXPLOSION_REFLECTION(16,250); -ACE_EXPLOSION_REFLECTION(16,260); -ACE_EXPLOSION_REFLECTION(16,270); -ACE_EXPLOSION_REFLECTION(16,280); -ACE_EXPLOSION_REFLECTION(16,290); -ACE_EXPLOSION_REFLECTION(16,300); -ACE_EXPLOSION_REFLECTION(16,310); -ACE_EXPLOSION_REFLECTION(16,320); -ACE_EXPLOSION_REFLECTION(16,330); -ACE_EXPLOSION_REFLECTION(16,340); -ACE_EXPLOSION_REFLECTION(16,350); -ACE_EXPLOSION_REFLECTION(16,360); -ACE_EXPLOSION_REFLECTION(16,370); -ACE_EXPLOSION_REFLECTION(16,380); -ACE_EXPLOSION_REFLECTION(16,390); -ACE_EXPLOSION_REFLECTION(16,400); -ACE_EXPLOSION_REFLECTION(16,410); -ACE_EXPLOSION_REFLECTION(16,420); -ACE_EXPLOSION_REFLECTION(16,430); -ACE_EXPLOSION_REFLECTION(16,440); -ACE_EXPLOSION_REFLECTION(16,450); -ACE_EXPLOSION_REFLECTION(16,460); -ACE_EXPLOSION_REFLECTION(16,470); -ACE_EXPLOSION_REFLECTION(16,480); -ACE_EXPLOSION_REFLECTION(16,490); -ACE_EXPLOSION_REFLECTION(16,500); -ACE_EXPLOSION_REFLECTION(18,10); -ACE_EXPLOSION_REFLECTION(18,20); -ACE_EXPLOSION_REFLECTION(18,30); -ACE_EXPLOSION_REFLECTION(18,40); -ACE_EXPLOSION_REFLECTION(18,50); -ACE_EXPLOSION_REFLECTION(18,60); -ACE_EXPLOSION_REFLECTION(18,70); -ACE_EXPLOSION_REFLECTION(18,80); -ACE_EXPLOSION_REFLECTION(18,90); -ACE_EXPLOSION_REFLECTION(18,100); -ACE_EXPLOSION_REFLECTION(18,110); -ACE_EXPLOSION_REFLECTION(18,120); -ACE_EXPLOSION_REFLECTION(18,130); -ACE_EXPLOSION_REFLECTION(18,140); -ACE_EXPLOSION_REFLECTION(18,150); -ACE_EXPLOSION_REFLECTION(18,160); -ACE_EXPLOSION_REFLECTION(18,170); -ACE_EXPLOSION_REFLECTION(18,180); -ACE_EXPLOSION_REFLECTION(18,190); -ACE_EXPLOSION_REFLECTION(18,200); -ACE_EXPLOSION_REFLECTION(18,210); -ACE_EXPLOSION_REFLECTION(18,220); -ACE_EXPLOSION_REFLECTION(18,230); -ACE_EXPLOSION_REFLECTION(18,240); -ACE_EXPLOSION_REFLECTION(18,250); -ACE_EXPLOSION_REFLECTION(18,260); -ACE_EXPLOSION_REFLECTION(18,270); -ACE_EXPLOSION_REFLECTION(18,280); -ACE_EXPLOSION_REFLECTION(18,290); -ACE_EXPLOSION_REFLECTION(18,300); -ACE_EXPLOSION_REFLECTION(18,310); -ACE_EXPLOSION_REFLECTION(18,320); -ACE_EXPLOSION_REFLECTION(18,330); -ACE_EXPLOSION_REFLECTION(18,340); -ACE_EXPLOSION_REFLECTION(18,350); -ACE_EXPLOSION_REFLECTION(18,360); -ACE_EXPLOSION_REFLECTION(18,370); -ACE_EXPLOSION_REFLECTION(18,380); -ACE_EXPLOSION_REFLECTION(18,390); -ACE_EXPLOSION_REFLECTION(18,400); -ACE_EXPLOSION_REFLECTION(18,410); -ACE_EXPLOSION_REFLECTION(18,420); -ACE_EXPLOSION_REFLECTION(18,430); -ACE_EXPLOSION_REFLECTION(18,440); -ACE_EXPLOSION_REFLECTION(18,450); -ACE_EXPLOSION_REFLECTION(18,460); -ACE_EXPLOSION_REFLECTION(18,470); -ACE_EXPLOSION_REFLECTION(18,480); -ACE_EXPLOSION_REFLECTION(18,490); -ACE_EXPLOSION_REFLECTION(18,500); -ACE_EXPLOSION_REFLECTION(20,10); -ACE_EXPLOSION_REFLECTION(20,20); -ACE_EXPLOSION_REFLECTION(20,30); -ACE_EXPLOSION_REFLECTION(20,40); -ACE_EXPLOSION_REFLECTION(20,50); -ACE_EXPLOSION_REFLECTION(20,60); -ACE_EXPLOSION_REFLECTION(20,70); -ACE_EXPLOSION_REFLECTION(20,80); -ACE_EXPLOSION_REFLECTION(20,90); -ACE_EXPLOSION_REFLECTION(20,100); -ACE_EXPLOSION_REFLECTION(20,110); -ACE_EXPLOSION_REFLECTION(20,120); -ACE_EXPLOSION_REFLECTION(20,130); -ACE_EXPLOSION_REFLECTION(20,140); -ACE_EXPLOSION_REFLECTION(20,150); -ACE_EXPLOSION_REFLECTION(20,160); -ACE_EXPLOSION_REFLECTION(20,170); -ACE_EXPLOSION_REFLECTION(20,180); -ACE_EXPLOSION_REFLECTION(20,190); -ACE_EXPLOSION_REFLECTION(20,200); -ACE_EXPLOSION_REFLECTION(20,210); -ACE_EXPLOSION_REFLECTION(20,220); -ACE_EXPLOSION_REFLECTION(20,230); -ACE_EXPLOSION_REFLECTION(20,240); -ACE_EXPLOSION_REFLECTION(20,250); -ACE_EXPLOSION_REFLECTION(20,260); -ACE_EXPLOSION_REFLECTION(20,270); -ACE_EXPLOSION_REFLECTION(20,280); -ACE_EXPLOSION_REFLECTION(20,290); -ACE_EXPLOSION_REFLECTION(20,300); -ACE_EXPLOSION_REFLECTION(20,310); -ACE_EXPLOSION_REFLECTION(20,320); -ACE_EXPLOSION_REFLECTION(20,330); -ACE_EXPLOSION_REFLECTION(20,340); -ACE_EXPLOSION_REFLECTION(20,350); -ACE_EXPLOSION_REFLECTION(20,360); -ACE_EXPLOSION_REFLECTION(20,370); -ACE_EXPLOSION_REFLECTION(20,380); -ACE_EXPLOSION_REFLECTION(20,390); -ACE_EXPLOSION_REFLECTION(20,400); -ACE_EXPLOSION_REFLECTION(20,410); -ACE_EXPLOSION_REFLECTION(20,420); -ACE_EXPLOSION_REFLECTION(20,430); -ACE_EXPLOSION_REFLECTION(20,440); -ACE_EXPLOSION_REFLECTION(20,450); -ACE_EXPLOSION_REFLECTION(20,460); -ACE_EXPLOSION_REFLECTION(20,470); -ACE_EXPLOSION_REFLECTION(20,480); -ACE_EXPLOSION_REFLECTION(20,490); -ACE_EXPLOSION_REFLECTION(20,500); -ACE_EXPLOSION_REFLECTION(22,10); -ACE_EXPLOSION_REFLECTION(22,20); -ACE_EXPLOSION_REFLECTION(22,30); -ACE_EXPLOSION_REFLECTION(22,40); -ACE_EXPLOSION_REFLECTION(22,50); -ACE_EXPLOSION_REFLECTION(22,60); -ACE_EXPLOSION_REFLECTION(22,70); -ACE_EXPLOSION_REFLECTION(22,80); -ACE_EXPLOSION_REFLECTION(22,90); -ACE_EXPLOSION_REFLECTION(22,100); -ACE_EXPLOSION_REFLECTION(22,110); -ACE_EXPLOSION_REFLECTION(22,120); -ACE_EXPLOSION_REFLECTION(22,130); -ACE_EXPLOSION_REFLECTION(22,140); -ACE_EXPLOSION_REFLECTION(22,150); -ACE_EXPLOSION_REFLECTION(22,160); -ACE_EXPLOSION_REFLECTION(22,170); -ACE_EXPLOSION_REFLECTION(22,180); -ACE_EXPLOSION_REFLECTION(22,190); -ACE_EXPLOSION_REFLECTION(22,200); -ACE_EXPLOSION_REFLECTION(22,210); -ACE_EXPLOSION_REFLECTION(22,220); -ACE_EXPLOSION_REFLECTION(22,230); -ACE_EXPLOSION_REFLECTION(22,240); -ACE_EXPLOSION_REFLECTION(22,250); -ACE_EXPLOSION_REFLECTION(22,260); -ACE_EXPLOSION_REFLECTION(22,270); -ACE_EXPLOSION_REFLECTION(22,280); -ACE_EXPLOSION_REFLECTION(22,290); -ACE_EXPLOSION_REFLECTION(22,300); -ACE_EXPLOSION_REFLECTION(22,310); -ACE_EXPLOSION_REFLECTION(22,320); -ACE_EXPLOSION_REFLECTION(22,330); -ACE_EXPLOSION_REFLECTION(22,340); -ACE_EXPLOSION_REFLECTION(22,350); -ACE_EXPLOSION_REFLECTION(22,360); -ACE_EXPLOSION_REFLECTION(22,370); -ACE_EXPLOSION_REFLECTION(22,380); -ACE_EXPLOSION_REFLECTION(22,390); -ACE_EXPLOSION_REFLECTION(22,400); -ACE_EXPLOSION_REFLECTION(22,410); -ACE_EXPLOSION_REFLECTION(22,420); -ACE_EXPLOSION_REFLECTION(22,430); -ACE_EXPLOSION_REFLECTION(22,440); -ACE_EXPLOSION_REFLECTION(22,450); -ACE_EXPLOSION_REFLECTION(22,460); -ACE_EXPLOSION_REFLECTION(22,470); -ACE_EXPLOSION_REFLECTION(22,480); -ACE_EXPLOSION_REFLECTION(22,490); -ACE_EXPLOSION_REFLECTION(22,500); -ACE_EXPLOSION_REFLECTION(24,10); -ACE_EXPLOSION_REFLECTION(24,20); -ACE_EXPLOSION_REFLECTION(24,30); -ACE_EXPLOSION_REFLECTION(24,40); -ACE_EXPLOSION_REFLECTION(24,50); -ACE_EXPLOSION_REFLECTION(24,60); -ACE_EXPLOSION_REFLECTION(24,70); -ACE_EXPLOSION_REFLECTION(24,80); -ACE_EXPLOSION_REFLECTION(24,90); -ACE_EXPLOSION_REFLECTION(24,100); -ACE_EXPLOSION_REFLECTION(24,110); -ACE_EXPLOSION_REFLECTION(24,120); -ACE_EXPLOSION_REFLECTION(24,130); -ACE_EXPLOSION_REFLECTION(24,140); -ACE_EXPLOSION_REFLECTION(24,150); -ACE_EXPLOSION_REFLECTION(24,160); -ACE_EXPLOSION_REFLECTION(24,170); -ACE_EXPLOSION_REFLECTION(24,180); -ACE_EXPLOSION_REFLECTION(24,190); -ACE_EXPLOSION_REFLECTION(24,200); -ACE_EXPLOSION_REFLECTION(24,210); -ACE_EXPLOSION_REFLECTION(24,220); -ACE_EXPLOSION_REFLECTION(24,230); -ACE_EXPLOSION_REFLECTION(24,240); -ACE_EXPLOSION_REFLECTION(24,250); -ACE_EXPLOSION_REFLECTION(24,260); -ACE_EXPLOSION_REFLECTION(24,270); -ACE_EXPLOSION_REFLECTION(24,280); -ACE_EXPLOSION_REFLECTION(24,290); -ACE_EXPLOSION_REFLECTION(24,300); -ACE_EXPLOSION_REFLECTION(24,310); -ACE_EXPLOSION_REFLECTION(24,320); -ACE_EXPLOSION_REFLECTION(24,330); -ACE_EXPLOSION_REFLECTION(24,340); -ACE_EXPLOSION_REFLECTION(24,350); -ACE_EXPLOSION_REFLECTION(24,360); -ACE_EXPLOSION_REFLECTION(24,370); -ACE_EXPLOSION_REFLECTION(24,380); -ACE_EXPLOSION_REFLECTION(24,390); -ACE_EXPLOSION_REFLECTION(24,400); -ACE_EXPLOSION_REFLECTION(24,410); -ACE_EXPLOSION_REFLECTION(24,420); -ACE_EXPLOSION_REFLECTION(24,430); -ACE_EXPLOSION_REFLECTION(24,440); -ACE_EXPLOSION_REFLECTION(24,450); -ACE_EXPLOSION_REFLECTION(24,460); -ACE_EXPLOSION_REFLECTION(24,470); -ACE_EXPLOSION_REFLECTION(24,480); -ACE_EXPLOSION_REFLECTION(24,490); -ACE_EXPLOSION_REFLECTION(24,500); -ACE_EXPLOSION_REFLECTION(26,10); -ACE_EXPLOSION_REFLECTION(26,20); -ACE_EXPLOSION_REFLECTION(26,30); -ACE_EXPLOSION_REFLECTION(26,40); -ACE_EXPLOSION_REFLECTION(26,50); -ACE_EXPLOSION_REFLECTION(26,60); -ACE_EXPLOSION_REFLECTION(26,70); -ACE_EXPLOSION_REFLECTION(26,80); -ACE_EXPLOSION_REFLECTION(26,90); -ACE_EXPLOSION_REFLECTION(26,100); -ACE_EXPLOSION_REFLECTION(26,110); -ACE_EXPLOSION_REFLECTION(26,120); -ACE_EXPLOSION_REFLECTION(26,130); -ACE_EXPLOSION_REFLECTION(26,140); -ACE_EXPLOSION_REFLECTION(26,150); -ACE_EXPLOSION_REFLECTION(26,160); -ACE_EXPLOSION_REFLECTION(26,170); -ACE_EXPLOSION_REFLECTION(26,180); -ACE_EXPLOSION_REFLECTION(26,190); -ACE_EXPLOSION_REFLECTION(26,200); -ACE_EXPLOSION_REFLECTION(26,210); -ACE_EXPLOSION_REFLECTION(26,220); -ACE_EXPLOSION_REFLECTION(26,230); -ACE_EXPLOSION_REFLECTION(26,240); -ACE_EXPLOSION_REFLECTION(26,250); -ACE_EXPLOSION_REFLECTION(26,260); -ACE_EXPLOSION_REFLECTION(26,270); -ACE_EXPLOSION_REFLECTION(26,280); -ACE_EXPLOSION_REFLECTION(26,290); -ACE_EXPLOSION_REFLECTION(26,300); -ACE_EXPLOSION_REFLECTION(26,310); -ACE_EXPLOSION_REFLECTION(26,320); -ACE_EXPLOSION_REFLECTION(26,330); -ACE_EXPLOSION_REFLECTION(26,340); -ACE_EXPLOSION_REFLECTION(26,350); -ACE_EXPLOSION_REFLECTION(26,360); -ACE_EXPLOSION_REFLECTION(26,370); -ACE_EXPLOSION_REFLECTION(26,380); -ACE_EXPLOSION_REFLECTION(26,390); -ACE_EXPLOSION_REFLECTION(26,400); -ACE_EXPLOSION_REFLECTION(26,410); -ACE_EXPLOSION_REFLECTION(26,420); -ACE_EXPLOSION_REFLECTION(26,430); -ACE_EXPLOSION_REFLECTION(26,440); -ACE_EXPLOSION_REFLECTION(26,450); -ACE_EXPLOSION_REFLECTION(26,460); -ACE_EXPLOSION_REFLECTION(26,470); -ACE_EXPLOSION_REFLECTION(26,480); -ACE_EXPLOSION_REFLECTION(26,490); -ACE_EXPLOSION_REFLECTION(26,500); -ACE_EXPLOSION_REFLECTION(28,10); -ACE_EXPLOSION_REFLECTION(28,20); -ACE_EXPLOSION_REFLECTION(28,30); -ACE_EXPLOSION_REFLECTION(28,40); -ACE_EXPLOSION_REFLECTION(28,50); -ACE_EXPLOSION_REFLECTION(28,60); -ACE_EXPLOSION_REFLECTION(28,70); -ACE_EXPLOSION_REFLECTION(28,80); -ACE_EXPLOSION_REFLECTION(28,90); -ACE_EXPLOSION_REFLECTION(28,100); -ACE_EXPLOSION_REFLECTION(28,110); -ACE_EXPLOSION_REFLECTION(28,120); -ACE_EXPLOSION_REFLECTION(28,130); -ACE_EXPLOSION_REFLECTION(28,140); -ACE_EXPLOSION_REFLECTION(28,150); -ACE_EXPLOSION_REFLECTION(28,160); -ACE_EXPLOSION_REFLECTION(28,170); -ACE_EXPLOSION_REFLECTION(28,180); -ACE_EXPLOSION_REFLECTION(28,190); -ACE_EXPLOSION_REFLECTION(28,200); -ACE_EXPLOSION_REFLECTION(28,210); -ACE_EXPLOSION_REFLECTION(28,220); -ACE_EXPLOSION_REFLECTION(28,230); -ACE_EXPLOSION_REFLECTION(28,240); -ACE_EXPLOSION_REFLECTION(28,250); -ACE_EXPLOSION_REFLECTION(28,260); -ACE_EXPLOSION_REFLECTION(28,270); -ACE_EXPLOSION_REFLECTION(28,280); -ACE_EXPLOSION_REFLECTION(28,290); -ACE_EXPLOSION_REFLECTION(28,300); -ACE_EXPLOSION_REFLECTION(28,310); -ACE_EXPLOSION_REFLECTION(28,320); -ACE_EXPLOSION_REFLECTION(28,330); -ACE_EXPLOSION_REFLECTION(28,340); -ACE_EXPLOSION_REFLECTION(28,350); -ACE_EXPLOSION_REFLECTION(28,360); -ACE_EXPLOSION_REFLECTION(28,370); -ACE_EXPLOSION_REFLECTION(28,380); -ACE_EXPLOSION_REFLECTION(28,390); -ACE_EXPLOSION_REFLECTION(28,400); -ACE_EXPLOSION_REFLECTION(28,410); -ACE_EXPLOSION_REFLECTION(28,420); -ACE_EXPLOSION_REFLECTION(28,430); -ACE_EXPLOSION_REFLECTION(28,440); -ACE_EXPLOSION_REFLECTION(28,450); -ACE_EXPLOSION_REFLECTION(28,460); -ACE_EXPLOSION_REFLECTION(28,470); -ACE_EXPLOSION_REFLECTION(28,480); -ACE_EXPLOSION_REFLECTION(28,490); -ACE_EXPLOSION_REFLECTION(28,500); -ACE_EXPLOSION_REFLECTION(30,10); -ACE_EXPLOSION_REFLECTION(30,20); -ACE_EXPLOSION_REFLECTION(30,30); -ACE_EXPLOSION_REFLECTION(30,40); -ACE_EXPLOSION_REFLECTION(30,50); -ACE_EXPLOSION_REFLECTION(30,60); -ACE_EXPLOSION_REFLECTION(30,70); -ACE_EXPLOSION_REFLECTION(30,80); -ACE_EXPLOSION_REFLECTION(30,90); -ACE_EXPLOSION_REFLECTION(30,100); -ACE_EXPLOSION_REFLECTION(30,110); -ACE_EXPLOSION_REFLECTION(30,120); -ACE_EXPLOSION_REFLECTION(30,130); -ACE_EXPLOSION_REFLECTION(30,140); -ACE_EXPLOSION_REFLECTION(30,150); -ACE_EXPLOSION_REFLECTION(30,160); -ACE_EXPLOSION_REFLECTION(30,170); -ACE_EXPLOSION_REFLECTION(30,180); -ACE_EXPLOSION_REFLECTION(30,190); -ACE_EXPLOSION_REFLECTION(30,200); -ACE_EXPLOSION_REFLECTION(30,210); -ACE_EXPLOSION_REFLECTION(30,220); -ACE_EXPLOSION_REFLECTION(30,230); -ACE_EXPLOSION_REFLECTION(30,240); -ACE_EXPLOSION_REFLECTION(30,250); -ACE_EXPLOSION_REFLECTION(30,260); -ACE_EXPLOSION_REFLECTION(30,270); -ACE_EXPLOSION_REFLECTION(30,280); -ACE_EXPLOSION_REFLECTION(30,290); -ACE_EXPLOSION_REFLECTION(30,300); -ACE_EXPLOSION_REFLECTION(30,310); -ACE_EXPLOSION_REFLECTION(30,320); -ACE_EXPLOSION_REFLECTION(30,330); -ACE_EXPLOSION_REFLECTION(30,340); -ACE_EXPLOSION_REFLECTION(30,350); -ACE_EXPLOSION_REFLECTION(30,360); -ACE_EXPLOSION_REFLECTION(30,370); -ACE_EXPLOSION_REFLECTION(30,380); -ACE_EXPLOSION_REFLECTION(30,390); -ACE_EXPLOSION_REFLECTION(30,400); -ACE_EXPLOSION_REFLECTION(30,410); -ACE_EXPLOSION_REFLECTION(30,420); -ACE_EXPLOSION_REFLECTION(30,430); -ACE_EXPLOSION_REFLECTION(30,440); -ACE_EXPLOSION_REFLECTION(30,450); -ACE_EXPLOSION_REFLECTION(30,460); -ACE_EXPLOSION_REFLECTION(30,470); -ACE_EXPLOSION_REFLECTION(30,480); -ACE_EXPLOSION_REFLECTION(30,490); -ACE_EXPLOSION_REFLECTION(30,500); -ACE_EXPLOSION_REFLECTION(32,10); -ACE_EXPLOSION_REFLECTION(32,20); -ACE_EXPLOSION_REFLECTION(32,30); -ACE_EXPLOSION_REFLECTION(32,40); -ACE_EXPLOSION_REFLECTION(32,50); -ACE_EXPLOSION_REFLECTION(32,60); -ACE_EXPLOSION_REFLECTION(32,70); -ACE_EXPLOSION_REFLECTION(32,80); -ACE_EXPLOSION_REFLECTION(32,90); -ACE_EXPLOSION_REFLECTION(32,100); -ACE_EXPLOSION_REFLECTION(32,110); -ACE_EXPLOSION_REFLECTION(32,120); -ACE_EXPLOSION_REFLECTION(32,130); -ACE_EXPLOSION_REFLECTION(32,140); -ACE_EXPLOSION_REFLECTION(32,150); -ACE_EXPLOSION_REFLECTION(32,160); -ACE_EXPLOSION_REFLECTION(32,170); -ACE_EXPLOSION_REFLECTION(32,180); -ACE_EXPLOSION_REFLECTION(32,190); -ACE_EXPLOSION_REFLECTION(32,200); -ACE_EXPLOSION_REFLECTION(32,210); -ACE_EXPLOSION_REFLECTION(32,220); -ACE_EXPLOSION_REFLECTION(32,230); -ACE_EXPLOSION_REFLECTION(32,240); -ACE_EXPLOSION_REFLECTION(32,250); -ACE_EXPLOSION_REFLECTION(32,260); -ACE_EXPLOSION_REFLECTION(32,270); -ACE_EXPLOSION_REFLECTION(32,280); -ACE_EXPLOSION_REFLECTION(32,290); -ACE_EXPLOSION_REFLECTION(32,300); -ACE_EXPLOSION_REFLECTION(32,310); -ACE_EXPLOSION_REFLECTION(32,320); -ACE_EXPLOSION_REFLECTION(32,330); -ACE_EXPLOSION_REFLECTION(32,340); -ACE_EXPLOSION_REFLECTION(32,350); -ACE_EXPLOSION_REFLECTION(32,360); -ACE_EXPLOSION_REFLECTION(32,370); -ACE_EXPLOSION_REFLECTION(32,380); -ACE_EXPLOSION_REFLECTION(32,390); -ACE_EXPLOSION_REFLECTION(32,400); -ACE_EXPLOSION_REFLECTION(32,410); -ACE_EXPLOSION_REFLECTION(32,420); -ACE_EXPLOSION_REFLECTION(32,430); -ACE_EXPLOSION_REFLECTION(32,440); -ACE_EXPLOSION_REFLECTION(32,450); -ACE_EXPLOSION_REFLECTION(32,460); -ACE_EXPLOSION_REFLECTION(32,470); -ACE_EXPLOSION_REFLECTION(32,480); -ACE_EXPLOSION_REFLECTION(32,490); -ACE_EXPLOSION_REFLECTION(32,500); -ACE_EXPLOSION_REFLECTION(34,10); -ACE_EXPLOSION_REFLECTION(34,20); -ACE_EXPLOSION_REFLECTION(34,30); -ACE_EXPLOSION_REFLECTION(34,40); -ACE_EXPLOSION_REFLECTION(34,50); -ACE_EXPLOSION_REFLECTION(34,60); -ACE_EXPLOSION_REFLECTION(34,70); -ACE_EXPLOSION_REFLECTION(34,80); -ACE_EXPLOSION_REFLECTION(34,90); -ACE_EXPLOSION_REFLECTION(34,100); -ACE_EXPLOSION_REFLECTION(34,110); -ACE_EXPLOSION_REFLECTION(34,120); -ACE_EXPLOSION_REFLECTION(34,130); -ACE_EXPLOSION_REFLECTION(34,140); -ACE_EXPLOSION_REFLECTION(34,150); -ACE_EXPLOSION_REFLECTION(34,160); -ACE_EXPLOSION_REFLECTION(34,170); -ACE_EXPLOSION_REFLECTION(34,180); -ACE_EXPLOSION_REFLECTION(34,190); -ACE_EXPLOSION_REFLECTION(34,200); -ACE_EXPLOSION_REFLECTION(34,210); -ACE_EXPLOSION_REFLECTION(34,220); -ACE_EXPLOSION_REFLECTION(34,230); -ACE_EXPLOSION_REFLECTION(34,240); -ACE_EXPLOSION_REFLECTION(34,250); -ACE_EXPLOSION_REFLECTION(34,260); -ACE_EXPLOSION_REFLECTION(34,270); -ACE_EXPLOSION_REFLECTION(34,280); -ACE_EXPLOSION_REFLECTION(34,290); -ACE_EXPLOSION_REFLECTION(34,300); -ACE_EXPLOSION_REFLECTION(34,310); -ACE_EXPLOSION_REFLECTION(34,320); -ACE_EXPLOSION_REFLECTION(34,330); -ACE_EXPLOSION_REFLECTION(34,340); -ACE_EXPLOSION_REFLECTION(34,350); -ACE_EXPLOSION_REFLECTION(34,360); -ACE_EXPLOSION_REFLECTION(34,370); -ACE_EXPLOSION_REFLECTION(34,380); -ACE_EXPLOSION_REFLECTION(34,390); -ACE_EXPLOSION_REFLECTION(34,400); -ACE_EXPLOSION_REFLECTION(34,410); -ACE_EXPLOSION_REFLECTION(34,420); -ACE_EXPLOSION_REFLECTION(34,430); -ACE_EXPLOSION_REFLECTION(34,440); -ACE_EXPLOSION_REFLECTION(34,450); -ACE_EXPLOSION_REFLECTION(34,460); -ACE_EXPLOSION_REFLECTION(34,470); -ACE_EXPLOSION_REFLECTION(34,480); -ACE_EXPLOSION_REFLECTION(34,490); -ACE_EXPLOSION_REFLECTION(34,500); -ACE_EXPLOSION_REFLECTION(36,10); -ACE_EXPLOSION_REFLECTION(36,20); -ACE_EXPLOSION_REFLECTION(36,30); -ACE_EXPLOSION_REFLECTION(36,40); -ACE_EXPLOSION_REFLECTION(36,50); -ACE_EXPLOSION_REFLECTION(36,60); -ACE_EXPLOSION_REFLECTION(36,70); -ACE_EXPLOSION_REFLECTION(36,80); -ACE_EXPLOSION_REFLECTION(36,90); -ACE_EXPLOSION_REFLECTION(36,100); -ACE_EXPLOSION_REFLECTION(36,110); -ACE_EXPLOSION_REFLECTION(36,120); -ACE_EXPLOSION_REFLECTION(36,130); -ACE_EXPLOSION_REFLECTION(36,140); -ACE_EXPLOSION_REFLECTION(36,150); -ACE_EXPLOSION_REFLECTION(36,160); -ACE_EXPLOSION_REFLECTION(36,170); -ACE_EXPLOSION_REFLECTION(36,180); -ACE_EXPLOSION_REFLECTION(36,190); -ACE_EXPLOSION_REFLECTION(36,200); -ACE_EXPLOSION_REFLECTION(36,210); -ACE_EXPLOSION_REFLECTION(36,220); -ACE_EXPLOSION_REFLECTION(36,230); -ACE_EXPLOSION_REFLECTION(36,240); -ACE_EXPLOSION_REFLECTION(36,250); -ACE_EXPLOSION_REFLECTION(36,260); -ACE_EXPLOSION_REFLECTION(36,270); -ACE_EXPLOSION_REFLECTION(36,280); -ACE_EXPLOSION_REFLECTION(36,290); -ACE_EXPLOSION_REFLECTION(36,300); -ACE_EXPLOSION_REFLECTION(36,310); -ACE_EXPLOSION_REFLECTION(36,320); -ACE_EXPLOSION_REFLECTION(36,330); -ACE_EXPLOSION_REFLECTION(36,340); -ACE_EXPLOSION_REFLECTION(36,350); -ACE_EXPLOSION_REFLECTION(36,360); -ACE_EXPLOSION_REFLECTION(36,370); -ACE_EXPLOSION_REFLECTION(36,380); -ACE_EXPLOSION_REFLECTION(36,390); -ACE_EXPLOSION_REFLECTION(36,400); -ACE_EXPLOSION_REFLECTION(36,410); -ACE_EXPLOSION_REFLECTION(36,420); -ACE_EXPLOSION_REFLECTION(36,430); -ACE_EXPLOSION_REFLECTION(36,440); -ACE_EXPLOSION_REFLECTION(36,450); -ACE_EXPLOSION_REFLECTION(36,460); -ACE_EXPLOSION_REFLECTION(36,470); -ACE_EXPLOSION_REFLECTION(36,480); -ACE_EXPLOSION_REFLECTION(36,490); -ACE_EXPLOSION_REFLECTION(36,500); -ACE_EXPLOSION_REFLECTION(38,10); -ACE_EXPLOSION_REFLECTION(38,20); -ACE_EXPLOSION_REFLECTION(38,30); -ACE_EXPLOSION_REFLECTION(38,40); -ACE_EXPLOSION_REFLECTION(38,50); -ACE_EXPLOSION_REFLECTION(38,60); -ACE_EXPLOSION_REFLECTION(38,70); -ACE_EXPLOSION_REFLECTION(38,80); -ACE_EXPLOSION_REFLECTION(38,90); -ACE_EXPLOSION_REFLECTION(38,100); -ACE_EXPLOSION_REFLECTION(38,110); -ACE_EXPLOSION_REFLECTION(38,120); -ACE_EXPLOSION_REFLECTION(38,130); -ACE_EXPLOSION_REFLECTION(38,140); -ACE_EXPLOSION_REFLECTION(38,150); -ACE_EXPLOSION_REFLECTION(38,160); -ACE_EXPLOSION_REFLECTION(38,170); -ACE_EXPLOSION_REFLECTION(38,180); -ACE_EXPLOSION_REFLECTION(38,190); -ACE_EXPLOSION_REFLECTION(38,200); -ACE_EXPLOSION_REFLECTION(38,210); -ACE_EXPLOSION_REFLECTION(38,220); -ACE_EXPLOSION_REFLECTION(38,230); -ACE_EXPLOSION_REFLECTION(38,240); -ACE_EXPLOSION_REFLECTION(38,250); -ACE_EXPLOSION_REFLECTION(38,260); -ACE_EXPLOSION_REFLECTION(38,270); -ACE_EXPLOSION_REFLECTION(38,280); -ACE_EXPLOSION_REFLECTION(38,290); -ACE_EXPLOSION_REFLECTION(38,300); -ACE_EXPLOSION_REFLECTION(38,310); -ACE_EXPLOSION_REFLECTION(38,320); -ACE_EXPLOSION_REFLECTION(38,330); -ACE_EXPLOSION_REFLECTION(38,340); -ACE_EXPLOSION_REFLECTION(38,350); -ACE_EXPLOSION_REFLECTION(38,360); -ACE_EXPLOSION_REFLECTION(38,370); -ACE_EXPLOSION_REFLECTION(38,380); -ACE_EXPLOSION_REFLECTION(38,390); -ACE_EXPLOSION_REFLECTION(38,400); -ACE_EXPLOSION_REFLECTION(38,410); -ACE_EXPLOSION_REFLECTION(38,420); -ACE_EXPLOSION_REFLECTION(38,430); -ACE_EXPLOSION_REFLECTION(38,440); -ACE_EXPLOSION_REFLECTION(38,450); -ACE_EXPLOSION_REFLECTION(38,460); -ACE_EXPLOSION_REFLECTION(38,470); -ACE_EXPLOSION_REFLECTION(38,480); -ACE_EXPLOSION_REFLECTION(38,490); -ACE_EXPLOSION_REFLECTION(38,500); -ACE_EXPLOSION_REFLECTION(40,10); -ACE_EXPLOSION_REFLECTION(40,20); -ACE_EXPLOSION_REFLECTION(40,30); -ACE_EXPLOSION_REFLECTION(40,40); -ACE_EXPLOSION_REFLECTION(40,50); -ACE_EXPLOSION_REFLECTION(40,60); -ACE_EXPLOSION_REFLECTION(40,70); -ACE_EXPLOSION_REFLECTION(40,80); -ACE_EXPLOSION_REFLECTION(40,90); -ACE_EXPLOSION_REFLECTION(40,100); -ACE_EXPLOSION_REFLECTION(40,110); -ACE_EXPLOSION_REFLECTION(40,120); -ACE_EXPLOSION_REFLECTION(40,130); -ACE_EXPLOSION_REFLECTION(40,140); -ACE_EXPLOSION_REFLECTION(40,150); -ACE_EXPLOSION_REFLECTION(40,160); -ACE_EXPLOSION_REFLECTION(40,170); -ACE_EXPLOSION_REFLECTION(40,180); -ACE_EXPLOSION_REFLECTION(40,190); -ACE_EXPLOSION_REFLECTION(40,200); -ACE_EXPLOSION_REFLECTION(40,210); -ACE_EXPLOSION_REFLECTION(40,220); -ACE_EXPLOSION_REFLECTION(40,230); -ACE_EXPLOSION_REFLECTION(40,240); -ACE_EXPLOSION_REFLECTION(40,250); -ACE_EXPLOSION_REFLECTION(40,260); -ACE_EXPLOSION_REFLECTION(40,270); -ACE_EXPLOSION_REFLECTION(40,280); -ACE_EXPLOSION_REFLECTION(40,290); -ACE_EXPLOSION_REFLECTION(40,300); -ACE_EXPLOSION_REFLECTION(40,310); -ACE_EXPLOSION_REFLECTION(40,320); -ACE_EXPLOSION_REFLECTION(40,330); -ACE_EXPLOSION_REFLECTION(40,340); -ACE_EXPLOSION_REFLECTION(40,350); -ACE_EXPLOSION_REFLECTION(40,360); -ACE_EXPLOSION_REFLECTION(40,370); -ACE_EXPLOSION_REFLECTION(40,380); -ACE_EXPLOSION_REFLECTION(40,390); -ACE_EXPLOSION_REFLECTION(40,400); -ACE_EXPLOSION_REFLECTION(40,410); -ACE_EXPLOSION_REFLECTION(40,420); -ACE_EXPLOSION_REFLECTION(40,430); -ACE_EXPLOSION_REFLECTION(40,440); -ACE_EXPLOSION_REFLECTION(40,450); -ACE_EXPLOSION_REFLECTION(40,460); -ACE_EXPLOSION_REFLECTION(40,470); -ACE_EXPLOSION_REFLECTION(40,480); -ACE_EXPLOSION_REFLECTION(40,490); -ACE_EXPLOSION_REFLECTION(40,500); -ACE_EXPLOSION_REFLECTION(42,10); -ACE_EXPLOSION_REFLECTION(42,20); -ACE_EXPLOSION_REFLECTION(42,30); -ACE_EXPLOSION_REFLECTION(42,40); -ACE_EXPLOSION_REFLECTION(42,50); -ACE_EXPLOSION_REFLECTION(42,60); -ACE_EXPLOSION_REFLECTION(42,70); -ACE_EXPLOSION_REFLECTION(42,80); -ACE_EXPLOSION_REFLECTION(42,90); -ACE_EXPLOSION_REFLECTION(42,100); -ACE_EXPLOSION_REFLECTION(42,110); -ACE_EXPLOSION_REFLECTION(42,120); -ACE_EXPLOSION_REFLECTION(42,130); -ACE_EXPLOSION_REFLECTION(42,140); -ACE_EXPLOSION_REFLECTION(42,150); -ACE_EXPLOSION_REFLECTION(42,160); -ACE_EXPLOSION_REFLECTION(42,170); -ACE_EXPLOSION_REFLECTION(42,180); -ACE_EXPLOSION_REFLECTION(42,190); -ACE_EXPLOSION_REFLECTION(42,200); -ACE_EXPLOSION_REFLECTION(42,210); -ACE_EXPLOSION_REFLECTION(42,220); -ACE_EXPLOSION_REFLECTION(42,230); -ACE_EXPLOSION_REFLECTION(42,240); -ACE_EXPLOSION_REFLECTION(42,250); -ACE_EXPLOSION_REFLECTION(42,260); -ACE_EXPLOSION_REFLECTION(42,270); -ACE_EXPLOSION_REFLECTION(42,280); -ACE_EXPLOSION_REFLECTION(42,290); -ACE_EXPLOSION_REFLECTION(42,300); -ACE_EXPLOSION_REFLECTION(42,310); -ACE_EXPLOSION_REFLECTION(42,320); -ACE_EXPLOSION_REFLECTION(42,330); -ACE_EXPLOSION_REFLECTION(42,340); -ACE_EXPLOSION_REFLECTION(42,350); -ACE_EXPLOSION_REFLECTION(42,360); -ACE_EXPLOSION_REFLECTION(42,370); -ACE_EXPLOSION_REFLECTION(42,380); -ACE_EXPLOSION_REFLECTION(42,390); -ACE_EXPLOSION_REFLECTION(42,400); -ACE_EXPLOSION_REFLECTION(42,410); -ACE_EXPLOSION_REFLECTION(42,420); -ACE_EXPLOSION_REFLECTION(42,430); -ACE_EXPLOSION_REFLECTION(42,440); -ACE_EXPLOSION_REFLECTION(42,450); -ACE_EXPLOSION_REFLECTION(42,460); -ACE_EXPLOSION_REFLECTION(42,470); -ACE_EXPLOSION_REFLECTION(42,480); -ACE_EXPLOSION_REFLECTION(42,490); -ACE_EXPLOSION_REFLECTION(42,500); -ACE_EXPLOSION_REFLECTION(44,10); -ACE_EXPLOSION_REFLECTION(44,20); -ACE_EXPLOSION_REFLECTION(44,30); -ACE_EXPLOSION_REFLECTION(44,40); -ACE_EXPLOSION_REFLECTION(44,50); -ACE_EXPLOSION_REFLECTION(44,60); -ACE_EXPLOSION_REFLECTION(44,70); -ACE_EXPLOSION_REFLECTION(44,80); -ACE_EXPLOSION_REFLECTION(44,90); -ACE_EXPLOSION_REFLECTION(44,100); -ACE_EXPLOSION_REFLECTION(44,110); -ACE_EXPLOSION_REFLECTION(44,120); -ACE_EXPLOSION_REFLECTION(44,130); -ACE_EXPLOSION_REFLECTION(44,140); -ACE_EXPLOSION_REFLECTION(44,150); -ACE_EXPLOSION_REFLECTION(44,160); -ACE_EXPLOSION_REFLECTION(44,170); -ACE_EXPLOSION_REFLECTION(44,180); -ACE_EXPLOSION_REFLECTION(44,190); -ACE_EXPLOSION_REFLECTION(44,200); -ACE_EXPLOSION_REFLECTION(44,210); -ACE_EXPLOSION_REFLECTION(44,220); -ACE_EXPLOSION_REFLECTION(44,230); -ACE_EXPLOSION_REFLECTION(44,240); -ACE_EXPLOSION_REFLECTION(44,250); -ACE_EXPLOSION_REFLECTION(44,260); -ACE_EXPLOSION_REFLECTION(44,270); -ACE_EXPLOSION_REFLECTION(44,280); -ACE_EXPLOSION_REFLECTION(44,290); -ACE_EXPLOSION_REFLECTION(44,300); -ACE_EXPLOSION_REFLECTION(44,310); -ACE_EXPLOSION_REFLECTION(44,320); -ACE_EXPLOSION_REFLECTION(44,330); -ACE_EXPLOSION_REFLECTION(44,340); -ACE_EXPLOSION_REFLECTION(44,350); -ACE_EXPLOSION_REFLECTION(44,360); -ACE_EXPLOSION_REFLECTION(44,370); -ACE_EXPLOSION_REFLECTION(44,380); -ACE_EXPLOSION_REFLECTION(44,390); -ACE_EXPLOSION_REFLECTION(44,400); -ACE_EXPLOSION_REFLECTION(44,410); -ACE_EXPLOSION_REFLECTION(44,420); -ACE_EXPLOSION_REFLECTION(44,430); -ACE_EXPLOSION_REFLECTION(44,440); -ACE_EXPLOSION_REFLECTION(44,450); -ACE_EXPLOSION_REFLECTION(44,460); -ACE_EXPLOSION_REFLECTION(44,470); -ACE_EXPLOSION_REFLECTION(44,480); -ACE_EXPLOSION_REFLECTION(44,490); -ACE_EXPLOSION_REFLECTION(44,500); -ACE_EXPLOSION_REFLECTION(46,10); -ACE_EXPLOSION_REFLECTION(46,20); -ACE_EXPLOSION_REFLECTION(46,30); -ACE_EXPLOSION_REFLECTION(46,40); -ACE_EXPLOSION_REFLECTION(46,50); -ACE_EXPLOSION_REFLECTION(46,60); -ACE_EXPLOSION_REFLECTION(46,70); -ACE_EXPLOSION_REFLECTION(46,80); -ACE_EXPLOSION_REFLECTION(46,90); -ACE_EXPLOSION_REFLECTION(46,100); -ACE_EXPLOSION_REFLECTION(46,110); -ACE_EXPLOSION_REFLECTION(46,120); -ACE_EXPLOSION_REFLECTION(46,130); -ACE_EXPLOSION_REFLECTION(46,140); -ACE_EXPLOSION_REFLECTION(46,150); -ACE_EXPLOSION_REFLECTION(46,160); -ACE_EXPLOSION_REFLECTION(46,170); -ACE_EXPLOSION_REFLECTION(46,180); -ACE_EXPLOSION_REFLECTION(46,190); -ACE_EXPLOSION_REFLECTION(46,200); -ACE_EXPLOSION_REFLECTION(46,210); -ACE_EXPLOSION_REFLECTION(46,220); -ACE_EXPLOSION_REFLECTION(46,230); -ACE_EXPLOSION_REFLECTION(46,240); -ACE_EXPLOSION_REFLECTION(46,250); -ACE_EXPLOSION_REFLECTION(46,260); -ACE_EXPLOSION_REFLECTION(46,270); -ACE_EXPLOSION_REFLECTION(46,280); -ACE_EXPLOSION_REFLECTION(46,290); -ACE_EXPLOSION_REFLECTION(46,300); -ACE_EXPLOSION_REFLECTION(46,310); -ACE_EXPLOSION_REFLECTION(46,320); -ACE_EXPLOSION_REFLECTION(46,330); -ACE_EXPLOSION_REFLECTION(46,340); -ACE_EXPLOSION_REFLECTION(46,350); -ACE_EXPLOSION_REFLECTION(46,360); -ACE_EXPLOSION_REFLECTION(46,370); -ACE_EXPLOSION_REFLECTION(46,380); -ACE_EXPLOSION_REFLECTION(46,390); -ACE_EXPLOSION_REFLECTION(46,400); -ACE_EXPLOSION_REFLECTION(46,410); -ACE_EXPLOSION_REFLECTION(46,420); -ACE_EXPLOSION_REFLECTION(46,430); -ACE_EXPLOSION_REFLECTION(46,440); -ACE_EXPLOSION_REFLECTION(46,450); -ACE_EXPLOSION_REFLECTION(46,460); -ACE_EXPLOSION_REFLECTION(46,470); -ACE_EXPLOSION_REFLECTION(46,480); -ACE_EXPLOSION_REFLECTION(46,490); -ACE_EXPLOSION_REFLECTION(46,500); -ACE_EXPLOSION_REFLECTION(48,10); -ACE_EXPLOSION_REFLECTION(48,20); -ACE_EXPLOSION_REFLECTION(48,30); -ACE_EXPLOSION_REFLECTION(48,40); -ACE_EXPLOSION_REFLECTION(48,50); -ACE_EXPLOSION_REFLECTION(48,60); -ACE_EXPLOSION_REFLECTION(48,70); -ACE_EXPLOSION_REFLECTION(48,80); -ACE_EXPLOSION_REFLECTION(48,90); -ACE_EXPLOSION_REFLECTION(48,100); -ACE_EXPLOSION_REFLECTION(48,110); -ACE_EXPLOSION_REFLECTION(48,120); -ACE_EXPLOSION_REFLECTION(48,130); -ACE_EXPLOSION_REFLECTION(48,140); -ACE_EXPLOSION_REFLECTION(48,150); -ACE_EXPLOSION_REFLECTION(48,160); -ACE_EXPLOSION_REFLECTION(48,170); -ACE_EXPLOSION_REFLECTION(48,180); -ACE_EXPLOSION_REFLECTION(48,190); -ACE_EXPLOSION_REFLECTION(48,200); -ACE_EXPLOSION_REFLECTION(48,210); -ACE_EXPLOSION_REFLECTION(48,220); -ACE_EXPLOSION_REFLECTION(48,230); -ACE_EXPLOSION_REFLECTION(48,240); -ACE_EXPLOSION_REFLECTION(48,250); -ACE_EXPLOSION_REFLECTION(48,260); -ACE_EXPLOSION_REFLECTION(48,270); -ACE_EXPLOSION_REFLECTION(48,280); -ACE_EXPLOSION_REFLECTION(48,290); -ACE_EXPLOSION_REFLECTION(48,300); -ACE_EXPLOSION_REFLECTION(48,310); -ACE_EXPLOSION_REFLECTION(48,320); -ACE_EXPLOSION_REFLECTION(48,330); -ACE_EXPLOSION_REFLECTION(48,340); -ACE_EXPLOSION_REFLECTION(48,350); -ACE_EXPLOSION_REFLECTION(48,360); -ACE_EXPLOSION_REFLECTION(48,370); -ACE_EXPLOSION_REFLECTION(48,380); -ACE_EXPLOSION_REFLECTION(48,390); -ACE_EXPLOSION_REFLECTION(48,400); -ACE_EXPLOSION_REFLECTION(48,410); -ACE_EXPLOSION_REFLECTION(48,420); -ACE_EXPLOSION_REFLECTION(48,430); -ACE_EXPLOSION_REFLECTION(48,440); -ACE_EXPLOSION_REFLECTION(48,450); -ACE_EXPLOSION_REFLECTION(48,460); -ACE_EXPLOSION_REFLECTION(48,470); -ACE_EXPLOSION_REFLECTION(48,480); -ACE_EXPLOSION_REFLECTION(48,490); -ACE_EXPLOSION_REFLECTION(48,500); -ACE_EXPLOSION_REFLECTION(50,10); -ACE_EXPLOSION_REFLECTION(50,20); -ACE_EXPLOSION_REFLECTION(50,30); -ACE_EXPLOSION_REFLECTION(50,40); -ACE_EXPLOSION_REFLECTION(50,50); -ACE_EXPLOSION_REFLECTION(50,60); -ACE_EXPLOSION_REFLECTION(50,70); -ACE_EXPLOSION_REFLECTION(50,80); -ACE_EXPLOSION_REFLECTION(50,90); -ACE_EXPLOSION_REFLECTION(50,100); -ACE_EXPLOSION_REFLECTION(50,110); -ACE_EXPLOSION_REFLECTION(50,120); -ACE_EXPLOSION_REFLECTION(50,130); -ACE_EXPLOSION_REFLECTION(50,140); -ACE_EXPLOSION_REFLECTION(50,150); -ACE_EXPLOSION_REFLECTION(50,160); -ACE_EXPLOSION_REFLECTION(50,170); -ACE_EXPLOSION_REFLECTION(50,180); -ACE_EXPLOSION_REFLECTION(50,190); -ACE_EXPLOSION_REFLECTION(50,200); -ACE_EXPLOSION_REFLECTION(50,210); -ACE_EXPLOSION_REFLECTION(50,220); -ACE_EXPLOSION_REFLECTION(50,230); -ACE_EXPLOSION_REFLECTION(50,240); -ACE_EXPLOSION_REFLECTION(50,250); -ACE_EXPLOSION_REFLECTION(50,260); -ACE_EXPLOSION_REFLECTION(50,270); -ACE_EXPLOSION_REFLECTION(50,280); -ACE_EXPLOSION_REFLECTION(50,290); -ACE_EXPLOSION_REFLECTION(50,300); -ACE_EXPLOSION_REFLECTION(50,310); -ACE_EXPLOSION_REFLECTION(50,320); -ACE_EXPLOSION_REFLECTION(50,330); -ACE_EXPLOSION_REFLECTION(50,340); -ACE_EXPLOSION_REFLECTION(50,350); -ACE_EXPLOSION_REFLECTION(50,360); -ACE_EXPLOSION_REFLECTION(50,370); -ACE_EXPLOSION_REFLECTION(50,380); -ACE_EXPLOSION_REFLECTION(50,390); -ACE_EXPLOSION_REFLECTION(50,400); -ACE_EXPLOSION_REFLECTION(50,410); -ACE_EXPLOSION_REFLECTION(50,420); -ACE_EXPLOSION_REFLECTION(50,430); -ACE_EXPLOSION_REFLECTION(50,440); -ACE_EXPLOSION_REFLECTION(50,450); -ACE_EXPLOSION_REFLECTION(50,460); -ACE_EXPLOSION_REFLECTION(50,470); -ACE_EXPLOSION_REFLECTION(50,480); -ACE_EXPLOSION_REFLECTION(50,490); -ACE_EXPLOSION_REFLECTION(50,500); -ACE_EXPLOSION_REFLECTION(52,10); -ACE_EXPLOSION_REFLECTION(52,20); -ACE_EXPLOSION_REFLECTION(52,30); -ACE_EXPLOSION_REFLECTION(52,40); -ACE_EXPLOSION_REFLECTION(52,50); -ACE_EXPLOSION_REFLECTION(52,60); -ACE_EXPLOSION_REFLECTION(52,70); -ACE_EXPLOSION_REFLECTION(52,80); -ACE_EXPLOSION_REFLECTION(52,90); -ACE_EXPLOSION_REFLECTION(52,100); -ACE_EXPLOSION_REFLECTION(52,110); -ACE_EXPLOSION_REFLECTION(52,120); -ACE_EXPLOSION_REFLECTION(52,130); -ACE_EXPLOSION_REFLECTION(52,140); -ACE_EXPLOSION_REFLECTION(52,150); -ACE_EXPLOSION_REFLECTION(52,160); -ACE_EXPLOSION_REFLECTION(52,170); -ACE_EXPLOSION_REFLECTION(52,180); -ACE_EXPLOSION_REFLECTION(52,190); -ACE_EXPLOSION_REFLECTION(52,200); -ACE_EXPLOSION_REFLECTION(52,210); -ACE_EXPLOSION_REFLECTION(52,220); -ACE_EXPLOSION_REFLECTION(52,230); -ACE_EXPLOSION_REFLECTION(52,240); -ACE_EXPLOSION_REFLECTION(52,250); -ACE_EXPLOSION_REFLECTION(52,260); -ACE_EXPLOSION_REFLECTION(52,270); -ACE_EXPLOSION_REFLECTION(52,280); -ACE_EXPLOSION_REFLECTION(52,290); -ACE_EXPLOSION_REFLECTION(52,300); -ACE_EXPLOSION_REFLECTION(52,310); -ACE_EXPLOSION_REFLECTION(52,320); -ACE_EXPLOSION_REFLECTION(52,330); -ACE_EXPLOSION_REFLECTION(52,340); -ACE_EXPLOSION_REFLECTION(52,350); -ACE_EXPLOSION_REFLECTION(52,360); -ACE_EXPLOSION_REFLECTION(52,370); -ACE_EXPLOSION_REFLECTION(52,380); -ACE_EXPLOSION_REFLECTION(52,390); -ACE_EXPLOSION_REFLECTION(52,400); -ACE_EXPLOSION_REFLECTION(52,410); -ACE_EXPLOSION_REFLECTION(52,420); -ACE_EXPLOSION_REFLECTION(52,430); -ACE_EXPLOSION_REFLECTION(52,440); -ACE_EXPLOSION_REFLECTION(52,450); -ACE_EXPLOSION_REFLECTION(52,460); -ACE_EXPLOSION_REFLECTION(52,470); -ACE_EXPLOSION_REFLECTION(52,480); -ACE_EXPLOSION_REFLECTION(52,490); -ACE_EXPLOSION_REFLECTION(52,500); -ACE_EXPLOSION_REFLECTION(54,10); -ACE_EXPLOSION_REFLECTION(54,20); -ACE_EXPLOSION_REFLECTION(54,30); -ACE_EXPLOSION_REFLECTION(54,40); -ACE_EXPLOSION_REFLECTION(54,50); -ACE_EXPLOSION_REFLECTION(54,60); -ACE_EXPLOSION_REFLECTION(54,70); -ACE_EXPLOSION_REFLECTION(54,80); -ACE_EXPLOSION_REFLECTION(54,90); -ACE_EXPLOSION_REFLECTION(54,100); -ACE_EXPLOSION_REFLECTION(54,110); -ACE_EXPLOSION_REFLECTION(54,120); -ACE_EXPLOSION_REFLECTION(54,130); -ACE_EXPLOSION_REFLECTION(54,140); -ACE_EXPLOSION_REFLECTION(54,150); -ACE_EXPLOSION_REFLECTION(54,160); -ACE_EXPLOSION_REFLECTION(54,170); -ACE_EXPLOSION_REFLECTION(54,180); -ACE_EXPLOSION_REFLECTION(54,190); -ACE_EXPLOSION_REFLECTION(54,200); -ACE_EXPLOSION_REFLECTION(54,210); -ACE_EXPLOSION_REFLECTION(54,220); -ACE_EXPLOSION_REFLECTION(54,230); -ACE_EXPLOSION_REFLECTION(54,240); -ACE_EXPLOSION_REFLECTION(54,250); -ACE_EXPLOSION_REFLECTION(54,260); -ACE_EXPLOSION_REFLECTION(54,270); -ACE_EXPLOSION_REFLECTION(54,280); -ACE_EXPLOSION_REFLECTION(54,290); -ACE_EXPLOSION_REFLECTION(54,300); -ACE_EXPLOSION_REFLECTION(54,310); -ACE_EXPLOSION_REFLECTION(54,320); -ACE_EXPLOSION_REFLECTION(54,330); -ACE_EXPLOSION_REFLECTION(54,340); -ACE_EXPLOSION_REFLECTION(54,350); -ACE_EXPLOSION_REFLECTION(54,360); -ACE_EXPLOSION_REFLECTION(54,370); -ACE_EXPLOSION_REFLECTION(54,380); -ACE_EXPLOSION_REFLECTION(54,390); -ACE_EXPLOSION_REFLECTION(54,400); -ACE_EXPLOSION_REFLECTION(54,410); -ACE_EXPLOSION_REFLECTION(54,420); -ACE_EXPLOSION_REFLECTION(54,430); -ACE_EXPLOSION_REFLECTION(54,440); -ACE_EXPLOSION_REFLECTION(54,450); -ACE_EXPLOSION_REFLECTION(54,460); -ACE_EXPLOSION_REFLECTION(54,470); -ACE_EXPLOSION_REFLECTION(54,480); -ACE_EXPLOSION_REFLECTION(54,490); -ACE_EXPLOSION_REFLECTION(54,500); -ACE_EXPLOSION_REFLECTION(56,10); -ACE_EXPLOSION_REFLECTION(56,20); -ACE_EXPLOSION_REFLECTION(56,30); -ACE_EXPLOSION_REFLECTION(56,40); -ACE_EXPLOSION_REFLECTION(56,50); -ACE_EXPLOSION_REFLECTION(56,60); -ACE_EXPLOSION_REFLECTION(56,70); -ACE_EXPLOSION_REFLECTION(56,80); -ACE_EXPLOSION_REFLECTION(56,90); -ACE_EXPLOSION_REFLECTION(56,100); -ACE_EXPLOSION_REFLECTION(56,110); -ACE_EXPLOSION_REFLECTION(56,120); -ACE_EXPLOSION_REFLECTION(56,130); -ACE_EXPLOSION_REFLECTION(56,140); -ACE_EXPLOSION_REFLECTION(56,150); -ACE_EXPLOSION_REFLECTION(56,160); -ACE_EXPLOSION_REFLECTION(56,170); -ACE_EXPLOSION_REFLECTION(56,180); -ACE_EXPLOSION_REFLECTION(56,190); -ACE_EXPLOSION_REFLECTION(56,200); -ACE_EXPLOSION_REFLECTION(56,210); -ACE_EXPLOSION_REFLECTION(56,220); -ACE_EXPLOSION_REFLECTION(56,230); -ACE_EXPLOSION_REFLECTION(56,240); -ACE_EXPLOSION_REFLECTION(56,250); -ACE_EXPLOSION_REFLECTION(56,260); -ACE_EXPLOSION_REFLECTION(56,270); -ACE_EXPLOSION_REFLECTION(56,280); -ACE_EXPLOSION_REFLECTION(56,290); -ACE_EXPLOSION_REFLECTION(56,300); -ACE_EXPLOSION_REFLECTION(56,310); -ACE_EXPLOSION_REFLECTION(56,320); -ACE_EXPLOSION_REFLECTION(56,330); -ACE_EXPLOSION_REFLECTION(56,340); -ACE_EXPLOSION_REFLECTION(56,350); -ACE_EXPLOSION_REFLECTION(56,360); -ACE_EXPLOSION_REFLECTION(56,370); -ACE_EXPLOSION_REFLECTION(56,380); -ACE_EXPLOSION_REFLECTION(56,390); -ACE_EXPLOSION_REFLECTION(56,400); -ACE_EXPLOSION_REFLECTION(56,410); -ACE_EXPLOSION_REFLECTION(56,420); -ACE_EXPLOSION_REFLECTION(56,430); -ACE_EXPLOSION_REFLECTION(56,440); -ACE_EXPLOSION_REFLECTION(56,450); -ACE_EXPLOSION_REFLECTION(56,460); -ACE_EXPLOSION_REFLECTION(56,470); -ACE_EXPLOSION_REFLECTION(56,480); -ACE_EXPLOSION_REFLECTION(56,490); -ACE_EXPLOSION_REFLECTION(56,500); -ACE_EXPLOSION_REFLECTION(58,10); -ACE_EXPLOSION_REFLECTION(58,20); -ACE_EXPLOSION_REFLECTION(58,30); -ACE_EXPLOSION_REFLECTION(58,40); -ACE_EXPLOSION_REFLECTION(58,50); -ACE_EXPLOSION_REFLECTION(58,60); -ACE_EXPLOSION_REFLECTION(58,70); -ACE_EXPLOSION_REFLECTION(58,80); -ACE_EXPLOSION_REFLECTION(58,90); -ACE_EXPLOSION_REFLECTION(58,100); -ACE_EXPLOSION_REFLECTION(58,110); -ACE_EXPLOSION_REFLECTION(58,120); -ACE_EXPLOSION_REFLECTION(58,130); -ACE_EXPLOSION_REFLECTION(58,140); -ACE_EXPLOSION_REFLECTION(58,150); -ACE_EXPLOSION_REFLECTION(58,160); -ACE_EXPLOSION_REFLECTION(58,170); -ACE_EXPLOSION_REFLECTION(58,180); -ACE_EXPLOSION_REFLECTION(58,190); -ACE_EXPLOSION_REFLECTION(58,200); -ACE_EXPLOSION_REFLECTION(58,210); -ACE_EXPLOSION_REFLECTION(58,220); -ACE_EXPLOSION_REFLECTION(58,230); -ACE_EXPLOSION_REFLECTION(58,240); -ACE_EXPLOSION_REFLECTION(58,250); -ACE_EXPLOSION_REFLECTION(58,260); -ACE_EXPLOSION_REFLECTION(58,270); -ACE_EXPLOSION_REFLECTION(58,280); -ACE_EXPLOSION_REFLECTION(58,290); -ACE_EXPLOSION_REFLECTION(58,300); -ACE_EXPLOSION_REFLECTION(58,310); -ACE_EXPLOSION_REFLECTION(58,320); -ACE_EXPLOSION_REFLECTION(58,330); -ACE_EXPLOSION_REFLECTION(58,340); -ACE_EXPLOSION_REFLECTION(58,350); -ACE_EXPLOSION_REFLECTION(58,360); -ACE_EXPLOSION_REFLECTION(58,370); -ACE_EXPLOSION_REFLECTION(58,380); -ACE_EXPLOSION_REFLECTION(58,390); -ACE_EXPLOSION_REFLECTION(58,400); -ACE_EXPLOSION_REFLECTION(58,410); -ACE_EXPLOSION_REFLECTION(58,420); -ACE_EXPLOSION_REFLECTION(58,430); -ACE_EXPLOSION_REFLECTION(58,440); -ACE_EXPLOSION_REFLECTION(58,450); -ACE_EXPLOSION_REFLECTION(58,460); -ACE_EXPLOSION_REFLECTION(58,470); -ACE_EXPLOSION_REFLECTION(58,480); -ACE_EXPLOSION_REFLECTION(58,490); -ACE_EXPLOSION_REFLECTION(58,500); -ACE_EXPLOSION_REFLECTION(60,10); -ACE_EXPLOSION_REFLECTION(60,20); -ACE_EXPLOSION_REFLECTION(60,30); -ACE_EXPLOSION_REFLECTION(60,40); -ACE_EXPLOSION_REFLECTION(60,50); -ACE_EXPLOSION_REFLECTION(60,60); -ACE_EXPLOSION_REFLECTION(60,70); -ACE_EXPLOSION_REFLECTION(60,80); -ACE_EXPLOSION_REFLECTION(60,90); -ACE_EXPLOSION_REFLECTION(60,100); -ACE_EXPLOSION_REFLECTION(60,110); -ACE_EXPLOSION_REFLECTION(60,120); -ACE_EXPLOSION_REFLECTION(60,130); -ACE_EXPLOSION_REFLECTION(60,140); -ACE_EXPLOSION_REFLECTION(60,150); -ACE_EXPLOSION_REFLECTION(60,160); -ACE_EXPLOSION_REFLECTION(60,170); -ACE_EXPLOSION_REFLECTION(60,180); -ACE_EXPLOSION_REFLECTION(60,190); -ACE_EXPLOSION_REFLECTION(60,200); -ACE_EXPLOSION_REFLECTION(60,210); -ACE_EXPLOSION_REFLECTION(60,220); -ACE_EXPLOSION_REFLECTION(60,230); -ACE_EXPLOSION_REFLECTION(60,240); -ACE_EXPLOSION_REFLECTION(60,250); -ACE_EXPLOSION_REFLECTION(60,260); -ACE_EXPLOSION_REFLECTION(60,270); -ACE_EXPLOSION_REFLECTION(60,280); -ACE_EXPLOSION_REFLECTION(60,290); -ACE_EXPLOSION_REFLECTION(60,300); -ACE_EXPLOSION_REFLECTION(60,310); -ACE_EXPLOSION_REFLECTION(60,320); -ACE_EXPLOSION_REFLECTION(60,330); -ACE_EXPLOSION_REFLECTION(60,340); -ACE_EXPLOSION_REFLECTION(60,350); -ACE_EXPLOSION_REFLECTION(60,360); -ACE_EXPLOSION_REFLECTION(60,370); -ACE_EXPLOSION_REFLECTION(60,380); -ACE_EXPLOSION_REFLECTION(60,390); -ACE_EXPLOSION_REFLECTION(60,400); -ACE_EXPLOSION_REFLECTION(60,410); -ACE_EXPLOSION_REFLECTION(60,420); -ACE_EXPLOSION_REFLECTION(60,430); -ACE_EXPLOSION_REFLECTION(60,440); -ACE_EXPLOSION_REFLECTION(60,450); -ACE_EXPLOSION_REFLECTION(60,460); -ACE_EXPLOSION_REFLECTION(60,470); -ACE_EXPLOSION_REFLECTION(60,480); -ACE_EXPLOSION_REFLECTION(60,490); -ACE_EXPLOSION_REFLECTION(60,500); -ACE_EXPLOSION_REFLECTION(62,10); -ACE_EXPLOSION_REFLECTION(62,20); -ACE_EXPLOSION_REFLECTION(62,30); -ACE_EXPLOSION_REFLECTION(62,40); -ACE_EXPLOSION_REFLECTION(62,50); -ACE_EXPLOSION_REFLECTION(62,60); -ACE_EXPLOSION_REFLECTION(62,70); -ACE_EXPLOSION_REFLECTION(62,80); -ACE_EXPLOSION_REFLECTION(62,90); -ACE_EXPLOSION_REFLECTION(62,100); -ACE_EXPLOSION_REFLECTION(62,110); -ACE_EXPLOSION_REFLECTION(62,120); -ACE_EXPLOSION_REFLECTION(62,130); -ACE_EXPLOSION_REFLECTION(62,140); -ACE_EXPLOSION_REFLECTION(62,150); -ACE_EXPLOSION_REFLECTION(62,160); -ACE_EXPLOSION_REFLECTION(62,170); -ACE_EXPLOSION_REFLECTION(62,180); -ACE_EXPLOSION_REFLECTION(62,190); -ACE_EXPLOSION_REFLECTION(62,200); -ACE_EXPLOSION_REFLECTION(62,210); -ACE_EXPLOSION_REFLECTION(62,220); -ACE_EXPLOSION_REFLECTION(62,230); -ACE_EXPLOSION_REFLECTION(62,240); -ACE_EXPLOSION_REFLECTION(62,250); -ACE_EXPLOSION_REFLECTION(62,260); -ACE_EXPLOSION_REFLECTION(62,270); -ACE_EXPLOSION_REFLECTION(62,280); -ACE_EXPLOSION_REFLECTION(62,290); -ACE_EXPLOSION_REFLECTION(62,300); -ACE_EXPLOSION_REFLECTION(62,310); -ACE_EXPLOSION_REFLECTION(62,320); -ACE_EXPLOSION_REFLECTION(62,330); -ACE_EXPLOSION_REFLECTION(62,340); -ACE_EXPLOSION_REFLECTION(62,350); -ACE_EXPLOSION_REFLECTION(62,360); -ACE_EXPLOSION_REFLECTION(62,370); -ACE_EXPLOSION_REFLECTION(62,380); -ACE_EXPLOSION_REFLECTION(62,390); -ACE_EXPLOSION_REFLECTION(62,400); -ACE_EXPLOSION_REFLECTION(62,410); -ACE_EXPLOSION_REFLECTION(62,420); -ACE_EXPLOSION_REFLECTION(62,430); -ACE_EXPLOSION_REFLECTION(62,440); -ACE_EXPLOSION_REFLECTION(62,450); -ACE_EXPLOSION_REFLECTION(62,460); -ACE_EXPLOSION_REFLECTION(62,470); -ACE_EXPLOSION_REFLECTION(62,480); -ACE_EXPLOSION_REFLECTION(62,490); -ACE_EXPLOSION_REFLECTION(62,500); -ACE_EXPLOSION_REFLECTION(64,10); -ACE_EXPLOSION_REFLECTION(64,20); -ACE_EXPLOSION_REFLECTION(64,30); -ACE_EXPLOSION_REFLECTION(64,40); -ACE_EXPLOSION_REFLECTION(64,50); -ACE_EXPLOSION_REFLECTION(64,60); -ACE_EXPLOSION_REFLECTION(64,70); -ACE_EXPLOSION_REFLECTION(64,80); -ACE_EXPLOSION_REFLECTION(64,90); -ACE_EXPLOSION_REFLECTION(64,100); -ACE_EXPLOSION_REFLECTION(64,110); -ACE_EXPLOSION_REFLECTION(64,120); -ACE_EXPLOSION_REFLECTION(64,130); -ACE_EXPLOSION_REFLECTION(64,140); -ACE_EXPLOSION_REFLECTION(64,150); -ACE_EXPLOSION_REFLECTION(64,160); -ACE_EXPLOSION_REFLECTION(64,170); -ACE_EXPLOSION_REFLECTION(64,180); -ACE_EXPLOSION_REFLECTION(64,190); -ACE_EXPLOSION_REFLECTION(64,200); -ACE_EXPLOSION_REFLECTION(64,210); -ACE_EXPLOSION_REFLECTION(64,220); -ACE_EXPLOSION_REFLECTION(64,230); -ACE_EXPLOSION_REFLECTION(64,240); -ACE_EXPLOSION_REFLECTION(64,250); -ACE_EXPLOSION_REFLECTION(64,260); -ACE_EXPLOSION_REFLECTION(64,270); -ACE_EXPLOSION_REFLECTION(64,280); -ACE_EXPLOSION_REFLECTION(64,290); -ACE_EXPLOSION_REFLECTION(64,300); -ACE_EXPLOSION_REFLECTION(64,310); -ACE_EXPLOSION_REFLECTION(64,320); -ACE_EXPLOSION_REFLECTION(64,330); -ACE_EXPLOSION_REFLECTION(64,340); -ACE_EXPLOSION_REFLECTION(64,350); -ACE_EXPLOSION_REFLECTION(64,360); -ACE_EXPLOSION_REFLECTION(64,370); -ACE_EXPLOSION_REFLECTION(64,380); -ACE_EXPLOSION_REFLECTION(64,390); -ACE_EXPLOSION_REFLECTION(64,400); -ACE_EXPLOSION_REFLECTION(64,410); -ACE_EXPLOSION_REFLECTION(64,420); -ACE_EXPLOSION_REFLECTION(64,430); -ACE_EXPLOSION_REFLECTION(64,440); -ACE_EXPLOSION_REFLECTION(64,450); -ACE_EXPLOSION_REFLECTION(64,460); -ACE_EXPLOSION_REFLECTION(64,470); -ACE_EXPLOSION_REFLECTION(64,480); -ACE_EXPLOSION_REFLECTION(64,490); -ACE_EXPLOSION_REFLECTION(64,500); -ACE_EXPLOSION_REFLECTION(66,10); -ACE_EXPLOSION_REFLECTION(66,20); -ACE_EXPLOSION_REFLECTION(66,30); -ACE_EXPLOSION_REFLECTION(66,40); -ACE_EXPLOSION_REFLECTION(66,50); -ACE_EXPLOSION_REFLECTION(66,60); -ACE_EXPLOSION_REFLECTION(66,70); -ACE_EXPLOSION_REFLECTION(66,80); -ACE_EXPLOSION_REFLECTION(66,90); -ACE_EXPLOSION_REFLECTION(66,100); -ACE_EXPLOSION_REFLECTION(66,110); -ACE_EXPLOSION_REFLECTION(66,120); -ACE_EXPLOSION_REFLECTION(66,130); -ACE_EXPLOSION_REFLECTION(66,140); -ACE_EXPLOSION_REFLECTION(66,150); -ACE_EXPLOSION_REFLECTION(66,160); -ACE_EXPLOSION_REFLECTION(66,170); -ACE_EXPLOSION_REFLECTION(66,180); -ACE_EXPLOSION_REFLECTION(66,190); -ACE_EXPLOSION_REFLECTION(66,200); -ACE_EXPLOSION_REFLECTION(66,210); -ACE_EXPLOSION_REFLECTION(66,220); -ACE_EXPLOSION_REFLECTION(66,230); -ACE_EXPLOSION_REFLECTION(66,240); -ACE_EXPLOSION_REFLECTION(66,250); -ACE_EXPLOSION_REFLECTION(66,260); -ACE_EXPLOSION_REFLECTION(66,270); -ACE_EXPLOSION_REFLECTION(66,280); -ACE_EXPLOSION_REFLECTION(66,290); -ACE_EXPLOSION_REFLECTION(66,300); -ACE_EXPLOSION_REFLECTION(66,310); -ACE_EXPLOSION_REFLECTION(66,320); -ACE_EXPLOSION_REFLECTION(66,330); -ACE_EXPLOSION_REFLECTION(66,340); -ACE_EXPLOSION_REFLECTION(66,350); -ACE_EXPLOSION_REFLECTION(66,360); -ACE_EXPLOSION_REFLECTION(66,370); -ACE_EXPLOSION_REFLECTION(66,380); -ACE_EXPLOSION_REFLECTION(66,390); -ACE_EXPLOSION_REFLECTION(66,400); -ACE_EXPLOSION_REFLECTION(66,410); -ACE_EXPLOSION_REFLECTION(66,420); -ACE_EXPLOSION_REFLECTION(66,430); -ACE_EXPLOSION_REFLECTION(66,440); -ACE_EXPLOSION_REFLECTION(66,450); -ACE_EXPLOSION_REFLECTION(66,460); -ACE_EXPLOSION_REFLECTION(66,470); -ACE_EXPLOSION_REFLECTION(66,480); -ACE_EXPLOSION_REFLECTION(66,490); -ACE_EXPLOSION_REFLECTION(66,500); -ACE_EXPLOSION_REFLECTION(68,10); -ACE_EXPLOSION_REFLECTION(68,20); -ACE_EXPLOSION_REFLECTION(68,30); -ACE_EXPLOSION_REFLECTION(68,40); -ACE_EXPLOSION_REFLECTION(68,50); -ACE_EXPLOSION_REFLECTION(68,60); -ACE_EXPLOSION_REFLECTION(68,70); -ACE_EXPLOSION_REFLECTION(68,80); -ACE_EXPLOSION_REFLECTION(68,90); -ACE_EXPLOSION_REFLECTION(68,100); -ACE_EXPLOSION_REFLECTION(68,110); -ACE_EXPLOSION_REFLECTION(68,120); -ACE_EXPLOSION_REFLECTION(68,130); -ACE_EXPLOSION_REFLECTION(68,140); -ACE_EXPLOSION_REFLECTION(68,150); -ACE_EXPLOSION_REFLECTION(68,160); -ACE_EXPLOSION_REFLECTION(68,170); -ACE_EXPLOSION_REFLECTION(68,180); -ACE_EXPLOSION_REFLECTION(68,190); -ACE_EXPLOSION_REFLECTION(68,200); -ACE_EXPLOSION_REFLECTION(68,210); -ACE_EXPLOSION_REFLECTION(68,220); -ACE_EXPLOSION_REFLECTION(68,230); -ACE_EXPLOSION_REFLECTION(68,240); -ACE_EXPLOSION_REFLECTION(68,250); -ACE_EXPLOSION_REFLECTION(68,260); -ACE_EXPLOSION_REFLECTION(68,270); -ACE_EXPLOSION_REFLECTION(68,280); -ACE_EXPLOSION_REFLECTION(68,290); -ACE_EXPLOSION_REFLECTION(68,300); -ACE_EXPLOSION_REFLECTION(68,310); -ACE_EXPLOSION_REFLECTION(68,320); -ACE_EXPLOSION_REFLECTION(68,330); -ACE_EXPLOSION_REFLECTION(68,340); -ACE_EXPLOSION_REFLECTION(68,350); -ACE_EXPLOSION_REFLECTION(68,360); -ACE_EXPLOSION_REFLECTION(68,370); -ACE_EXPLOSION_REFLECTION(68,380); -ACE_EXPLOSION_REFLECTION(68,390); -ACE_EXPLOSION_REFLECTION(68,400); -ACE_EXPLOSION_REFLECTION(68,410); -ACE_EXPLOSION_REFLECTION(68,420); -ACE_EXPLOSION_REFLECTION(68,430); -ACE_EXPLOSION_REFLECTION(68,440); -ACE_EXPLOSION_REFLECTION(68,450); -ACE_EXPLOSION_REFLECTION(68,460); -ACE_EXPLOSION_REFLECTION(68,470); -ACE_EXPLOSION_REFLECTION(68,480); -ACE_EXPLOSION_REFLECTION(68,490); -ACE_EXPLOSION_REFLECTION(68,500); -ACE_EXPLOSION_REFLECTION(70,10); -ACE_EXPLOSION_REFLECTION(70,20); -ACE_EXPLOSION_REFLECTION(70,30); -ACE_EXPLOSION_REFLECTION(70,40); -ACE_EXPLOSION_REFLECTION(70,50); -ACE_EXPLOSION_REFLECTION(70,60); -ACE_EXPLOSION_REFLECTION(70,70); -ACE_EXPLOSION_REFLECTION(70,80); -ACE_EXPLOSION_REFLECTION(70,90); -ACE_EXPLOSION_REFLECTION(70,100); -ACE_EXPLOSION_REFLECTION(70,110); -ACE_EXPLOSION_REFLECTION(70,120); -ACE_EXPLOSION_REFLECTION(70,130); -ACE_EXPLOSION_REFLECTION(70,140); -ACE_EXPLOSION_REFLECTION(70,150); -ACE_EXPLOSION_REFLECTION(70,160); -ACE_EXPLOSION_REFLECTION(70,170); -ACE_EXPLOSION_REFLECTION(70,180); -ACE_EXPLOSION_REFLECTION(70,190); -ACE_EXPLOSION_REFLECTION(70,200); -ACE_EXPLOSION_REFLECTION(70,210); -ACE_EXPLOSION_REFLECTION(70,220); -ACE_EXPLOSION_REFLECTION(70,230); -ACE_EXPLOSION_REFLECTION(70,240); -ACE_EXPLOSION_REFLECTION(70,250); -ACE_EXPLOSION_REFLECTION(70,260); -ACE_EXPLOSION_REFLECTION(70,270); -ACE_EXPLOSION_REFLECTION(70,280); -ACE_EXPLOSION_REFLECTION(70,290); -ACE_EXPLOSION_REFLECTION(70,300); -ACE_EXPLOSION_REFLECTION(70,310); -ACE_EXPLOSION_REFLECTION(70,320); -ACE_EXPLOSION_REFLECTION(70,330); -ACE_EXPLOSION_REFLECTION(70,340); -ACE_EXPLOSION_REFLECTION(70,350); -ACE_EXPLOSION_REFLECTION(70,360); -ACE_EXPLOSION_REFLECTION(70,370); -ACE_EXPLOSION_REFLECTION(70,380); -ACE_EXPLOSION_REFLECTION(70,390); -ACE_EXPLOSION_REFLECTION(70,400); -ACE_EXPLOSION_REFLECTION(70,410); -ACE_EXPLOSION_REFLECTION(70,420); -ACE_EXPLOSION_REFLECTION(70,430); -ACE_EXPLOSION_REFLECTION(70,440); -ACE_EXPLOSION_REFLECTION(70,450); -ACE_EXPLOSION_REFLECTION(70,460); -ACE_EXPLOSION_REFLECTION(70,470); -ACE_EXPLOSION_REFLECTION(70,480); -ACE_EXPLOSION_REFLECTION(70,490); -ACE_EXPLOSION_REFLECTION(70,500); -ACE_EXPLOSION_REFLECTION(72,10); -ACE_EXPLOSION_REFLECTION(72,20); -ACE_EXPLOSION_REFLECTION(72,30); -ACE_EXPLOSION_REFLECTION(72,40); -ACE_EXPLOSION_REFLECTION(72,50); -ACE_EXPLOSION_REFLECTION(72,60); -ACE_EXPLOSION_REFLECTION(72,70); -ACE_EXPLOSION_REFLECTION(72,80); -ACE_EXPLOSION_REFLECTION(72,90); -ACE_EXPLOSION_REFLECTION(72,100); -ACE_EXPLOSION_REFLECTION(72,110); -ACE_EXPLOSION_REFLECTION(72,120); -ACE_EXPLOSION_REFLECTION(72,130); -ACE_EXPLOSION_REFLECTION(72,140); -ACE_EXPLOSION_REFLECTION(72,150); -ACE_EXPLOSION_REFLECTION(72,160); -ACE_EXPLOSION_REFLECTION(72,170); -ACE_EXPLOSION_REFLECTION(72,180); -ACE_EXPLOSION_REFLECTION(72,190); -ACE_EXPLOSION_REFLECTION(72,200); -ACE_EXPLOSION_REFLECTION(72,210); -ACE_EXPLOSION_REFLECTION(72,220); -ACE_EXPLOSION_REFLECTION(72,230); -ACE_EXPLOSION_REFLECTION(72,240); -ACE_EXPLOSION_REFLECTION(72,250); -ACE_EXPLOSION_REFLECTION(72,260); -ACE_EXPLOSION_REFLECTION(72,270); -ACE_EXPLOSION_REFLECTION(72,280); -ACE_EXPLOSION_REFLECTION(72,290); -ACE_EXPLOSION_REFLECTION(72,300); -ACE_EXPLOSION_REFLECTION(72,310); -ACE_EXPLOSION_REFLECTION(72,320); -ACE_EXPLOSION_REFLECTION(72,330); -ACE_EXPLOSION_REFLECTION(72,340); -ACE_EXPLOSION_REFLECTION(72,350); -ACE_EXPLOSION_REFLECTION(72,360); -ACE_EXPLOSION_REFLECTION(72,370); -ACE_EXPLOSION_REFLECTION(72,380); -ACE_EXPLOSION_REFLECTION(72,390); -ACE_EXPLOSION_REFLECTION(72,400); -ACE_EXPLOSION_REFLECTION(72,410); -ACE_EXPLOSION_REFLECTION(72,420); -ACE_EXPLOSION_REFLECTION(72,430); -ACE_EXPLOSION_REFLECTION(72,440); -ACE_EXPLOSION_REFLECTION(72,450); -ACE_EXPLOSION_REFLECTION(72,460); -ACE_EXPLOSION_REFLECTION(72,470); -ACE_EXPLOSION_REFLECTION(72,480); -ACE_EXPLOSION_REFLECTION(72,490); -ACE_EXPLOSION_REFLECTION(72,500); -ACE_EXPLOSION_REFLECTION(74,10); -ACE_EXPLOSION_REFLECTION(74,20); -ACE_EXPLOSION_REFLECTION(74,30); -ACE_EXPLOSION_REFLECTION(74,40); -ACE_EXPLOSION_REFLECTION(74,50); -ACE_EXPLOSION_REFLECTION(74,60); -ACE_EXPLOSION_REFLECTION(74,70); -ACE_EXPLOSION_REFLECTION(74,80); -ACE_EXPLOSION_REFLECTION(74,90); -ACE_EXPLOSION_REFLECTION(74,100); -ACE_EXPLOSION_REFLECTION(74,110); -ACE_EXPLOSION_REFLECTION(74,120); -ACE_EXPLOSION_REFLECTION(74,130); -ACE_EXPLOSION_REFLECTION(74,140); -ACE_EXPLOSION_REFLECTION(74,150); -ACE_EXPLOSION_REFLECTION(74,160); -ACE_EXPLOSION_REFLECTION(74,170); -ACE_EXPLOSION_REFLECTION(74,180); -ACE_EXPLOSION_REFLECTION(74,190); -ACE_EXPLOSION_REFLECTION(74,200); -ACE_EXPLOSION_REFLECTION(74,210); -ACE_EXPLOSION_REFLECTION(74,220); -ACE_EXPLOSION_REFLECTION(74,230); -ACE_EXPLOSION_REFLECTION(74,240); -ACE_EXPLOSION_REFLECTION(74,250); -ACE_EXPLOSION_REFLECTION(74,260); -ACE_EXPLOSION_REFLECTION(74,270); -ACE_EXPLOSION_REFLECTION(74,280); -ACE_EXPLOSION_REFLECTION(74,290); -ACE_EXPLOSION_REFLECTION(74,300); -ACE_EXPLOSION_REFLECTION(74,310); -ACE_EXPLOSION_REFLECTION(74,320); -ACE_EXPLOSION_REFLECTION(74,330); -ACE_EXPLOSION_REFLECTION(74,340); -ACE_EXPLOSION_REFLECTION(74,350); -ACE_EXPLOSION_REFLECTION(74,360); -ACE_EXPLOSION_REFLECTION(74,370); -ACE_EXPLOSION_REFLECTION(74,380); -ACE_EXPLOSION_REFLECTION(74,390); -ACE_EXPLOSION_REFLECTION(74,400); -ACE_EXPLOSION_REFLECTION(74,410); -ACE_EXPLOSION_REFLECTION(74,420); -ACE_EXPLOSION_REFLECTION(74,430); -ACE_EXPLOSION_REFLECTION(74,440); -ACE_EXPLOSION_REFLECTION(74,450); -ACE_EXPLOSION_REFLECTION(74,460); -ACE_EXPLOSION_REFLECTION(74,470); -ACE_EXPLOSION_REFLECTION(74,480); -ACE_EXPLOSION_REFLECTION(74,490); -ACE_EXPLOSION_REFLECTION(74,500); -ACE_EXPLOSION_REFLECTION(76,10); -ACE_EXPLOSION_REFLECTION(76,20); -ACE_EXPLOSION_REFLECTION(76,30); -ACE_EXPLOSION_REFLECTION(76,40); -ACE_EXPLOSION_REFLECTION(76,50); -ACE_EXPLOSION_REFLECTION(76,60); -ACE_EXPLOSION_REFLECTION(76,70); -ACE_EXPLOSION_REFLECTION(76,80); -ACE_EXPLOSION_REFLECTION(76,90); -ACE_EXPLOSION_REFLECTION(76,100); -ACE_EXPLOSION_REFLECTION(76,110); -ACE_EXPLOSION_REFLECTION(76,120); -ACE_EXPLOSION_REFLECTION(76,130); -ACE_EXPLOSION_REFLECTION(76,140); -ACE_EXPLOSION_REFLECTION(76,150); -ACE_EXPLOSION_REFLECTION(76,160); -ACE_EXPLOSION_REFLECTION(76,170); -ACE_EXPLOSION_REFLECTION(76,180); -ACE_EXPLOSION_REFLECTION(76,190); -ACE_EXPLOSION_REFLECTION(76,200); -ACE_EXPLOSION_REFLECTION(76,210); -ACE_EXPLOSION_REFLECTION(76,220); -ACE_EXPLOSION_REFLECTION(76,230); -ACE_EXPLOSION_REFLECTION(76,240); -ACE_EXPLOSION_REFLECTION(76,250); -ACE_EXPLOSION_REFLECTION(76,260); -ACE_EXPLOSION_REFLECTION(76,270); -ACE_EXPLOSION_REFLECTION(76,280); -ACE_EXPLOSION_REFLECTION(76,290); -ACE_EXPLOSION_REFLECTION(76,300); -ACE_EXPLOSION_REFLECTION(76,310); -ACE_EXPLOSION_REFLECTION(76,320); -ACE_EXPLOSION_REFLECTION(76,330); -ACE_EXPLOSION_REFLECTION(76,340); -ACE_EXPLOSION_REFLECTION(76,350); -ACE_EXPLOSION_REFLECTION(76,360); -ACE_EXPLOSION_REFLECTION(76,370); -ACE_EXPLOSION_REFLECTION(76,380); -ACE_EXPLOSION_REFLECTION(76,390); -ACE_EXPLOSION_REFLECTION(76,400); -ACE_EXPLOSION_REFLECTION(76,410); -ACE_EXPLOSION_REFLECTION(76,420); -ACE_EXPLOSION_REFLECTION(76,430); -ACE_EXPLOSION_REFLECTION(76,440); -ACE_EXPLOSION_REFLECTION(76,450); -ACE_EXPLOSION_REFLECTION(76,460); -ACE_EXPLOSION_REFLECTION(76,470); -ACE_EXPLOSION_REFLECTION(76,480); -ACE_EXPLOSION_REFLECTION(76,490); -ACE_EXPLOSION_REFLECTION(76,500); -ACE_EXPLOSION_REFLECTION(78,10); -ACE_EXPLOSION_REFLECTION(78,20); -ACE_EXPLOSION_REFLECTION(78,30); -ACE_EXPLOSION_REFLECTION(78,40); -ACE_EXPLOSION_REFLECTION(78,50); -ACE_EXPLOSION_REFLECTION(78,60); -ACE_EXPLOSION_REFLECTION(78,70); -ACE_EXPLOSION_REFLECTION(78,80); -ACE_EXPLOSION_REFLECTION(78,90); -ACE_EXPLOSION_REFLECTION(78,100); -ACE_EXPLOSION_REFLECTION(78,110); -ACE_EXPLOSION_REFLECTION(78,120); -ACE_EXPLOSION_REFLECTION(78,130); -ACE_EXPLOSION_REFLECTION(78,140); -ACE_EXPLOSION_REFLECTION(78,150); -ACE_EXPLOSION_REFLECTION(78,160); -ACE_EXPLOSION_REFLECTION(78,170); -ACE_EXPLOSION_REFLECTION(78,180); -ACE_EXPLOSION_REFLECTION(78,190); -ACE_EXPLOSION_REFLECTION(78,200); -ACE_EXPLOSION_REFLECTION(78,210); -ACE_EXPLOSION_REFLECTION(78,220); -ACE_EXPLOSION_REFLECTION(78,230); -ACE_EXPLOSION_REFLECTION(78,240); -ACE_EXPLOSION_REFLECTION(78,250); -ACE_EXPLOSION_REFLECTION(78,260); -ACE_EXPLOSION_REFLECTION(78,270); -ACE_EXPLOSION_REFLECTION(78,280); -ACE_EXPLOSION_REFLECTION(78,290); -ACE_EXPLOSION_REFLECTION(78,300); -ACE_EXPLOSION_REFLECTION(78,310); -ACE_EXPLOSION_REFLECTION(78,320); -ACE_EXPLOSION_REFLECTION(78,330); -ACE_EXPLOSION_REFLECTION(78,340); -ACE_EXPLOSION_REFLECTION(78,350); -ACE_EXPLOSION_REFLECTION(78,360); -ACE_EXPLOSION_REFLECTION(78,370); -ACE_EXPLOSION_REFLECTION(78,380); -ACE_EXPLOSION_REFLECTION(78,390); -ACE_EXPLOSION_REFLECTION(78,400); -ACE_EXPLOSION_REFLECTION(78,410); -ACE_EXPLOSION_REFLECTION(78,420); -ACE_EXPLOSION_REFLECTION(78,430); -ACE_EXPLOSION_REFLECTION(78,440); -ACE_EXPLOSION_REFLECTION(78,450); -ACE_EXPLOSION_REFLECTION(78,460); -ACE_EXPLOSION_REFLECTION(78,470); -ACE_EXPLOSION_REFLECTION(78,480); -ACE_EXPLOSION_REFLECTION(78,490); -ACE_EXPLOSION_REFLECTION(78,500); -ACE_EXPLOSION_REFLECTION(80,10); -ACE_EXPLOSION_REFLECTION(80,20); -ACE_EXPLOSION_REFLECTION(80,30); -ACE_EXPLOSION_REFLECTION(80,40); -ACE_EXPLOSION_REFLECTION(80,50); -ACE_EXPLOSION_REFLECTION(80,60); -ACE_EXPLOSION_REFLECTION(80,70); -ACE_EXPLOSION_REFLECTION(80,80); -ACE_EXPLOSION_REFLECTION(80,90); -ACE_EXPLOSION_REFLECTION(80,100); -ACE_EXPLOSION_REFLECTION(80,110); -ACE_EXPLOSION_REFLECTION(80,120); -ACE_EXPLOSION_REFLECTION(80,130); -ACE_EXPLOSION_REFLECTION(80,140); -ACE_EXPLOSION_REFLECTION(80,150); -ACE_EXPLOSION_REFLECTION(80,160); -ACE_EXPLOSION_REFLECTION(80,170); -ACE_EXPLOSION_REFLECTION(80,180); -ACE_EXPLOSION_REFLECTION(80,190); -ACE_EXPLOSION_REFLECTION(80,200); -ACE_EXPLOSION_REFLECTION(80,210); -ACE_EXPLOSION_REFLECTION(80,220); -ACE_EXPLOSION_REFLECTION(80,230); -ACE_EXPLOSION_REFLECTION(80,240); -ACE_EXPLOSION_REFLECTION(80,250); -ACE_EXPLOSION_REFLECTION(80,260); -ACE_EXPLOSION_REFLECTION(80,270); -ACE_EXPLOSION_REFLECTION(80,280); -ACE_EXPLOSION_REFLECTION(80,290); -ACE_EXPLOSION_REFLECTION(80,300); -ACE_EXPLOSION_REFLECTION(80,310); -ACE_EXPLOSION_REFLECTION(80,320); -ACE_EXPLOSION_REFLECTION(80,330); -ACE_EXPLOSION_REFLECTION(80,340); -ACE_EXPLOSION_REFLECTION(80,350); -ACE_EXPLOSION_REFLECTION(80,360); -ACE_EXPLOSION_REFLECTION(80,370); -ACE_EXPLOSION_REFLECTION(80,380); -ACE_EXPLOSION_REFLECTION(80,390); -ACE_EXPLOSION_REFLECTION(80,400); -ACE_EXPLOSION_REFLECTION(80,410); -ACE_EXPLOSION_REFLECTION(80,420); -ACE_EXPLOSION_REFLECTION(80,430); -ACE_EXPLOSION_REFLECTION(80,440); -ACE_EXPLOSION_REFLECTION(80,450); -ACE_EXPLOSION_REFLECTION(80,460); -ACE_EXPLOSION_REFLECTION(80,470); -ACE_EXPLOSION_REFLECTION(80,480); -ACE_EXPLOSION_REFLECTION(80,490); -ACE_EXPLOSION_REFLECTION(80,500); -ACE_EXPLOSION_REFLECTION(82,10); -ACE_EXPLOSION_REFLECTION(82,20); -ACE_EXPLOSION_REFLECTION(82,30); -ACE_EXPLOSION_REFLECTION(82,40); -ACE_EXPLOSION_REFLECTION(82,50); -ACE_EXPLOSION_REFLECTION(82,60); -ACE_EXPLOSION_REFLECTION(82,70); -ACE_EXPLOSION_REFLECTION(82,80); -ACE_EXPLOSION_REFLECTION(82,90); -ACE_EXPLOSION_REFLECTION(82,100); -ACE_EXPLOSION_REFLECTION(82,110); -ACE_EXPLOSION_REFLECTION(82,120); -ACE_EXPLOSION_REFLECTION(82,130); -ACE_EXPLOSION_REFLECTION(82,140); -ACE_EXPLOSION_REFLECTION(82,150); -ACE_EXPLOSION_REFLECTION(82,160); -ACE_EXPLOSION_REFLECTION(82,170); -ACE_EXPLOSION_REFLECTION(82,180); -ACE_EXPLOSION_REFLECTION(82,190); -ACE_EXPLOSION_REFLECTION(82,200); -ACE_EXPLOSION_REFLECTION(82,210); -ACE_EXPLOSION_REFLECTION(82,220); -ACE_EXPLOSION_REFLECTION(82,230); -ACE_EXPLOSION_REFLECTION(82,240); -ACE_EXPLOSION_REFLECTION(82,250); -ACE_EXPLOSION_REFLECTION(82,260); -ACE_EXPLOSION_REFLECTION(82,270); -ACE_EXPLOSION_REFLECTION(82,280); -ACE_EXPLOSION_REFLECTION(82,290); -ACE_EXPLOSION_REFLECTION(82,300); -ACE_EXPLOSION_REFLECTION(82,310); -ACE_EXPLOSION_REFLECTION(82,320); -ACE_EXPLOSION_REFLECTION(82,330); -ACE_EXPLOSION_REFLECTION(82,340); -ACE_EXPLOSION_REFLECTION(82,350); -ACE_EXPLOSION_REFLECTION(82,360); -ACE_EXPLOSION_REFLECTION(82,370); -ACE_EXPLOSION_REFLECTION(82,380); -ACE_EXPLOSION_REFLECTION(82,390); -ACE_EXPLOSION_REFLECTION(82,400); -ACE_EXPLOSION_REFLECTION(82,410); -ACE_EXPLOSION_REFLECTION(82,420); -ACE_EXPLOSION_REFLECTION(82,430); -ACE_EXPLOSION_REFLECTION(82,440); -ACE_EXPLOSION_REFLECTION(82,450); -ACE_EXPLOSION_REFLECTION(82,460); -ACE_EXPLOSION_REFLECTION(82,470); -ACE_EXPLOSION_REFLECTION(82,480); -ACE_EXPLOSION_REFLECTION(82,490); -ACE_EXPLOSION_REFLECTION(82,500); -ACE_EXPLOSION_REFLECTION(84,10); -ACE_EXPLOSION_REFLECTION(84,20); -ACE_EXPLOSION_REFLECTION(84,30); -ACE_EXPLOSION_REFLECTION(84,40); -ACE_EXPLOSION_REFLECTION(84,50); -ACE_EXPLOSION_REFLECTION(84,60); -ACE_EXPLOSION_REFLECTION(84,70); -ACE_EXPLOSION_REFLECTION(84,80); -ACE_EXPLOSION_REFLECTION(84,90); -ACE_EXPLOSION_REFLECTION(84,100); -ACE_EXPLOSION_REFLECTION(84,110); -ACE_EXPLOSION_REFLECTION(84,120); -ACE_EXPLOSION_REFLECTION(84,130); -ACE_EXPLOSION_REFLECTION(84,140); -ACE_EXPLOSION_REFLECTION(84,150); -ACE_EXPLOSION_REFLECTION(84,160); -ACE_EXPLOSION_REFLECTION(84,170); -ACE_EXPLOSION_REFLECTION(84,180); -ACE_EXPLOSION_REFLECTION(84,190); -ACE_EXPLOSION_REFLECTION(84,200); -ACE_EXPLOSION_REFLECTION(84,210); -ACE_EXPLOSION_REFLECTION(84,220); -ACE_EXPLOSION_REFLECTION(84,230); -ACE_EXPLOSION_REFLECTION(84,240); -ACE_EXPLOSION_REFLECTION(84,250); -ACE_EXPLOSION_REFLECTION(84,260); -ACE_EXPLOSION_REFLECTION(84,270); -ACE_EXPLOSION_REFLECTION(84,280); -ACE_EXPLOSION_REFLECTION(84,290); -ACE_EXPLOSION_REFLECTION(84,300); -ACE_EXPLOSION_REFLECTION(84,310); -ACE_EXPLOSION_REFLECTION(84,320); -ACE_EXPLOSION_REFLECTION(84,330); -ACE_EXPLOSION_REFLECTION(84,340); -ACE_EXPLOSION_REFLECTION(84,350); -ACE_EXPLOSION_REFLECTION(84,360); -ACE_EXPLOSION_REFLECTION(84,370); -ACE_EXPLOSION_REFLECTION(84,380); -ACE_EXPLOSION_REFLECTION(84,390); -ACE_EXPLOSION_REFLECTION(84,400); -ACE_EXPLOSION_REFLECTION(84,410); -ACE_EXPLOSION_REFLECTION(84,420); -ACE_EXPLOSION_REFLECTION(84,430); -ACE_EXPLOSION_REFLECTION(84,440); -ACE_EXPLOSION_REFLECTION(84,450); -ACE_EXPLOSION_REFLECTION(84,460); -ACE_EXPLOSION_REFLECTION(84,470); -ACE_EXPLOSION_REFLECTION(84,480); -ACE_EXPLOSION_REFLECTION(84,490); -ACE_EXPLOSION_REFLECTION(84,500); -ACE_EXPLOSION_REFLECTION(86,10); -ACE_EXPLOSION_REFLECTION(86,20); -ACE_EXPLOSION_REFLECTION(86,30); -ACE_EXPLOSION_REFLECTION(86,40); -ACE_EXPLOSION_REFLECTION(86,50); -ACE_EXPLOSION_REFLECTION(86,60); -ACE_EXPLOSION_REFLECTION(86,70); -ACE_EXPLOSION_REFLECTION(86,80); -ACE_EXPLOSION_REFLECTION(86,90); -ACE_EXPLOSION_REFLECTION(86,100); -ACE_EXPLOSION_REFLECTION(86,110); -ACE_EXPLOSION_REFLECTION(86,120); -ACE_EXPLOSION_REFLECTION(86,130); -ACE_EXPLOSION_REFLECTION(86,140); -ACE_EXPLOSION_REFLECTION(86,150); -ACE_EXPLOSION_REFLECTION(86,160); -ACE_EXPLOSION_REFLECTION(86,170); -ACE_EXPLOSION_REFLECTION(86,180); -ACE_EXPLOSION_REFLECTION(86,190); -ACE_EXPLOSION_REFLECTION(86,200); -ACE_EXPLOSION_REFLECTION(86,210); -ACE_EXPLOSION_REFLECTION(86,220); -ACE_EXPLOSION_REFLECTION(86,230); -ACE_EXPLOSION_REFLECTION(86,240); -ACE_EXPLOSION_REFLECTION(86,250); -ACE_EXPLOSION_REFLECTION(86,260); -ACE_EXPLOSION_REFLECTION(86,270); -ACE_EXPLOSION_REFLECTION(86,280); -ACE_EXPLOSION_REFLECTION(86,290); -ACE_EXPLOSION_REFLECTION(86,300); -ACE_EXPLOSION_REFLECTION(86,310); -ACE_EXPLOSION_REFLECTION(86,320); -ACE_EXPLOSION_REFLECTION(86,330); -ACE_EXPLOSION_REFLECTION(86,340); -ACE_EXPLOSION_REFLECTION(86,350); -ACE_EXPLOSION_REFLECTION(86,360); -ACE_EXPLOSION_REFLECTION(86,370); -ACE_EXPLOSION_REFLECTION(86,380); -ACE_EXPLOSION_REFLECTION(86,390); -ACE_EXPLOSION_REFLECTION(86,400); -ACE_EXPLOSION_REFLECTION(86,410); -ACE_EXPLOSION_REFLECTION(86,420); -ACE_EXPLOSION_REFLECTION(86,430); -ACE_EXPLOSION_REFLECTION(86,440); -ACE_EXPLOSION_REFLECTION(86,450); -ACE_EXPLOSION_REFLECTION(86,460); -ACE_EXPLOSION_REFLECTION(86,470); -ACE_EXPLOSION_REFLECTION(86,480); -ACE_EXPLOSION_REFLECTION(86,490); -ACE_EXPLOSION_REFLECTION(86,500); -ACE_EXPLOSION_REFLECTION(88,10); -ACE_EXPLOSION_REFLECTION(88,20); -ACE_EXPLOSION_REFLECTION(88,30); -ACE_EXPLOSION_REFLECTION(88,40); -ACE_EXPLOSION_REFLECTION(88,50); -ACE_EXPLOSION_REFLECTION(88,60); -ACE_EXPLOSION_REFLECTION(88,70); -ACE_EXPLOSION_REFLECTION(88,80); -ACE_EXPLOSION_REFLECTION(88,90); -ACE_EXPLOSION_REFLECTION(88,100); -ACE_EXPLOSION_REFLECTION(88,110); -ACE_EXPLOSION_REFLECTION(88,120); -ACE_EXPLOSION_REFLECTION(88,130); -ACE_EXPLOSION_REFLECTION(88,140); -ACE_EXPLOSION_REFLECTION(88,150); -ACE_EXPLOSION_REFLECTION(88,160); -ACE_EXPLOSION_REFLECTION(88,170); -ACE_EXPLOSION_REFLECTION(88,180); -ACE_EXPLOSION_REFLECTION(88,190); -ACE_EXPLOSION_REFLECTION(88,200); -ACE_EXPLOSION_REFLECTION(88,210); -ACE_EXPLOSION_REFLECTION(88,220); -ACE_EXPLOSION_REFLECTION(88,230); -ACE_EXPLOSION_REFLECTION(88,240); -ACE_EXPLOSION_REFLECTION(88,250); -ACE_EXPLOSION_REFLECTION(88,260); -ACE_EXPLOSION_REFLECTION(88,270); -ACE_EXPLOSION_REFLECTION(88,280); -ACE_EXPLOSION_REFLECTION(88,290); -ACE_EXPLOSION_REFLECTION(88,300); -ACE_EXPLOSION_REFLECTION(88,310); -ACE_EXPLOSION_REFLECTION(88,320); -ACE_EXPLOSION_REFLECTION(88,330); -ACE_EXPLOSION_REFLECTION(88,340); -ACE_EXPLOSION_REFLECTION(88,350); -ACE_EXPLOSION_REFLECTION(88,360); -ACE_EXPLOSION_REFLECTION(88,370); -ACE_EXPLOSION_REFLECTION(88,380); -ACE_EXPLOSION_REFLECTION(88,390); -ACE_EXPLOSION_REFLECTION(88,400); -ACE_EXPLOSION_REFLECTION(88,410); -ACE_EXPLOSION_REFLECTION(88,420); -ACE_EXPLOSION_REFLECTION(88,430); -ACE_EXPLOSION_REFLECTION(88,440); -ACE_EXPLOSION_REFLECTION(88,450); -ACE_EXPLOSION_REFLECTION(88,460); -ACE_EXPLOSION_REFLECTION(88,470); -ACE_EXPLOSION_REFLECTION(88,480); -ACE_EXPLOSION_REFLECTION(88,490); -ACE_EXPLOSION_REFLECTION(88,500); -ACE_EXPLOSION_REFLECTION(90,10); -ACE_EXPLOSION_REFLECTION(90,20); -ACE_EXPLOSION_REFLECTION(90,30); -ACE_EXPLOSION_REFLECTION(90,40); -ACE_EXPLOSION_REFLECTION(90,50); -ACE_EXPLOSION_REFLECTION(90,60); -ACE_EXPLOSION_REFLECTION(90,70); -ACE_EXPLOSION_REFLECTION(90,80); -ACE_EXPLOSION_REFLECTION(90,90); -ACE_EXPLOSION_REFLECTION(90,100); -ACE_EXPLOSION_REFLECTION(90,110); -ACE_EXPLOSION_REFLECTION(90,120); -ACE_EXPLOSION_REFLECTION(90,130); -ACE_EXPLOSION_REFLECTION(90,140); -ACE_EXPLOSION_REFLECTION(90,150); -ACE_EXPLOSION_REFLECTION(90,160); -ACE_EXPLOSION_REFLECTION(90,170); -ACE_EXPLOSION_REFLECTION(90,180); -ACE_EXPLOSION_REFLECTION(90,190); -ACE_EXPLOSION_REFLECTION(90,200); -ACE_EXPLOSION_REFLECTION(90,210); -ACE_EXPLOSION_REFLECTION(90,220); -ACE_EXPLOSION_REFLECTION(90,230); -ACE_EXPLOSION_REFLECTION(90,240); -ACE_EXPLOSION_REFLECTION(90,250); -ACE_EXPLOSION_REFLECTION(90,260); -ACE_EXPLOSION_REFLECTION(90,270); -ACE_EXPLOSION_REFLECTION(90,280); -ACE_EXPLOSION_REFLECTION(90,290); -ACE_EXPLOSION_REFLECTION(90,300); -ACE_EXPLOSION_REFLECTION(90,310); -ACE_EXPLOSION_REFLECTION(90,320); -ACE_EXPLOSION_REFLECTION(90,330); -ACE_EXPLOSION_REFLECTION(90,340); -ACE_EXPLOSION_REFLECTION(90,350); -ACE_EXPLOSION_REFLECTION(90,360); -ACE_EXPLOSION_REFLECTION(90,370); -ACE_EXPLOSION_REFLECTION(90,380); -ACE_EXPLOSION_REFLECTION(90,390); -ACE_EXPLOSION_REFLECTION(90,400); -ACE_EXPLOSION_REFLECTION(90,410); -ACE_EXPLOSION_REFLECTION(90,420); -ACE_EXPLOSION_REFLECTION(90,430); -ACE_EXPLOSION_REFLECTION(90,440); -ACE_EXPLOSION_REFLECTION(90,450); -ACE_EXPLOSION_REFLECTION(90,460); -ACE_EXPLOSION_REFLECTION(90,470); -ACE_EXPLOSION_REFLECTION(90,480); -ACE_EXPLOSION_REFLECTION(90,490); -ACE_EXPLOSION_REFLECTION(90,500); -ACE_EXPLOSION_REFLECTION(92,10); -ACE_EXPLOSION_REFLECTION(92,20); -ACE_EXPLOSION_REFLECTION(92,30); -ACE_EXPLOSION_REFLECTION(92,40); -ACE_EXPLOSION_REFLECTION(92,50); -ACE_EXPLOSION_REFLECTION(92,60); -ACE_EXPLOSION_REFLECTION(92,70); -ACE_EXPLOSION_REFLECTION(92,80); -ACE_EXPLOSION_REFLECTION(92,90); -ACE_EXPLOSION_REFLECTION(92,100); -ACE_EXPLOSION_REFLECTION(92,110); -ACE_EXPLOSION_REFLECTION(92,120); -ACE_EXPLOSION_REFLECTION(92,130); -ACE_EXPLOSION_REFLECTION(92,140); -ACE_EXPLOSION_REFLECTION(92,150); -ACE_EXPLOSION_REFLECTION(92,160); -ACE_EXPLOSION_REFLECTION(92,170); -ACE_EXPLOSION_REFLECTION(92,180); -ACE_EXPLOSION_REFLECTION(92,190); -ACE_EXPLOSION_REFLECTION(92,200); -ACE_EXPLOSION_REFLECTION(92,210); -ACE_EXPLOSION_REFLECTION(92,220); -ACE_EXPLOSION_REFLECTION(92,230); -ACE_EXPLOSION_REFLECTION(92,240); -ACE_EXPLOSION_REFLECTION(92,250); -ACE_EXPLOSION_REFLECTION(92,260); -ACE_EXPLOSION_REFLECTION(92,270); -ACE_EXPLOSION_REFLECTION(92,280); -ACE_EXPLOSION_REFLECTION(92,290); -ACE_EXPLOSION_REFLECTION(92,300); -ACE_EXPLOSION_REFLECTION(92,310); -ACE_EXPLOSION_REFLECTION(92,320); -ACE_EXPLOSION_REFLECTION(92,330); -ACE_EXPLOSION_REFLECTION(92,340); -ACE_EXPLOSION_REFLECTION(92,350); -ACE_EXPLOSION_REFLECTION(92,360); -ACE_EXPLOSION_REFLECTION(92,370); -ACE_EXPLOSION_REFLECTION(92,380); -ACE_EXPLOSION_REFLECTION(92,390); -ACE_EXPLOSION_REFLECTION(92,400); -ACE_EXPLOSION_REFLECTION(92,410); -ACE_EXPLOSION_REFLECTION(92,420); -ACE_EXPLOSION_REFLECTION(92,430); -ACE_EXPLOSION_REFLECTION(92,440); -ACE_EXPLOSION_REFLECTION(92,450); -ACE_EXPLOSION_REFLECTION(92,460); -ACE_EXPLOSION_REFLECTION(92,470); -ACE_EXPLOSION_REFLECTION(92,480); -ACE_EXPLOSION_REFLECTION(92,490); -ACE_EXPLOSION_REFLECTION(92,500); -ACE_EXPLOSION_REFLECTION(94,10); -ACE_EXPLOSION_REFLECTION(94,20); -ACE_EXPLOSION_REFLECTION(94,30); -ACE_EXPLOSION_REFLECTION(94,40); -ACE_EXPLOSION_REFLECTION(94,50); -ACE_EXPLOSION_REFLECTION(94,60); -ACE_EXPLOSION_REFLECTION(94,70); -ACE_EXPLOSION_REFLECTION(94,80); -ACE_EXPLOSION_REFLECTION(94,90); -ACE_EXPLOSION_REFLECTION(94,100); -ACE_EXPLOSION_REFLECTION(94,110); -ACE_EXPLOSION_REFLECTION(94,120); -ACE_EXPLOSION_REFLECTION(94,130); -ACE_EXPLOSION_REFLECTION(94,140); -ACE_EXPLOSION_REFLECTION(94,150); -ACE_EXPLOSION_REFLECTION(94,160); -ACE_EXPLOSION_REFLECTION(94,170); -ACE_EXPLOSION_REFLECTION(94,180); -ACE_EXPLOSION_REFLECTION(94,190); -ACE_EXPLOSION_REFLECTION(94,200); -ACE_EXPLOSION_REFLECTION(94,210); -ACE_EXPLOSION_REFLECTION(94,220); -ACE_EXPLOSION_REFLECTION(94,230); -ACE_EXPLOSION_REFLECTION(94,240); -ACE_EXPLOSION_REFLECTION(94,250); -ACE_EXPLOSION_REFLECTION(94,260); -ACE_EXPLOSION_REFLECTION(94,270); -ACE_EXPLOSION_REFLECTION(94,280); -ACE_EXPLOSION_REFLECTION(94,290); -ACE_EXPLOSION_REFLECTION(94,300); -ACE_EXPLOSION_REFLECTION(94,310); -ACE_EXPLOSION_REFLECTION(94,320); -ACE_EXPLOSION_REFLECTION(94,330); -ACE_EXPLOSION_REFLECTION(94,340); -ACE_EXPLOSION_REFLECTION(94,350); -ACE_EXPLOSION_REFLECTION(94,360); -ACE_EXPLOSION_REFLECTION(94,370); -ACE_EXPLOSION_REFLECTION(94,380); -ACE_EXPLOSION_REFLECTION(94,390); -ACE_EXPLOSION_REFLECTION(94,400); -ACE_EXPLOSION_REFLECTION(94,410); -ACE_EXPLOSION_REFLECTION(94,420); -ACE_EXPLOSION_REFLECTION(94,430); -ACE_EXPLOSION_REFLECTION(94,440); -ACE_EXPLOSION_REFLECTION(94,450); -ACE_EXPLOSION_REFLECTION(94,460); -ACE_EXPLOSION_REFLECTION(94,470); -ACE_EXPLOSION_REFLECTION(94,480); -ACE_EXPLOSION_REFLECTION(94,490); -ACE_EXPLOSION_REFLECTION(94,500); -ACE_EXPLOSION_REFLECTION(96,10); -ACE_EXPLOSION_REFLECTION(96,20); -ACE_EXPLOSION_REFLECTION(96,30); -ACE_EXPLOSION_REFLECTION(96,40); -ACE_EXPLOSION_REFLECTION(96,50); -ACE_EXPLOSION_REFLECTION(96,60); -ACE_EXPLOSION_REFLECTION(96,70); -ACE_EXPLOSION_REFLECTION(96,80); -ACE_EXPLOSION_REFLECTION(96,90); -ACE_EXPLOSION_REFLECTION(96,100); -ACE_EXPLOSION_REFLECTION(96,110); -ACE_EXPLOSION_REFLECTION(96,120); -ACE_EXPLOSION_REFLECTION(96,130); -ACE_EXPLOSION_REFLECTION(96,140); -ACE_EXPLOSION_REFLECTION(96,150); -ACE_EXPLOSION_REFLECTION(96,160); -ACE_EXPLOSION_REFLECTION(96,170); -ACE_EXPLOSION_REFLECTION(96,180); -ACE_EXPLOSION_REFLECTION(96,190); -ACE_EXPLOSION_REFLECTION(96,200); -ACE_EXPLOSION_REFLECTION(96,210); -ACE_EXPLOSION_REFLECTION(96,220); -ACE_EXPLOSION_REFLECTION(96,230); -ACE_EXPLOSION_REFLECTION(96,240); -ACE_EXPLOSION_REFLECTION(96,250); -ACE_EXPLOSION_REFLECTION(96,260); -ACE_EXPLOSION_REFLECTION(96,270); -ACE_EXPLOSION_REFLECTION(96,280); -ACE_EXPLOSION_REFLECTION(96,290); -ACE_EXPLOSION_REFLECTION(96,300); -ACE_EXPLOSION_REFLECTION(96,310); -ACE_EXPLOSION_REFLECTION(96,320); -ACE_EXPLOSION_REFLECTION(96,330); -ACE_EXPLOSION_REFLECTION(96,340); -ACE_EXPLOSION_REFLECTION(96,350); -ACE_EXPLOSION_REFLECTION(96,360); -ACE_EXPLOSION_REFLECTION(96,370); -ACE_EXPLOSION_REFLECTION(96,380); -ACE_EXPLOSION_REFLECTION(96,390); -ACE_EXPLOSION_REFLECTION(96,400); -ACE_EXPLOSION_REFLECTION(96,410); -ACE_EXPLOSION_REFLECTION(96,420); -ACE_EXPLOSION_REFLECTION(96,430); -ACE_EXPLOSION_REFLECTION(96,440); -ACE_EXPLOSION_REFLECTION(96,450); -ACE_EXPLOSION_REFLECTION(96,460); -ACE_EXPLOSION_REFLECTION(96,470); -ACE_EXPLOSION_REFLECTION(96,480); -ACE_EXPLOSION_REFLECTION(96,490); -ACE_EXPLOSION_REFLECTION(96,500); -ACE_EXPLOSION_REFLECTION(98,10); -ACE_EXPLOSION_REFLECTION(98,20); -ACE_EXPLOSION_REFLECTION(98,30); -ACE_EXPLOSION_REFLECTION(98,40); -ACE_EXPLOSION_REFLECTION(98,50); -ACE_EXPLOSION_REFLECTION(98,60); -ACE_EXPLOSION_REFLECTION(98,70); -ACE_EXPLOSION_REFLECTION(98,80); -ACE_EXPLOSION_REFLECTION(98,90); -ACE_EXPLOSION_REFLECTION(98,100); -ACE_EXPLOSION_REFLECTION(98,110); -ACE_EXPLOSION_REFLECTION(98,120); -ACE_EXPLOSION_REFLECTION(98,130); -ACE_EXPLOSION_REFLECTION(98,140); -ACE_EXPLOSION_REFLECTION(98,150); -ACE_EXPLOSION_REFLECTION(98,160); -ACE_EXPLOSION_REFLECTION(98,170); -ACE_EXPLOSION_REFLECTION(98,180); -ACE_EXPLOSION_REFLECTION(98,190); -ACE_EXPLOSION_REFLECTION(98,200); -ACE_EXPLOSION_REFLECTION(98,210); -ACE_EXPLOSION_REFLECTION(98,220); -ACE_EXPLOSION_REFLECTION(98,230); -ACE_EXPLOSION_REFLECTION(98,240); -ACE_EXPLOSION_REFLECTION(98,250); -ACE_EXPLOSION_REFLECTION(98,260); -ACE_EXPLOSION_REFLECTION(98,270); -ACE_EXPLOSION_REFLECTION(98,280); -ACE_EXPLOSION_REFLECTION(98,290); -ACE_EXPLOSION_REFLECTION(98,300); -ACE_EXPLOSION_REFLECTION(98,310); -ACE_EXPLOSION_REFLECTION(98,320); -ACE_EXPLOSION_REFLECTION(98,330); -ACE_EXPLOSION_REFLECTION(98,340); -ACE_EXPLOSION_REFLECTION(98,350); -ACE_EXPLOSION_REFLECTION(98,360); -ACE_EXPLOSION_REFLECTION(98,370); -ACE_EXPLOSION_REFLECTION(98,380); -ACE_EXPLOSION_REFLECTION(98,390); -ACE_EXPLOSION_REFLECTION(98,400); -ACE_EXPLOSION_REFLECTION(98,410); -ACE_EXPLOSION_REFLECTION(98,420); -ACE_EXPLOSION_REFLECTION(98,430); -ACE_EXPLOSION_REFLECTION(98,440); -ACE_EXPLOSION_REFLECTION(98,450); -ACE_EXPLOSION_REFLECTION(98,460); -ACE_EXPLOSION_REFLECTION(98,470); -ACE_EXPLOSION_REFLECTION(98,480); -ACE_EXPLOSION_REFLECTION(98,490); -ACE_EXPLOSION_REFLECTION(98,500); -ACE_EXPLOSION_REFLECTION(100,10); -ACE_EXPLOSION_REFLECTION(100,20); -ACE_EXPLOSION_REFLECTION(100,30); -ACE_EXPLOSION_REFLECTION(100,40); -ACE_EXPLOSION_REFLECTION(100,50); -ACE_EXPLOSION_REFLECTION(100,60); -ACE_EXPLOSION_REFLECTION(100,70); -ACE_EXPLOSION_REFLECTION(100,80); -ACE_EXPLOSION_REFLECTION(100,90); -ACE_EXPLOSION_REFLECTION(100,100); -ACE_EXPLOSION_REFLECTION(100,110); -ACE_EXPLOSION_REFLECTION(100,120); -ACE_EXPLOSION_REFLECTION(100,130); -ACE_EXPLOSION_REFLECTION(100,140); -ACE_EXPLOSION_REFLECTION(100,150); -ACE_EXPLOSION_REFLECTION(100,160); -ACE_EXPLOSION_REFLECTION(100,170); -ACE_EXPLOSION_REFLECTION(100,180); -ACE_EXPLOSION_REFLECTION(100,190); -ACE_EXPLOSION_REFLECTION(100,200); -ACE_EXPLOSION_REFLECTION(100,210); -ACE_EXPLOSION_REFLECTION(100,220); -ACE_EXPLOSION_REFLECTION(100,230); -ACE_EXPLOSION_REFLECTION(100,240); -ACE_EXPLOSION_REFLECTION(100,250); -ACE_EXPLOSION_REFLECTION(100,260); -ACE_EXPLOSION_REFLECTION(100,270); -ACE_EXPLOSION_REFLECTION(100,280); -ACE_EXPLOSION_REFLECTION(100,290); -ACE_EXPLOSION_REFLECTION(100,300); -ACE_EXPLOSION_REFLECTION(100,310); -ACE_EXPLOSION_REFLECTION(100,320); -ACE_EXPLOSION_REFLECTION(100,330); -ACE_EXPLOSION_REFLECTION(100,340); -ACE_EXPLOSION_REFLECTION(100,350); -ACE_EXPLOSION_REFLECTION(100,360); -ACE_EXPLOSION_REFLECTION(100,370); -ACE_EXPLOSION_REFLECTION(100,380); -ACE_EXPLOSION_REFLECTION(100,390); -ACE_EXPLOSION_REFLECTION(100,400); -ACE_EXPLOSION_REFLECTION(100,410); -ACE_EXPLOSION_REFLECTION(100,420); -ACE_EXPLOSION_REFLECTION(100,430); -ACE_EXPLOSION_REFLECTION(100,440); -ACE_EXPLOSION_REFLECTION(100,450); -ACE_EXPLOSION_REFLECTION(100,460); -ACE_EXPLOSION_REFLECTION(100,470); -ACE_EXPLOSION_REFLECTION(100,480); -ACE_EXPLOSION_REFLECTION(100,490); -ACE_EXPLOSION_REFLECTION(100,500); - +ACE_EXPLOSION_RANGE(2); +ACE_EXPLOSION_RANGE(4); +ACE_EXPLOSION_RANGE(6); +ACE_EXPLOSION_RANGE(8); +ACE_EXPLOSION_RANGE(10); +ACE_EXPLOSION_RANGE(12); +ACE_EXPLOSION_RANGE(14); +ACE_EXPLOSION_RANGE(16); +ACE_EXPLOSION_RANGE(18); +ACE_EXPLOSION_RANGE(20); +ACE_EXPLOSION_RANGE(22); +ACE_EXPLOSION_RANGE(24); +ACE_EXPLOSION_RANGE(26); +ACE_EXPLOSION_RANGE(28); +ACE_EXPLOSION_RANGE(30); +ACE_EXPLOSION_RANGE(32); +ACE_EXPLOSION_RANGE(34); +ACE_EXPLOSION_RANGE(36); +ACE_EXPLOSION_RANGE(38); +ACE_EXPLOSION_RANGE(40); +ACE_EXPLOSION_RANGE(42); +ACE_EXPLOSION_RANGE(44); +ACE_EXPLOSION_RANGE(46); +ACE_EXPLOSION_RANGE(48); +ACE_EXPLOSION_RANGE(50); +ACE_EXPLOSION_RANGE(52); +ACE_EXPLOSION_RANGE(54); +ACE_EXPLOSION_RANGE(56); +ACE_EXPLOSION_RANGE(58); +ACE_EXPLOSION_RANGE(60); +ACE_EXPLOSION_RANGE(62); +ACE_EXPLOSION_RANGE(64); +ACE_EXPLOSION_RANGE(66); +ACE_EXPLOSION_RANGE(68); +ACE_EXPLOSION_RANGE(70); +ACE_EXPLOSION_RANGE(72); +ACE_EXPLOSION_RANGE(74); +ACE_EXPLOSION_RANGE(76); +ACE_EXPLOSION_RANGE(78); +ACE_EXPLOSION_RANGE(80); +ACE_EXPLOSION_RANGE(82); +ACE_EXPLOSION_RANGE(84); +ACE_EXPLOSION_RANGE(86); +ACE_EXPLOSION_RANGE(88); +ACE_EXPLOSION_RANGE(90); +ACE_EXPLOSION_RANGE(92); +ACE_EXPLOSION_RANGE(94); +ACE_EXPLOSION_RANGE(96); +ACE_EXPLOSION_RANGE(98); +ACE_EXPLOSION_RANGE(100); diff --git a/addons/gestures/$PBOPREFIX$ b/addons/gestures/$PBOPREFIX$ new file mode 100644 index 0000000000..47459a13ac --- /dev/null +++ b/addons/gestures/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\gestures \ No newline at end of file diff --git a/addons/gestures/CfgEventHandlers.hpp b/addons/gestures/CfgEventHandlers.hpp new file mode 100644 index 0000000000..7b003bbe8c --- /dev/null +++ b/addons/gestures/CfgEventHandlers.hpp @@ -0,0 +1,11 @@ +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE( call COMPILE_FILE(XEH_preInit) ); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_postInit)); + }; +}; diff --git a/addons/gestures/CfgVehicles.hpp b/addons/gestures/CfgVehicles.hpp new file mode 100644 index 0000000000..019cffdb45 --- /dev/null +++ b/addons/gestures/CfgVehicles.hpp @@ -0,0 +1,145 @@ +class CfgVehicles { + + class Man; + class CAManBase: Man { + class ACE_SelfActions { + class ADDON { + displayName = CSTRING(Gestures); + condition = QUOTE(canStand _target && GVAR(ReloadMutex)); + statement = ""; + showDisabled = 1; + priority = 3.5; + icon = PATHTOF(UI\gestures_ca.paa); + + class GVAR(Advance) { + displayName = CSTRING(BIgestureAdvance); + condition = QUOTE(canStand _target); + statement = QUOTE(_target playActionNow 'gestureAdvance';); + showDisabled = 1; + priority = 1.9; + }; + class GVAR(Go) { + displayName = CSTRING(BIgestureGo); + condition = QUOTE(canStand _target); + statement = QUOTE(_target playActionNow ([ARR_2('gestureGo','gestureGoB')] select floor random 2);); + showDisabled = 1; + priority = 1.8; + }; + class GVAR(Follow) { + displayName = CSTRING(BIgestureFollow); + condition = QUOTE(canStand _target); + statement = QUOTE(_target playActionNow 'gestureFollow';); + showDisabled = 1; + priority = 1.7; + }; + class GVAR(Up) { + displayName = CSTRING(BIgestureUp); + condition = QUOTE(canStand _target); + statement = QUOTE(_target playActionNow 'gestureUp';); + showDisabled = 1; + priority = 1.5; + }; + class GVAR(CeaseFire) { + displayName = CSTRING(BIgestureCeaseFire); + condition = QUOTE(canStand _target); + statement = QUOTE(_target playActionNow 'gestureCeaseFire';); + showDisabled = 1; + priority = 1.3; + }; + class GVAR(Freeze) { + displayName = CSTRING(BIgestureFreeze); + condition = QUOTE(canStand _target); + statement = QUOTE(_target playActionNow 'gestureFreeze';); + showDisabled = 1; + priority = 1.2; + }; + class GVAR(Forward) { + displayName = CSTRING(forward); + condition = QUOTE(canStand _target && GVAR(ReloadMutex)); + statement = QUOTE(QUOTE(QGVAR(forward)) call FUNC(playSignal)); + showDisabled = 1; + priority = 1.9; + }; + class GVAR(Regroup) { + displayName = CSTRING(regroup); + condition = QUOTE(canStand _target && GVAR(ReloadMutex)); + statement = QUOTE(QUOTE(QGVAR(regroup)) call FUNC(playSignal)); + showDisabled = 1; + priority = 1.8; + }; + class GVAR(Stop) { + displayName = CSTRING(stop); + condition = QUOTE(canStand _target && GVAR(ReloadMutex)); + statement = QUOTE(QUOTE(QGVAR(stop)) call FUNC(playSignal)); + showDisabled = 1; + priority = 1.7; + }; + class GVAR(Cover) { + displayName = CSTRING(cover); + condition = QUOTE(canStand _target && GVAR(ReloadMutex)); + statement = QUOTE(QUOTE(QGVAR(cover)) call FUNC(playSignal)); + showDisabled = 1; + priority = 1.6; + }; + class GVAR(Point) { + displayName = CSTRING(point); + condition = QUOTE(canStand _target && GVAR(ReloadMutex)); + statement = QUOTE(QUOTE(QGVAR(point)) call FUNC(playSignal)); + showDisabled = 1; + priority = 1.5; + }; + class GVAR(Engage) { + displayName = CSTRING(engage); + condition = QUOTE(canStand _target && GVAR(ReloadMutex)); + statement = QUOTE(QUOTE(QGVAR(engage)) call FUNC(playSignal)); + showDisabled = 1; + priority = 1.4; + }; + class GVAR(Hold) { + displayName = CSTRING(hold); + condition = QUOTE(canStand _target && GVAR(ReloadMutex)); + statement = QUOTE(QUOTE(QGVAR(hold)) call FUNC(playSignal)); + showDisabled = 1; + priority = 1.3; + }; + class GVAR(Warning) { + displayName = CSTRING(warning); + condition = QUOTE(canStand _target && GVAR(ReloadMutex)); + statement = QUOTE(QUOTE(QGVAR(warning)) call FUNC(playSignal)); + showDisabled = 1; + priority = 1.2; + }; + /* + class class GVAR(Yes) { + displayName = ECSTRING(common,Yes); + condition = QUOTE(canStand _target); + statement = QUOTE(_target playActionNow ([ARR_2('gestureYes','gestureNod')] select floor random 2);); + showDisabled = 1; + priority = 1.1; + hotkey = "8"; + }; + + class class GVAR(No) { + displayName = ECSTRING(common,No); + condition = QUOTE(canStand _target); + statement = QUOTE(_target playActionNow 'gestureNo';); + showDisabled = 1; + priority = 1.0; + hotkey = "9"; + }; + + class class GVAR(Hi) { + displayName = CSTRING(Gestures_Hi); + condition = QUOTE(canStand _target); + statement = QUOTE(_target playActionNow ([ARR_3('gestureHi','gestureHiB','gestureHiC')] select floor random 3);); + showDisabled = 1; + priority = 0.9; + hotkey = "0"; + }; + */ + + }; + + }; + }; +}; diff --git a/addons/interaction/UI/gestures_ca.paa b/addons/gestures/UI/gestures_ca.paa similarity index 100% rename from addons/interaction/UI/gestures_ca.paa rename to addons/gestures/UI/gestures_ca.paa diff --git a/addons/gestures/XEH_postInit.sqf b/addons/gestures/XEH_postInit.sqf new file mode 100644 index 0000000000..fec57ab111 --- /dev/null +++ b/addons/gestures/XEH_postInit.sqf @@ -0,0 +1,38 @@ +#include "script_component.hpp" + +if (!hasInterface) exitWith {}; + +#include "key.sqf" + +// reload mutex, you can't play signal while reloading +GVAR(ReloadMutex) = true; + +// Event for main display to be loaded: +["mainDisplayLoaded", { + // handle reloading + (findDisplay 46) displayAddEventHandler ["KeyDown", { + if ((_this select 1) in actionKeys "ReloadMagazine") then { + if ((isNull ACE_player) || {!alive ACE_player}) exitWith {false}; + private _weapon = currentWeapon ACE_player; + + if (_weapon != "") then { + GVAR(ReloadMutex) = false; + + private _gesture = getText (configfile >> "CfgWeapons" >> _weapon >> "reloadAction"); + private _isLauncher = _weapon isKindOf ["Launcher", (configFile >> "CfgWeapons")]; + private _config = ["CfgGesturesMale", "CfgMovesMaleSdr"] select _isLauncher; + private _duration = getNumber (configfile >> _config >> "States" >> _gesture >> "speed"); + + if (_duration != 0) then { + _duration = if (_duration < 0) then { abs _duration } else { 1 / _duration }; + } else { + _duration = 3; + }; + + TRACE_2("Reloading, blocking gestures",_weapon,_duration); + [{GVAR(ReloadMutex) = true;}, [], _duration] call EFUNC(common,waitAndExecute); + }; + }; + false + }]; +}] call EFUNC(common,addEventHandler); diff --git a/addons/gestures/XEH_preInit.sqf b/addons/gestures/XEH_preInit.sqf new file mode 100644 index 0000000000..7fd2bb47f2 --- /dev/null +++ b/addons/gestures/XEH_preInit.sqf @@ -0,0 +1,7 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP(playSignal); + +ADDON = true; diff --git a/addons/gestures/anim/ace_cover.rtm b/addons/gestures/anim/ace_cover.rtm new file mode 100644 index 0000000000..ce15001076 Binary files /dev/null and b/addons/gestures/anim/ace_cover.rtm differ diff --git a/addons/gestures/anim/ace_cover_stand_lowered.rtm b/addons/gestures/anim/ace_cover_stand_lowered.rtm new file mode 100644 index 0000000000..b6838579ba Binary files /dev/null and b/addons/gestures/anim/ace_cover_stand_lowered.rtm differ diff --git a/addons/gestures/anim/ace_engage.rtm b/addons/gestures/anim/ace_engage.rtm new file mode 100644 index 0000000000..7dd573fb8f Binary files /dev/null and b/addons/gestures/anim/ace_engage.rtm differ diff --git a/addons/gestures/anim/ace_engage_stand_lowered.rtm b/addons/gestures/anim/ace_engage_stand_lowered.rtm new file mode 100644 index 0000000000..e4dee60e60 Binary files /dev/null and b/addons/gestures/anim/ace_engage_stand_lowered.rtm differ diff --git a/addons/gestures/anim/ace_forward.rtm b/addons/gestures/anim/ace_forward.rtm new file mode 100644 index 0000000000..3715c4f7fc Binary files /dev/null and b/addons/gestures/anim/ace_forward.rtm differ diff --git a/addons/gestures/anim/ace_forward_stand_lowered.rtm b/addons/gestures/anim/ace_forward_stand_lowered.rtm new file mode 100644 index 0000000000..40ca7465aa Binary files /dev/null and b/addons/gestures/anim/ace_forward_stand_lowered.rtm differ diff --git a/addons/gestures/anim/ace_hold.rtm b/addons/gestures/anim/ace_hold.rtm new file mode 100644 index 0000000000..e6fcb3e742 Binary files /dev/null and b/addons/gestures/anim/ace_hold.rtm differ diff --git a/addons/gestures/anim/ace_hold_stand_lowered.rtm b/addons/gestures/anim/ace_hold_stand_lowered.rtm new file mode 100644 index 0000000000..9ab8bca0cc Binary files /dev/null and b/addons/gestures/anim/ace_hold_stand_lowered.rtm differ diff --git a/addons/gestures/anim/ace_point.rtm b/addons/gestures/anim/ace_point.rtm new file mode 100644 index 0000000000..9e64cc630d Binary files /dev/null and b/addons/gestures/anim/ace_point.rtm differ diff --git a/addons/gestures/anim/ace_point_stand_lowered.rtm b/addons/gestures/anim/ace_point_stand_lowered.rtm new file mode 100644 index 0000000000..4d0fc5c1d2 Binary files /dev/null and b/addons/gestures/anim/ace_point_stand_lowered.rtm differ diff --git a/addons/gestures/anim/ace_regroup.rtm b/addons/gestures/anim/ace_regroup.rtm new file mode 100644 index 0000000000..2c40118e7c Binary files /dev/null and b/addons/gestures/anim/ace_regroup.rtm differ diff --git a/addons/gestures/anim/ace_regroup_stand_lowered.rtm b/addons/gestures/anim/ace_regroup_stand_lowered.rtm new file mode 100644 index 0000000000..9cd871f218 Binary files /dev/null and b/addons/gestures/anim/ace_regroup_stand_lowered.rtm differ diff --git a/addons/gestures/anim/ace_stop.rtm b/addons/gestures/anim/ace_stop.rtm new file mode 100644 index 0000000000..af1d8465be Binary files /dev/null and b/addons/gestures/anim/ace_stop.rtm differ diff --git a/addons/gestures/anim/ace_stop_stand_lowered.rtm b/addons/gestures/anim/ace_stop_stand_lowered.rtm new file mode 100644 index 0000000000..8b6d9270b6 Binary files /dev/null and b/addons/gestures/anim/ace_stop_stand_lowered.rtm differ diff --git a/addons/gestures/anim/ace_warning.rtm b/addons/gestures/anim/ace_warning.rtm new file mode 100644 index 0000000000..ff42d81727 Binary files /dev/null and b/addons/gestures/anim/ace_warning.rtm differ diff --git a/addons/gestures/anim/ace_warning_stand_lowered.rtm b/addons/gestures/anim/ace_warning_stand_lowered.rtm new file mode 100644 index 0000000000..9c9e86ec79 Binary files /dev/null and b/addons/gestures/anim/ace_warning_stand_lowered.rtm differ diff --git a/addons/gestures/cfgMovesBasic.hpp b/addons/gestures/cfgMovesBasic.hpp new file mode 100644 index 0000000000..a708787fd5 --- /dev/null +++ b/addons/gestures/cfgMovesBasic.hpp @@ -0,0 +1,200 @@ +class CfgMovesBasic { + class ManActions { + GVAR(forward) = QGVAR(forward); + GVAR(stop) = QGVAR(stop); + GVAR(cover) = QGVAR(cover); + GVAR(regroup) = QGVAR(regroup); + GVAR(engage) = QGVAR(engage); + GVAR(point) = QGVAR(point); + GVAR(hold) = QGVAR(hold); + GVAR(warning) = QGVAR(warningS); + + GVAR(forwardStandLowered) = QGVAR(forwardStandLowered); + GVAR(stopStandLowered) = QGVAR(stopStandLowered); + GVAR(coverStandLowered) = QGVAR(coverStandLowered); + GVAR(regroupStandLowered) = QGVAR(regroupStandLowered); + GVAR(engageStandLowered) = QGVAR(engageStandLowered); + GVAR(pointStandLowered) = QGVAR(pointStandLowered); + GVAR(holdStandLowered) = QGVAR(holdStandLowered); + GVAR(warningStandLowered) = QGVAR(warningStandLowered); + }; + + class Actions { + class NoActions: ManActions { + GVAR(forward)[] = {QGVAR(forward), "Gesture"}; + GVAR(stop)[] = {QGVAR(stop), "Gesture"}; + GVAR(cover)[] = {QGVAR(cover), "Gesture"}; + GVAR(regroup)[] = {QGVAR(regroup), "Gesture"}; + GVAR(engage)[] = {QGVAR(engage), "Gesture"}; + GVAR(point)[] = {QGVAR(point), "Gesture"}; + GVAR(hold)[] = {QGVAR(hold), "Gesture"}; + GVAR(warning)[] = {QGVAR(warning), "Gesture"}; + + GVAR(forwardStandLowered)[] = {QGVAR(forwardStandLowered), "Gesture"}; + GVAR(stopStandLowered)[] = {QGVAR(stopStandLowered), "Gesture"}; + GVAR(coverStandLowered)[] = {QGVAR(coverStandLowered), "Gesture"}; + GVAR(regroupStandLowered)[] = {QGVAR(regroupStandLowered), "Gesture"}; + GVAR(engageStandLowered)[] = {QGVAR(engageStandLowered), "Gesture"}; + GVAR(pointStandLowered)[] = {QGVAR(pointStandLowered), "Gesture"}; + GVAR(holdStandLowered)[] = {QGVAR(holdStandLowered), "Gesture"}; + GVAR(warningStandLowered)[] = {QGVAR(warningStandLowered), "Gesture"}; + }; + }; +}; + +class CfgGesturesMale { + class Default; + + class BlendAnims { + GVAR(LeftArm)[] = { + "LeftShoulder", 1, + "LeftArm", 1, + "LeftArmRoll", 1, + "LeftForeArm", 1, + "LeftForeArmRoll", 1, + "LeftHand", 1, + "LeftHandIndex1", 1, + "LeftHandIndex2", 1, + "LeftHandIndex3", 1, + "LeftHandMiddle1", 1, + "LeftHandMiddle2", 1, + "LeftHandMiddle3", 1, + "LeftHandPinky1", 1, + "LeftHandMiddle2", 1, + "LeftHandMiddle3", 1, + "LeftHandPinky1", 1, + "LeftHandPinky2", 1, + "LeftHandPinky3", 1, + "LeftHandRing", 1, + "LeftHandRing1", 1, + "LeftHandRing2", 1, + "LeftHandRing3", 1, + "LeftHandThumb1", 1, + "LeftHandThumb2", 1, + "LeftHandThumb3", 1 + }; + }; + + class States { + class GVAR(Base): Default { + actions = "NoActions"; + canPullTrigger = 0; + connectAs = ""; + connectFrom[] = {}; + connectTo[] = {}; + disableWeapons = 0; + enableBinocular = 1; + enableMissile = 1; + enableOptics = 0; + equivalentTo = ""; + file = "\A3\anims_f\Data\anim\Sdr\gst\GestureHi.rtm"; + forceAim = 0; + headBobMode = 0; + headBobStrength = 0; + interpolateFrom[] = {}; + interpolateTo[] = {}; + interpolateWith[] = {}; + interpolationRestart = 0; + interpolationSpeed = 6; + looped = 0; + mask = QGVAR(LeftArm); + minPlayTime = 0.5; + preload = 0; + ragdoll = 0; + relSpeedMax = 1; + relSpeedMin = 1; + showHandGun = 0; + showItemInHand = 0; + showItemInRightHand = 0; + showWeaponAim = 1; + soundEdge[] = {0.5,1}; + soundEnabled = 1; + soundOverride = ""; + speed = -2; + static = 0; + terminal = 0; + Walkcycles = 1; + weaponIK = 1; + + leftHandIKBeg = 1; + leftHandIKCurve[] = {0, 1, 0.1, 0, 0.8, 0, 1, 1}; + leftHandIKEnd = 1; + + rightHandIKBeg = 1; + rightHandIKCurve[] = {1}; + rightHandIKEnd = 1; + }; + + class GVAR(forward): GVAR(Base) { + file = QUOTE(PATHTOF(anim\ace_forward.rtm)); + speed = 1; + }; + + class GVAR(forwardStandLowered): GVAR(forward) { + file = QUOTE(PATHTOF(anim\ace_forward_stand_lowered.rtm)); + }; + + class GVAR(stop): GVAR(forward) { + file = QUOTE(PATHTOF(anim\ace_stop.rtm)); + speed = 0.6; + }; + + class GVAR(stopStandLowered): GVAR(stop) { + file = QUOTE(PATHTOF(anim\ace_stop_stand_lowered.rtm)); + }; + + class GVAR(cover): GVAR(forward) { + file = QUOTE(PATHTOF(anim\ace_cover.rtm)); + speed = 0.8; + }; + + class GVAR(coverStandLowered): GVAR(cover) { + file = QUOTE(PATHTOF(anim\ace_cover_stand_lowered.rtm)); + }; + + class GVAR(regroup): GVAR(forward) { + file = QUOTE(PATHTOF(anim\ace_regroup.rtm)); + speed = 0.8; + }; + + class GVAR(regroupStandLowered): GVAR(regroup) { + file = QUOTE(PATHTOF(anim\ace_regroup_stand_lowered.rtm)); + }; + + class GVAR(engage): GVAR(forward) { + file = QUOTE(PATHTOF(anim\ace_engage.rtm)); + speed = 0.9; + }; + + class GVAR(engageStandLowered): GVAR(engage) { + file = QUOTE(PATHTOF(anim\ace_engage_stand_lowered.rtm)); + }; + + class GVAR(point): GVAR(forward) { + file = QUOTE(PATHTOF(anim\ace_point.rtm)); + speed = 0.8; + }; + + class GVAR(pointStandLowered): GVAR(point) { + file = QUOTE(PATHTOF(anim\ace_point_stand_lowered.rtm)); + }; + + class GVAR(hold): GVAR(forward) { + file = QUOTE(PATHTOF(anim\ace_hold.rtm)); + speed = 0.8; + }; + + class GVAR(holdStandLowered): GVAR(hold) { + file = QUOTE(PATHTOF(anim\ace_hold_stand_lowered.rtm)); + }; + + class GVAR(warning): GVAR(forward) { + file = QUOTE(PATHTOF(anim\ace_warning.rtm)); + speed = 0.8; + }; + + class GVAR(warningStandLowered): GVAR(warning) { + file = QUOTE(PATHTOF(anim\ace_warning_stand_lowered.rtm)); + }; + }; +}; diff --git a/addons/gestures/config.cpp b/addons/gestures/config.cpp new file mode 100644 index 0000000000..6a3fa402d0 --- /dev/null +++ b/addons/gestures/config.cpp @@ -0,0 +1,17 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_interact_menu"}; + author[] = {"joko // Jonas", "Emperias", "Zigomarvin"}; + authorUrl = "https://github.com/commy2/"; + VERSION_CONFIG; + }; +}; + +#include "CfgMovesBasic.hpp" +#include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/gestures/functions/fnc_playSignal.sqf b/addons/gestures/functions/fnc_playSignal.sqf new file mode 100644 index 0000000000..b8a218f565 --- /dev/null +++ b/addons/gestures/functions/fnc_playSignal.sqf @@ -0,0 +1,33 @@ +/* + * Author: joko // Jonas, Emperias, Zigomarvin + * Detect if the player and play the Gesture Animation + * + * Arguments: + * Animation + * + * Return Value: + * + * + * Example: + * "GeniusAnimation" call ace_gestures_fnc_playSignal + * + * Public: No + */ +#include "script_component.hpp" + +TRACE_1("params",_this); + +if (!GVAR(ReloadMutex)) exitWith {false}; + +private _gesture = if (_this select [0,2] == "BI") then { + _this select [2] +} else { + if (((animationState ACE_player) select [0, 12]) in ["amovpercmstp", "amovpercmwlk", "amovpercmtac"] && weaponLowered ACE_player) then { + format ["%1StandLowered", _this] + } else { + _this + }; +}; + +ACE_player playAction _gesture; +true diff --git a/addons/gestures/functions/script_component.hpp b/addons/gestures/functions/script_component.hpp new file mode 100644 index 0000000000..53f6849ebc --- /dev/null +++ b/addons/gestures/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\gestures\script_component.hpp" diff --git a/addons/gestures/key.sqf b/addons/gestures/key.sqf new file mode 100644 index 0000000000..125463d4d1 --- /dev/null +++ b/addons/gestures/key.sqf @@ -0,0 +1,38 @@ +#include "\a3\editor_f\Data\Scripts\dikCodes.h" + +{ + _x params ["_currentName","_key"]; + + if (_currentName select [0,1] == "BI") then { + _currentName = _currentName select [2]; + }; + + private _code = (compile format [QUOTE(QUOTE(QGVAR(%1)) call FUNC(playSignal);), _currentName]); + + [ + "ACE3 Gestures", + _currentName, + localize format[LSTRING(%1), _currentName], + _code, + {false}, + [_key, [false, (_key != -1), false]], + false + ] call CBA_fnc_addKeybind; + + false +} count [ + ["stop", DIK_NUMPAD2], + ["cover", DIK_NUMPAD3], + ["forward", DIK_NUMPAD4], + ["regroup", DIK_NUMPAD5], + ["engage", DIK_NUMPAD6], + ["point", DIK_NUMPAD7], + ["hold", DIK_NUMPAD8], + ["warning", DIK_NUMPAD9], + ["BIgestureGo", -1], + ["BIgestureAdvance", -1], + ["BIgestureFollow", -1], + ["BIgestureUp", -1], + ["BIgestureFreeze", -1], + ["BIgestureCeaseFire", -1] +]; diff --git a/addons/gestures/script_component.hpp b/addons/gestures/script_component.hpp new file mode 100644 index 0000000000..06650c6ba8 --- /dev/null +++ b/addons/gestures/script_component.hpp @@ -0,0 +1,12 @@ +#define COMPONENT Gestures +#include "\z\ace\addons\main\script_mod.hpp" + +#ifdef DEBUG_ENABLED_GESTURES + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_GESTURES + #define DEBUG_SETTINGS DEBUG_SETTINGS_GESTURES +#endif + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/gestures/stringtable.xml b/addons/gestures/stringtable.xml new file mode 100644 index 0000000000..cc9b776cd1 --- /dev/null +++ b/addons/gestures/stringtable.xml @@ -0,0 +1,198 @@ + + + + + ACE Gestures + ACE Gesten + ACE Gesty + ACE Posunky + ACE Signaux + ACE Kézjelek + ACE Gesti + ACE Gestos + ACE Жесты + ACE Gestos + + + Gestures + Gesten + Gestos + Gesty + Posunky + Signaux + Жесты + Kézjelek + Gestos + Gesti + + + Advance + Vordringen + Avanzar + Naprzód + Postoupit + Avancer + Продвигаться + Előre + Avançar + Avanzare + + + Go + Los + Adelante + Szybko + Jít + Aller + Идти + Mozgás + Mover-se + Muoversi + + + Follow + Folgen + Seguirme + Za mną + Následovat + Suivre + Следовать + Utánam + Seguir + Seguire + + + Up + Aufstehen + Arriba + Do góry + Vztyk + Debout + Вверх + Fel + Acima + Alzarsi + + + Cease Fire + Feuer einstellen + Alto el fuego + Wstrzymać ogień + Zastavit palbu + Halte au feu + Прекратить огонь + Tüzet szüntess + Cessar Fogo + Cessare il Fuoco + + + Point + Zeigen + Señalar + Wskazać + Ukázat + Pointer + Точка + Mutat + Apontar + Puntare a + + + Freeze + Keine Bewegung + Alto + Stać + Stát + Halte + Замереть + Állj + Alto + Fermi + + + + Stop + Stop + Stop + Stop + + + + Cover + Deckung + Cubrirse + Do osłony + Krýt se + A couvert + Укрыться + Fedezékbe + Proteger-se + Copertura + + + + Rally up + Regroupement + Sammeln + Zbiórka + + + + Move forward + En avant + Vorwärts Bewegen + Naprzód + + + + Engage + Engager + Atak + + + + Point + Pointer + Zeigen + Wskaż + + + + Hold + Tenir + Anhalten + Wstrzymać + + + + Warning + Attention + Achtung + Uwaga + + + Hi + Hallo + Hola + Witaj + Ahoj + Salut + Привет + Helló + Olá + Ciao + + + Attack + Angreifen + Atacar + Do ataku + Zaútočit + Attaquer + Атаковать + Támadás + Atacar + Attaccare + + + \ No newline at end of file diff --git a/addons/goggles/XEH_postInit.sqf b/addons/goggles/XEH_postInit.sqf index 4958c8e02b..09a84ad151 100644 --- a/addons/goggles/XEH_postInit.sqf +++ b/addons/goggles/XEH_postInit.sqf @@ -95,7 +95,7 @@ GVAR(OldGlasses) = "#NULLSTRING"; }] call EFUNC(common,addEventHandler); // check goggles -local _fnc_checkGoggles = { +private _fnc_checkGoggles = { params ["_unit"]; if (GVAR(EffectsActive)) then { diff --git a/addons/goggles/config.cpp b/addons/goggles/config.cpp index 95b699eb1c..0812200a87 100644 --- a/addons/goggles/config.cpp +++ b/addons/goggles/config.cpp @@ -183,13 +183,13 @@ class CfgGlasses { ACE_Resistance = 1; ACE_Protection = 1; }; - class G_Bandanna_sport:G_Bandanna_blk { + class G_Bandanna_sport: G_Bandanna_shades { ACE_Color[] = {1,0,0}; ACE_TintAmount=COLOUR; ACE_Resistance = 1; ACE_Protection = 1; }; - class G_Bandanna_aviator:G_Bandanna_blk { + class G_Bandanna_aviator: G_Bandanna_shades { ACE_Color[] = {0,0,-1}; ACE_TintAmount=COLOUR; ACE_Resistance = 1; diff --git a/addons/goggles/functions/fnc_applyDirtEffect.sqf b/addons/goggles/functions/fnc_applyDirtEffect.sqf index b10ebc9668..c7ff386f9d 100644 --- a/addons/goggles/functions/fnc_applyDirtEffect.sqf +++ b/addons/goggles/functions/fnc_applyDirtEffect.sqf @@ -28,7 +28,7 @@ _effects set [DIRT, true]; SETGLASSES(_unit,_effects); if ([_unit] call FUNC(isGogglesVisible)) then { - local _dirtImage = getText (configFile >> "CfgGlasses" >> goggles _unit >> "ACE_OverlayDirt"); + private _dirtImage = getText (configFile >> "CfgGlasses" >> goggles _unit >> "ACE_OverlayDirt"); if (_dirtImage != "") then { GVAR(GogglesEffectsLayer) cutRsc ["RscACE_GogglesEffects", "PLAIN", 0.1, false]; diff --git a/addons/goggles/functions/fnc_applyDustEffect.sqf b/addons/goggles/functions/fnc_applyDustEffect.sqf index b052f3eae7..75f4853c01 100644 --- a/addons/goggles/functions/fnc_applyDustEffect.sqf +++ b/addons/goggles/functions/fnc_applyDustEffect.sqf @@ -54,7 +54,7 @@ GVAR(DustHandler) = [{ if (ACE_diagTime >= GETDUSTT(DTIME) + 3) then { SETDUST(DAMOUNT,CLAMP(GETDUSTT(DAMOUNT)-1,0,2)); - local _amount = 1 - (GETDUSTT(DAMOUNT) * 0.125); + private _amount = 1 - (GETDUSTT(DAMOUNT) * 0.125); if !(_unit getVariable ["ACE_EyesDamaged", false]) then { GVAR(PostProcessEyes) ppEffectAdjust [1, 1, 0, [0, 0, 0, 0], [_amount, _amount, _amount, _amount], [1, 1, 1, 0]]; diff --git a/addons/goggles/functions/fnc_applyRainEffect.sqf b/addons/goggles/functions/fnc_applyRainEffect.sqf index 7e1260a453..01b2894d87 100644 --- a/addons/goggles/functions/fnc_applyRainEffect.sqf +++ b/addons/goggles/functions/fnc_applyRainEffect.sqf @@ -27,7 +27,7 @@ _fnc_underCover = { if (vehicle _unit != _unit && {!isTurnedOut _unit}) exitWith {true}; // looking up and no roof over head - local _position = eyePos _unit; + private _position = eyePos _unit; positionCameraToWorld [0, 0, 1] select 2 < (positionCameraToWorld [0, 0, 0] select 2) - 0.4 || {(lineIntersects [_position, _position vectorAdd [0, 0, 15], _unit])} // return }; diff --git a/addons/goggles/functions/fnc_applyRotorWashEffect.sqf b/addons/goggles/functions/fnc_applyRotorWashEffect.sqf index 7dc088bc4e..bc8d0bafbf 100644 --- a/addons/goggles/functions/fnc_applyRotorWashEffect.sqf +++ b/addons/goggles/functions/fnc_applyRotorWashEffect.sqf @@ -86,7 +86,7 @@ if (_safe) exitWith {}; // apply rotor wash effect if (_rotorWash select 1 > 0) then { - local _scale = 0.7; + private _scale = 0.7; if (_rotorWash select 1 > 0) then { _scale = CLAMP(0.3 * (_rotorWash select 1),0.1,0.3); diff --git a/addons/goggles/functions/fnc_handleFired.sqf b/addons/goggles/functions/fnc_handleFired.sqf index 90260d07b3..793849822f 100644 --- a/addons/goggles/functions/fnc_handleFired.sqf +++ b/addons/goggles/functions/fnc_handleFired.sqf @@ -73,7 +73,7 @@ SETDUST(DTIME,ACE_diagTime); // apply dust effect if the amount of fired bullets is over the threshold if (GETDUSTT(DAMOUNT) < 2) then { - local _bulletsRequired = 100; + private _bulletsRequired = 100; if (isNumber (configFile >> _cloudType >> QGVAR(BulletCount))) then { _bulletsRequired = getNumber (configFile >> _cloudType >> QGVAR(BulletCount)); diff --git a/addons/goggles/functions/fnc_handleKilled.sqf b/addons/goggles/functions/fnc_handleKilled.sqf index d156fb684c..e8e207c478 100644 --- a/addons/goggles/functions/fnc_handleKilled.sqf +++ b/addons/goggles/functions/fnc_handleKilled.sqf @@ -26,7 +26,9 @@ GVAR(EffectsActive) = false; _unit setVariable ["ACE_EyesDamaged", false]; -[GVAR(DustHandler)] call CBA_fnc_removePerFrameHandler; +if (GVAR(DustHandler) != -1) then { + [GVAR(DustHandler)] call CBA_fnc_removePerFrameHandler; +}; GVAR(DustHandler) = -1; true diff --git a/addons/goggles/functions/fnc_isDivingGoggles.sqf b/addons/goggles/functions/fnc_isDivingGoggles.sqf index ab5bb74269..ac86a09d2b 100644 --- a/addons/goggles/functions/fnc_isDivingGoggles.sqf +++ b/addons/goggles/functions/fnc_isDivingGoggles.sqf @@ -17,7 +17,7 @@ params ["_glasses"]; -local _config = configFile >> "CfgGlasses" >> _glasses; +private _config = configFile >> "CfgGlasses" >> _glasses; if (!isClass _config) exitWith {false}; diff --git a/addons/goggles/functions/fnc_isInRotorWash.sqf b/addons/goggles/functions/fnc_isInRotorWash.sqf index 5ddc59192a..319da3a875 100644 --- a/addons/goggles/functions/fnc_isInRotorWash.sqf +++ b/addons/goggles/functions/fnc_isInRotorWash.sqf @@ -21,11 +21,11 @@ params ["_unit", ["_radius", 15]]; -local _rotorWash = [false, 0]; +private _rotorWash = [false, 0]; { if (isEngineOn _x) then { - local _distance = _unit distance _x; + private _distance = _unit distance _x; // convert distance to 0...1 range, where 0 is the maximum radius _distance = 1 - _distance / _radius; diff --git a/addons/hearing/ACE_Settings.hpp b/addons/hearing/ACE_Settings.hpp index 262c3edc34..13f445a987 100644 --- a/addons/hearing/ACE_Settings.hpp +++ b/addons/hearing/ACE_Settings.hpp @@ -25,4 +25,10 @@ class ACE_Settings { displayName = CSTRING(enabledForZeusUnits_DisplayName); description = CSTRING(enabledForZeusUnits_Description); }; + class GVAR(autoAddEarplugsToUnits) { + value = 1; + typeName = "BOOL"; + displayName = CSTRING(autoAddEarplugsToUnits_DisplayName); + description = CSTRING(autoAddEarplugsToUnits_Description); + }; }; diff --git a/addons/hearing/CfgEventHandlers.hpp b/addons/hearing/CfgEventHandlers.hpp index f09f259266..e31501d1c3 100644 --- a/addons/hearing/CfgEventHandlers.hpp +++ b/addons/hearing/CfgEventHandlers.hpp @@ -13,7 +13,7 @@ class Extended_PostInit_EventHandlers { class Extended_Init_EventHandlers { class CAManBase { class GVAR(AddEarPlugs) { - init = QUOTE( if (local (_this select 0)) then {_this call FUNC(addEarPlugs)}; ); + serverInit = QUOTE( _this call FUNC(addEarPlugs) ); }; }; }; @@ -33,3 +33,11 @@ class Extended_Explosion_EventHandlers { }; }; }; + +class Extended_Respawn_EventHandlers { + class CAManBase { + class ADDON { + respawn = QUOTE(_this call FUNC(handleRespawn)); + }; + }; +}; diff --git a/addons/hearing/CfgVehicles.hpp b/addons/hearing/CfgVehicles.hpp index 2273653c3a..76a2f90a80 100644 --- a/addons/hearing/CfgVehicles.hpp +++ b/addons/hearing/CfgVehicles.hpp @@ -101,6 +101,7 @@ class CfgVehicles { function = QFUNC(moduleHearing); scope = 2; isGlobal = 1; + isSingular = 1; icon = PATHTOF(UI\Icon_Module_Hearing_ca.paa); class Arguments { class EnableCombatDeafness { @@ -136,6 +137,12 @@ class CfgVehicles { typeName = "BOOL"; defaultValue = 1; }; + class autoAddEarplugsToUnits { + displayName = CSTRING(autoAddEarplugsToUnits_DisplayName); + description = CSTRING(autoAddEarplugsToUnits_Description); + typeName = "BOOL"; + defaultValue = 1; + }; }; class ModuleDescription { description = CSTRING(Module_Description); diff --git a/addons/hearing/CfgWeapons.hpp b/addons/hearing/CfgWeapons.hpp index 7c21baaed2..7e1c932f62 100644 --- a/addons/hearing/CfgWeapons.hpp +++ b/addons/hearing/CfgWeapons.hpp @@ -42,7 +42,8 @@ class CfgWeapons { class H_PilotHelmetFighter_O: H_PilotHelmetFighter_B {}; class H_PilotHelmetFighter_I: H_PilotHelmetFighter_B {}; - class H_Cap_headphones: H_HelmetB { + class HelmetBase; + class H_Cap_headphones: HelmetBase { GVAR(protection) = 0.5; GVAR(lowerVolume) = 0.60; }; diff --git a/addons/hearing/XEH_preInit.sqf b/addons/hearing/XEH_preInit.sqf index 16b9f35f80..3355d0cff4 100644 --- a/addons/hearing/XEH_preInit.sqf +++ b/addons/hearing/XEH_preInit.sqf @@ -6,6 +6,7 @@ PREP(addEarPlugs); PREP(earRinging); PREP(explosionNear); PREP(firedNear); +PREP(handleRespawn); PREP(hasEarPlugsIn); PREP(moduleHearing); PREP(putInEarPlugs); diff --git a/addons/hearing/functions/fnc_addEarPlugs.sqf b/addons/hearing/functions/fnc_addEarPlugs.sqf index b2e43bc718..9e6bd0cab2 100644 --- a/addons/hearing/functions/fnc_addEarPlugs.sqf +++ b/addons/hearing/functions/fnc_addEarPlugs.sqf @@ -14,29 +14,50 @@ * Public: No */ #include "script_component.hpp" + params ["_unit"]; +TRACE_2("params",_unit,typeOf _unit); -// Exit if hearing is disabled or soldier has earplugs already in (persistence scenarios) -if (!GVAR(enableCombatDeafness) || {[_unit] call FUNC(hasEarPlugsIn)}) exitWith {}; +// only run this after the settings are initialized +if !(EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(addEarPlugs), _this]; +}; -private ["_launcher"]; +// Exit if hearing is disabled OR autoAdd is disabled OR soldier has earplugs already in (persistence scenarios) +if (!GVAR(enableCombatDeafness) || {!GVAR(autoAddEarplugsToUnits)} || {[_unit] call FUNC(hasEarPlugsIn)}) exitWith {}; // add earplugs if the soldier has a rocket launcher -_launcher = secondaryWeapon _unit; - -if (_launcher != "") exitWith { +if ((secondaryWeapon _unit) != "") exitWith { + TRACE_1("has launcher - adding",_unit); _unit addItem "ACE_EarPlugs"; }; // otherwise add earplugs if the soldier has a big rifle -private ["_magazine", "_ammo"]; +if ((primaryWeapon _unit) == "") exitWith {}; -_magazine = primaryWeaponMagazine _unit select 0; +(primaryWeaponMagazine _unit) params [["_magazine", ""]]; +if (_magazine == "") exitWith {}; -if (isNil "_magazine") exitWith {}; +private _initSpeed = getNumber (configFile >> "CfgMagazines" >> _magazine >> "initSpeed"); +private _ammo = getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"); +private _count = getNumber (configFile >> "CfgMagazines" >> _magazine >> "count"); -_ammo = getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"); +private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ACE_caliber"); +_caliber = call { + if (_ammo isKindOf ["ShellBase", (configFile >> "CfgAmmo")]) exitWith { 80 }; + if (_ammo isKindOf ["RocketBase", (configFile >> "CfgAmmo")]) exitWith { 200 }; + if (_ammo isKindOf ["MissileBase", (configFile >> "CfgAmmo")]) exitWith { 600 }; + if (_ammo isKindOf ["SubmunitionBase", (configFile >> "CfgAmmo")]) exitWith { 80 }; + if (_caliber <= 0) then { 6.5 } else { _caliber }; +}; +private _loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5; -if (getNumber (configFile >> "CfgAmmo" >> _ammo >> "audiblefire") > 8) then { +//If unit has a machine gun boost effective loudness 50% +if (_count >= 50) then {_loudness = _loudness * 1.5}; + +TRACE_2("primaryWeapon",_unit,_loudness); + +if (_loudness > 0.2) then { + TRACE_1("loud gun - adding",_unit); _unit addItem "ACE_EarPlugs"; }; diff --git a/addons/hearing/functions/fnc_handleRespawn.sqf b/addons/hearing/functions/fnc_handleRespawn.sqf new file mode 100644 index 0000000000..527d5d6b16 --- /dev/null +++ b/addons/hearing/functions/fnc_handleRespawn.sqf @@ -0,0 +1,35 @@ +/* + * Author: PabstMirror + * Reset earplugs on respawn, and then re-add if appropriate + * + * Arguments: + * 0: Unit + * + * Return Value: + * Nothing + * + * Example: + * [player] call ACE_hearing_fnc_handleRespawn; + * + * Public: No + */ +#include "script_component.hpp" + +params ["_unit"]; +TRACE_2("params",_unit,typeOf _unit); + +if (!local _unit) exitWith {}; //XEH should only be called on local units + +private _respawn = [0] call BIS_fnc_missionRespawnType; + +//if respawn is not Group or side: +if (_respawn <= 3) then { + //Remove earplugs if they have them: + if (_unit getVariable ["ACE_hasEarPlugsin", false]) then { + TRACE_1("had EarPlugs in - removing",_unit); + _unit setVariable ["ACE_hasEarPlugsin", false, true]; + }; +}; + +//Re-add if they need them: +[_unit] call FUNC(addEarPlugs); diff --git a/addons/hearing/functions/fnc_moduleHearing.sqf b/addons/hearing/functions/fnc_moduleHearing.sqf index 0aa8843485..35836ddb0c 100644 --- a/addons/hearing/functions/fnc_moduleHearing.sqf +++ b/addons/hearing/functions/fnc_moduleHearing.sqf @@ -20,4 +20,5 @@ if ((_logic getVariable "DisableEarRinging") != -1) then { }; [_logic, QGVAR(enabledForZeusUnits), "enabledForZeusUnits"] call EFUNC(common,readSettingFromModule); +[_logic, QGVAR(autoAddEarplugsToUnits), "autoAddEarplugsToUnits"] call EFUNC(common,readSettingFromModule); ACE_LOGINFO("Hearing Module Initialized."); diff --git a/addons/hearing/stringtable.xml b/addons/hearing/stringtable.xml index 05dde3a1bf..471b16d243 100644 --- a/addons/hearing/stringtable.xml +++ b/addons/hearing/stringtable.xml @@ -165,5 +165,11 @@ Permite que unidades remotamente controladas pelo Zeus sejam atingidas por danos auditivos. Permitir a las unidades por control remoto de zeus que puedan tener daños auditivos. + + Add earplugs to units + + + Add the `ACE_EarPlugs` item to all units that have loud weapons. Can disable if using custom loadouts. + \ No newline at end of file diff --git a/addons/interact_menu/ACE_Settings.hpp b/addons/interact_menu/ACE_Settings.hpp index 381405987c..075408499b 100644 --- a/addons/interact_menu/ACE_Settings.hpp +++ b/addons/interact_menu/ACE_Settings.hpp @@ -96,4 +96,13 @@ class ACE_Settings { displayName = CSTRING(addBuildingActions); description = CSTRING(addBuildingActionsDescription); }; + class GVAR(menuAnimationSpeed) { + value = 0; + typeName = "SCALAR"; + isClientSettable = 1; + category = CSTRING(Category_InteractionMenu); + displayName = CSTRING(menuAnimationSpeed); + description = CSTRING(menuAnimationSpeed_Description); + values[] = {"$str_speed_normal", "2x", "3x"}; + }; }; diff --git a/addons/interact_menu/functions/fnc_keyDown.sqf b/addons/interact_menu/functions/fnc_keyDown.sqf index 8c8ecf0c20..56c0e6e19c 100644 --- a/addons/interact_menu/functions/fnc_keyDown.sqf +++ b/addons/interact_menu/functions/fnc_keyDown.sqf @@ -78,6 +78,21 @@ if (GVAR(useCursorMenu)) then { GVAR(selfMenuOffset) = ((positionCameraToWorld [0, 0, 2]) call EFUNC(common,positionToASL)) vectorDiff ((positionCameraToWorld [0, 0, 0]) call EFUNC(common,positionToASL)); +if (GVAR(menuAnimationSpeed) > 0) then { + //Auto expand the first level when self, mounted vehicle or zeus (skips the first animation as there is only one choice) + if (GVAR(openedMenuType) == 0) then { + if (isNull curatorCamera) then { + if (vehicle ACE_player != ACE_player) then { + GVAR(menuDepthPath) = [["ACE_SelfActions", (vehicle ACE_player)]]; + }; + } else { + GVAR(menuDepthPath) = [["ACE_ZeusActions", (getAssignedCuratorLogic player)]]; + }; + } else { + GVAR(menuDepthPath) = [["ACE_SelfActions", ACE_player]]; + }; +}; + ["interactMenuOpened", [_menuType]] call EFUNC(common,localEvent); true diff --git a/addons/interact_menu/functions/fnc_render.sqf b/addons/interact_menu/functions/fnc_render.sqf index 54f197a2a3..1a14acae07 100644 --- a/addons/interact_menu/functions/fnc_render.sqf +++ b/addons/interact_menu/functions/fnc_render.sqf @@ -14,13 +14,12 @@ BEGIN_COUNTER(fnc_render); -private ["_cursorPos2", "_p1", "_p2", "_forEachIndex", "_x", "_cursorScreenPos", "_closestDistance", "_closestSelection", "_sPos", "_disSq", "_closest", "_cTime", "_delta", "_foundTarget", "_misMatch", "_hoverPath", "_i", "_actionData", "_player", "_target"]; - -_foundTarget = false; +private _foundTarget = false; if (GVAR(openedMenuType) >= 0) then { - // _cursorPos1 = positionCameraToWorld [0, 0, 2]; - _cursorPos2 = positionCameraToWorld [0, 0, 2]; + BEGIN_COUNTER(fnc_renderMenuOpen); + + private _cursorPos2 = positionCameraToWorld [0, 0, 2]; // Render all available nearby interactions call FUNC(renderActionPoints); @@ -30,27 +29,26 @@ if (GVAR(openedMenuType) >= 0) then { [[0.5,0.5], "\a3\ui_f\data\IGUI\Cfg\Cursors\selected_ca.paa"] call FUNC(renderSelector); }; - _cursorScreenPos = [worldToScreen _cursorPos2, GVAR(cursorPos)] select (uiNamespace getVariable [QGVAR(cursorMenuOpened),false]); + private _cursorScreenPos = [worldToScreen _cursorPos2, GVAR(cursorPos)] select (uiNamespace getVariable [QGVAR(cursorMenuOpened),false]); - _closestDistance = 1000000; - _closestSelection = -1; + private _closestDistance = 1000000; + private _closestSelection = -1; { - _sPos = _x select 1; - _disSq = (((_cursorScreenPos select 0) - (_sPos select 0))^2 + ((_cursorScreenPos select 1) - (_sPos select 1))^2); - if(_disSq < 0.0125 && _disSq < _closestDistance) then { - _closestDistance = _disSq; + _x params ["", "_sPos"]; + private _distanceFromCursor = _cursorScreenPos distance2d _sPos; + if ((_distanceFromCursor < 0.1118) && {_distanceFromCursor < _closestDistance}) then { + _closestDistance = _distanceFromCursor; _closestSelection = _forEachIndex; }; } forEach GVAR(currentOptions); - if(_closestSelection == -1) exitWith {}; - _closest = GVAR(currentOptions) select _closestSelection; + private _closest = GVAR(currentOptions) select _closestSelection; + _closest params ["_action", "_sPos", "_hoverPath"]; - _sPos = _closest select 1; - _cTime = ACE_diagTime; - _delta = _cTime - GVAR(lastTime); + private _cTime = ACE_diagTime; + private _delta = _cTime - GVAR(lastTime); GVAR(lastTime) = _cTime; GVAR(rotationAngle) = (GVAR(rotationAngle) + (270*_delta)) mod 360; @@ -58,28 +56,17 @@ if (GVAR(openedMenuType) >= 0) then { _foundTarget = true; GVAR(actionSelected) = true; - GVAR(selectedAction) = (_closest select 0) select 1; + GVAR(selectedAction) = _action select 1; GVAR(selectedTarget) = (GVAR(selectedAction)) select 2; - _misMatch = false; - _hoverPath = (_closest select 2); + private _misMatch = !(GVAR(lastPath) isEqualTo _hoverPath); - if((count GVAR(lastPath)) != (count _hoverPath)) then { - _misMatch = true; - } else { - { - if !(_x isEqualTo (_hoverPath select _forEachIndex)) exitWith { - _misMatch = true; - }; - } forEach GVAR(lastPath); - }; - - if(_misMatch && {ACE_diagTime-GVAR(expandedTime) > 0.25}) then { + if(_misMatch && {ACE_diagTime-GVAR(expandedTime) > linearConversion [0, 2, GVAR(menuAnimationSpeed), 0.25, 0.08333333]}) then { GVAR(startHoverTime) = ACE_diagTime; GVAR(lastPath) = _hoverPath; GVAR(expanded) = false; } else { - if(!GVAR(expanded) && ACE_diagTime-GVAR(startHoverTime) > 0.25) then { + if(!GVAR(expanded) && {ACE_diagTime-GVAR(startHoverTime) > linearConversion [0, 2, GVAR(menuAnimationSpeed), 0.25, 0.08333333]}) then { GVAR(expanded) = true; // Start the expanding menu animation only if the user is not going up the menu @@ -89,9 +76,8 @@ if (GVAR(openedMenuType) >= 0) then { GVAR(menuDepthPath) = +GVAR(lastPath); // Execute the current action if it's run on hover - private "_runOnHover"; - _tmp = ((GVAR(selectedAction) select 0) select 9) select 3; - _runOnHover = true; + private _tmp = ((GVAR(selectedAction) select 0) select 9) select 3; + private _runOnHover = true; if ((typeName _tmp) == "CODE" ) then { _runOnHover = call _tmp; } else { @@ -103,14 +89,14 @@ if (GVAR(openedMenuType) >= 0) then { }; if (_runOnHover) then { this = GVAR(selectedTarget); - _player = ACE_Player; - _target = GVAR(selectedTarget); + private _player = ACE_Player; + private _target = GVAR(selectedTarget); // Clear the conditions caches ["clearConditionCaches", []] call EFUNC(common,localEvent); // Check the action conditions - _actionData = GVAR(selectedAction) select 0; + private _actionData = GVAR(selectedAction) select 0; if ([_target, _player, _actionData select 6] call (_actionData select 4)) then { // Call the statement [_target, _player, _actionData select 6] call (_actionData select 3); @@ -121,6 +107,7 @@ if (GVAR(openedMenuType) >= 0) then { }; }; }; + END_COUNTER(fnc_renderMenuOpen); }; if(!_foundTarget && GVAR(actionSelected)) then { diff --git a/addons/interact_menu/functions/fnc_renderMenu.sqf b/addons/interact_menu/functions/fnc_renderMenu.sqf index 21c434fe03..8b8ae963d9 100644 --- a/addons/interact_menu/functions/fnc_renderMenu.sqf +++ b/addons/interact_menu/functions/fnc_renderMenu.sqf @@ -101,9 +101,9 @@ if (GVAR(UseListMenu)) then { }; // Animate menu scale -if (_menuInSelectedPath && (_menuDepth == count _path)) then { - _scaleX = _scaleX * (0.3 + 0.7 * (((ACE_diagTime - GVAR(expandedTime)) * 8) min 1)); - _scaleY = _scaleY * (0.3 + 0.7 * (((ACE_diagTime - GVAR(expandedTime)) * 8) min 1)); +if (_menuInSelectedPath && {_menuDepth == count _path}) then { + _scaleX = _scaleX * (0.3 + 0.7 * (((ACE_diagTime - GVAR(expandedTime)) * linearConversion [0, 2, GVAR(menuAnimationSpeed), 8, 16]) min 1)); + _scaleY = _scaleY * (0.3 + 0.7 * (((ACE_diagTime - GVAR(expandedTime)) * linearConversion [0, 2, GVAR(menuAnimationSpeed), 8, 16]) min 1)); }; _target = _actionObject; diff --git a/addons/interact_menu/stringtable.xml b/addons/interact_menu/stringtable.xml index 42966c43c1..37da2aa95c 100644 --- a/addons/interact_menu/stringtable.xml +++ b/addons/interact_menu/stringtable.xml @@ -299,5 +299,11 @@ Menu interakce Menú de interacción + + Interaction Animation Speed + + + Makes menu animations faster and decreases the time needed to hover to show sub actions + diff --git a/addons/interaction/ACE_Settings.hpp b/addons/interaction/ACE_Settings.hpp index 075c1f056d..a4e6dad42c 100644 --- a/addons/interaction/ACE_Settings.hpp +++ b/addons/interaction/ACE_Settings.hpp @@ -4,4 +4,11 @@ class ACE_Settings { value = 1; typeName = "BOOL"; }; + class GVAR(enableMagazinePassing) { + value = 1; + typeName = "BOOL"; + isClientSettable = 1; + displayName = CSTRING(PassMagazineSetting); + category = ECSTRING(interact_menu,Category_InteractionMenu); + }; }; diff --git a/addons/interaction/ACE_ZeusActions.hpp b/addons/interaction/ACE_ZeusActions.hpp index 5a7ea9d631..af29186895 100644 --- a/addons/interaction/ACE_ZeusActions.hpp +++ b/addons/interaction/ACE_ZeusActions.hpp @@ -199,47 +199,47 @@ class ACE_ZeusActions { class wedge { displayName = "$STR_Wedge"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\wedge_ca.paa"; - statement = "{_x setWaypointFormation 'WEDGE';} forEach (curatorSelected select 1);"; + statement = "{_x setWaypointFormation 'WEDGE';} forEach (curatorSelected select 2);"; }; class vee { displayName = "$STR_Vee"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\vee_ca.paa"; - statement = "{_x setWaypointFormation 'VEE';} forEach (curatorSelected select 1);"; + statement = "{_x setWaypointFormation 'VEE';} forEach (curatorSelected select 2);"; }; class line { displayName = "$STR_Line"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\line_ca.paa"; - statement = "{_x setWaypointFormation 'LINE';} forEach (curatorSelected select 1);"; + statement = "{_x setWaypointFormation 'LINE';} forEach (curatorSelected select 2);"; }; class column { displayName = "$STR_Column"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\column_ca.paa"; - statement = "{_x setWaypointFormation 'COLUMN';} forEach (curatorSelected select 1);"; + statement = "{_x setWaypointFormation 'COLUMN';} forEach (curatorSelected select 2);"; }; class file { displayName = "$STR_File"; icon = "\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\file_ca.paa"; - statement = "{_x setWaypointFormation 'FILE';} forEach (curatorSelected select 1);"; + statement = "{_x setWaypointFormation 'FILE';} forEach (curatorSelected select 2);"; }; class stag_column { displayName = "$STR_Staggered"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\stag_column_ca.paa"; - statement = "{_x setWaypointFormation 'STAG COLUMN';} forEach (curatorSelected select 1);"; + statement = "{_x setWaypointFormation 'STAG COLUMN';} forEach (curatorSelected select 2);"; }; class ech_left { displayName = "$STR_EchL"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\ech_left_ca.paa"; - statement = "{_x setWaypointFormation 'ECH LEFT';} forEach (curatorSelected select 1);"; + statement = "{_x setWaypointFormation 'ECH LEFT';} forEach (curatorSelected select 2);"; }; class ech_right { displayName = "$STR_EchR"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\ech_right_ca.paa"; - statement = "{_x setWaypointFormation 'ECH RIGHT';} forEach (curatorSelected select 1);"; + statement = "{_x setWaypointFormation 'ECH RIGHT';} forEach (curatorSelected select 2);"; }; class diamond { displayName = "$STR_Diamond"; icon="\A3\UI_F_Curator\Data\RscCommon\RscAttributeFormation\diamond_ca.paa"; - statement = "{_x setWaypointFormation 'DIAMOND';} forEach (curatorSelected select 1);"; + statement = "{_x setWaypointFormation 'DIAMOND';} forEach (curatorSelected select 2);"; }; }; }; diff --git a/addons/interaction/CfgVehicles.hpp b/addons/interaction/CfgVehicles.hpp index 56fb06a85b..5f1fd751b9 100644 --- a/addons/interaction/CfgVehicles.hpp +++ b/addons/interaction/CfgVehicles.hpp @@ -8,6 +8,7 @@ class CfgVehicles { function = "ACE_Interaction_fnc_moduleInteraction"; scope = 2; isGlobal = 1; + isSingular = 1; icon = PATHTOF(UI\Icon_Module_Interaction_ca.paa); class Arguments { @@ -35,6 +36,32 @@ class CfgVehicles { icon = "\a3\ui_f\data\IGUI\Cfg\Actions\eject_ca.paa"; selection = "pelvis"; + class ACE_PassMagazine { + displayName = CSTRING(PassMagazine); + condition = ""; + statement = ""; + showDisabled = 0; + priority = 3.3; + icon = "\a3\ui_f\data\gui\Rsc\RscDisplayArsenal\cargomag_ca.paa"; + + class ACE_PassMagazinePrimary { + displayName = CSTRING(PassMagazinePrimary); + condition = QUOTE([ARR_3(_player,_target,primaryWeapon _target)] call FUNC(canPassMagazine)); + statement = QUOTE([ARR_3(_player,_target,primaryWeapon _target)] call FUNC(passMagazine)); + showDisabled = 0; + priority = 3; + icon = "\a3\ui_f\data\gui\Rsc\RscDisplayArsenal\primaryweapon_ca.paa"; + }; + class ACE_PassMagazineHandgun { + displayName = CSTRING(PassMagazineHandgun); + condition = QUOTE([ARR_3(_player,_target,handgunWeapon _target)] call FUNC(canPassMagazine)); + statement = QUOTE([ARR_3(_player,_target,handgunWeapon _target)] call FUNC(passMagazine)); + showDisabled = 0; + priority = 1; + icon = "\a3\ui_f\data\gui\Rsc\RscDisplayArsenal\handgun_ca.paa"; + }; + }; + class ACE_TeamManagement { displayName = CSTRING(TeamManagement); condition = QUOTE([ARR_2(_player,_target)] call DFUNC(canJoinTeam) && {GVAR(EnableTeamManagement)}); @@ -270,112 +297,6 @@ class CfgVehicles { hotkey = "M"; }; }; - - class ACE_Gestures { - displayName = CSTRING(Gestures); - condition = "canStand _target"; - statement = ""; - showDisabled = 1; - priority = 3.5; - icon = PATHTOF(UI\gestures_ca.paa); - hotkey = "G"; - - /*class ACE_Gesture_Advance { - displayName = CSTRING(Gestures_Attack); - condition = "canStand _target"; - statement = "_target playActionNow 'gestureAttack';"; - showDisabled = 1; - priority = 2.0; - };*/ - class ACE_Gesture_Advance { - displayName = CSTRING(Gestures_Advance); - condition = QUOTE(canStand _target); - statement = QUOTE(_target playActionNow 'gestureAdvance';); - showDisabled = 1; - priority = 1.9; - hotkey = "1"; - }; - class ACE_Gesture_Go { - displayName = CSTRING(Gestures_Go); - condition = QUOTE(canStand _target); - statement = QUOTE(_target playActionNow ([ARR_2('gestureGo','gestureGoB')] select floor random 2);); - showDisabled = 1; - priority = 1.8; - hotkey = "2"; - }; - class ACE_Gesture_Follow { - displayName = CSTRING(Gestures_Follow); - condition = QUOTE(canStand _target); - statement = QUOTE(_target playActionNow 'gestureFollow';); - showDisabled = 1; - priority = 1.7; - hotkey = "3"; - }; - /*class ACE_Gesture_Point { - displayName = CSTRING(Gestures_Point); - condition = QUOTE(canStand _target); - statement = QUOTE(_target playActionNow 'gesturePoint';); - showDisabled = 1; - priority = 1.6; - };*/ - class ACE_Gesture_Up { - displayName = CSTRING(Gestures_Up); - condition = QUOTE(canStand _target); - statement = QUOTE(_target playActionNow 'gestureUp';); - showDisabled = 1; - priority = 1.5; - hotkey = "4"; - }; - class ACE_Gesture_Cover { - displayName = CSTRING(Gestures_Cover); - condition = QUOTE(canStand _target); - statement = QUOTE(_target playActionNow 'gestureCover';); - showDisabled = 1; - priority = 1.4; - hotkey = "5"; - }; - class ACE_Gesture_CeaseFire { - displayName = CSTRING(Gestures_Cease_Fire); - condition = QUOTE(canStand _target); - statement = QUOTE(_target playActionNow 'gestureCeaseFire';); - showDisabled = 1; - priority = 1.3; - hotkey = "6"; - }; - class ACE_Gesture_Freeze { - displayName = CSTRING(Gestures_Freeze); - condition = QUOTE(canStand _target); - statement = QUOTE(_target playActionNow 'gestureFreeze';); - showDisabled = 1; - priority = 1.2; - hotkey = "7"; - }; - class ACE_Gesture_Yes { - displayName = ECSTRING(common,Yes); - condition = QUOTE(canStand _target); - statement = QUOTE(_target playActionNow ([ARR_2('gestureYes','gestureNod')] select floor random 2);); - showDisabled = 1; - priority = 1.1; - hotkey = "8"; - }; - class ACE_Gesture_No { - displayName = ECSTRING(common,No); - condition = QUOTE(canStand _target); - statement = QUOTE(_target playActionNow 'gestureNo';); - showDisabled = 1; - priority = 1.0; - hotkey = "9"; - }; - class ACE_Gesture_Hi { - displayName = CSTRING(Gestures_Hi); - condition = QUOTE(canStand _target); - statement = QUOTE(_target playActionNow ([ARR_3('gestureHi','gestureHiB','gestureHiC')] select floor random 3);); - showDisabled = 1; - priority = 0.9; - hotkey = "0"; - }; - }; - class ACE_Equipment { displayName = CSTRING(Equipment); condition = QUOTE(true); @@ -557,6 +478,14 @@ class CfgVehicles { }; }; + class Pod_Heli_Transport_04_base_F: StaticWeapon { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + distance = 5; + }; + }; + }; + class StaticMGWeapon: StaticWeapon {}; class HMG_01_base_F: StaticMGWeapon {}; diff --git a/addons/interaction/XEH_postInit.sqf b/addons/interaction/XEH_postInit.sqf index 6442911faa..bed8a349bc 100644 --- a/addons/interaction/XEH_postInit.sqf +++ b/addons/interaction/XEH_postInit.sqf @@ -29,19 +29,11 @@ GVAR(isOpeningDoor) = false; if (_unit == ACE_player) then { addCamShake [4, 0.5, 5]; - local _message = parseText format ([["%1 >", localize LSTRING(YouWereTappedRight)], ["< %1", localize LSTRING(YouWereTappedLeft)]] select (_shoulderNum == 0)); - [_message] call FUNC(displayTextStructured); + private _message = parseText format ([["%1 >", localize LSTRING(YouWereTappedRight)], ["< %1", localize LSTRING(YouWereTappedLeft)]] select (_shoulderNum == 1)); + [_message] call EFUNC(common,displayTextStructured); }; }] call EFUNC(common,addEventHandler); -// restore global fire teams for JIP -private "_team"; -{ - _team = _x getVariable [QGVAR(assignedFireTeam), ""]; - if (_team != "") then {_x assignTeam _team}; - false -} count allUnits; - // add keybinds ["ACE3 Common", QGVAR(openDoor), localize LSTRING(OpenDoor), { // Conditions: canInteract @@ -67,8 +59,11 @@ private "_team"; // Conditions: specific if !([ACE_player, cursorTarget] call FUNC(canTapShoulder)) exitWith {false}; + //Tap whichever shoulder is closest + private _shoulderNum = [0, 1] select (([cursorTarget, ACE_player] call BIS_fnc_relativeDirTo) > 180); + // Statement - [ACE_player, cursorTarget, 0] call FUNC(tapShoulder); + [ACE_player, cursorTarget, _shoulderNum] call FUNC(tapShoulder); true }, {false}, diff --git a/addons/interaction/XEH_preInit.sqf b/addons/interaction/XEH_preInit.sqf index 95be20f141..258567482d 100644 --- a/addons/interaction/XEH_preInit.sqf +++ b/addons/interaction/XEH_preInit.sqf @@ -20,6 +20,8 @@ PREP(sendAway); PREP(canJoinGroup); PREP(canJoinTeam); PREP(joinTeam); +PREP(canPassMagazine); +PREP(passMagazine); PREP(canBecomeLeader); PREP(doBecomeLeader); PREP(canTapShoulder); diff --git a/addons/interaction/functions/fnc_canPassMagazine.sqf b/addons/interaction/functions/fnc_canPassMagazine.sqf new file mode 100644 index 0000000000..1c1dd1bb2d --- /dev/null +++ b/addons/interaction/functions/fnc_canPassMagazine.sqf @@ -0,0 +1,30 @@ +/* + * Author: BaerMitUmlaut + * Checks if unit has a spare magazine for the specified weapon. + * + * Arguments: + * 0: Unit that passes the magazine + * 1: Unit to pass the magazine to + * 2: Weapon classname + * + * Return Value: + * Unit can pass magazine + * + * Example: + * [_player, _target, "arifle_MX_F"] call ace_interaction_fnc_canPassMagazine + * + * Public: No + */ + +#include "script_component.hpp" +params ["_player", "_target", "_weapon"]; +private ["_compatibleMags"]; + +if (!GVAR(enableMagazinePassing)) exitWith {false}; + +_compatibleMags = getArray (configfile >> "CfgWeapons" >> _weapon >> "magazines"); +{ + _x params ["_className", "", "_loaded"]; + if ((_className in _compatibleMags) && {!_loaded} && {_target canAdd _className}) exitWith {true}; + false +} foreach (magazinesAmmoFull _player); diff --git a/addons/interaction/functions/fnc_hideMouseHint.sqf b/addons/interaction/functions/fnc_hideMouseHint.sqf index 39f43e7fa3..d7f9d9140e 100644 --- a/addons/interaction/functions/fnc_hideMouseHint.sqf +++ b/addons/interaction/functions/fnc_hideMouseHint.sqf @@ -19,4 +19,4 @@ if (isNull (uiNamespace getVariable ["ACE_Helper_Display", objNull])) exitWith { (QGVAR(InteractionHelper) call BIS_fnc_rscLayer) cutText ["", "PLAIN"]; -showHUD true; +["mouseHint", []] call EFUNC(common,showHud); //This is equivalent to the old showHud true diff --git a/addons/interaction/functions/fnc_joinTeam.sqf b/addons/interaction/functions/fnc_joinTeam.sqf index 9283e7b474..1f713d8ba2 100644 --- a/addons/interaction/functions/fnc_joinTeam.sqf +++ b/addons/interaction/functions/fnc_joinTeam.sqf @@ -18,11 +18,7 @@ params ["_unit", "_team"]; -// make sure correct team is set on JIP -_unit setVariable [QGVAR(assignedFireTeam), _team, true]; - -// join fire team on every machine in that group -["assignTeam", units group _unit, [_unit, _team]] call EFUNC(common,targetEvent); +["CBA_teamColorChanged", [_unit, _team]] call CBA_fnc_globalEvent; // display message if (_unit == ACE_player) then { diff --git a/addons/interaction/functions/fnc_passMagazine.sqf b/addons/interaction/functions/fnc_passMagazine.sqf new file mode 100644 index 0000000000..2afe2f3817 --- /dev/null +++ b/addons/interaction/functions/fnc_passMagazine.sqf @@ -0,0 +1,57 @@ +/* + * Author: BaerMitUmlaut + * Pass spare magazine for the specified weapon. + * + * Arguments: + * 0: Unit that passes the magazine + * 1: Unit to pass the magazine to + * 2: Weapon classname + * + * Return Value: + * None + * + * Example: + * [_player, _target, "arifle_MX_F"] call ace_interaction_fnc_magToPassazine + * + * Public: No + */ + +#include "script_component.hpp" +params ["_player", "_target", "_weapon"]; +private ["_compatibleMags", "_filteredMags", "_magToPass", "_magToPassIndex", "_playerName", "_magToPassDisplayName"]; + +_compatibleMags = getArray (configfile >> "CfgWeapons" >> _weapon >> "magazines"); +_filteredMags = [magazinesAmmoFull _player, { + params ["_className", "", "_loaded"]; + _className in _compatibleMags && !_loaded +}] call EFUNC(common,filter); + +//select magazine with most ammo +_magToPass = _filteredMags select 0; +_magToPassIndex = 0; +{ + _x params ["_className", "_ammoCount"]; + if ((_ammoCount > (_magToPass select 1)) && (_target canAdd _className)) then { + _magToPass = _x; + _magToPassIndex = _forEachIndex; + }; +} foreach _filteredMags; + +//remove all magazines and add them again, except the one to be passed +//needed because of missing commands, see http://feedback.arma3.com/view.php?id=12782 +_magToPass params ["_magToPassClassName", "_magToPassAmmoCount"]; +_player removeMagazines _magToPassClassName; +{ + _x params ["_className", "_ammoCount"]; + if ((_className == _magToPassClassName) && (_forEachIndex != _magToPassIndex)) then { + _player addMagazine [_className, _ammoCount]; + }; +} foreach _filteredMags; + +_player playActionNow "PutDown"; + +_target addMagazine [_magToPassClassName, _magToPassAmmoCount]; + +_playerName = [_player] call EFUNC(common,getName); +_magToPassDisplayName = getText (configFile >> "CfgMagazines" >> _magToPassClassName >> "displayName"); +["displayTextStructured", [_target], [[LSTRING(PassMagazineHint), _playerName, _magToPassDisplayName], 1.5, _target]] call EFUNC(common,targetEvent); \ No newline at end of file diff --git a/addons/interaction/functions/fnc_showMouseHint.sqf b/addons/interaction/functions/fnc_showMouseHint.sqf index e8f279cc0c..429b7d7670 100644 --- a/addons/interaction/functions/fnc_showMouseHint.sqf +++ b/addons/interaction/functions/fnc_showMouseHint.sqf @@ -50,4 +50,4 @@ if (_scroll == "") exitWith { (_display displayCtrl 1002) ctrlSetText _scroll; -showHUD false; +["mouseHint", [false, true, true, true, true, true, true, false]] call EFUNC(common,showHud); //This is equivalent to the old showHud false diff --git a/addons/interaction/stringtable.xml b/addons/interaction/stringtable.xml index 13383f8088..96b38dd0a3 100644 --- a/addons/interaction/stringtable.xml +++ b/addons/interaction/stringtable.xml @@ -253,138 +253,6 @@ << Voltar << Indietro - - Gestures - Gesten - Gestos - Gesty - Posunky - Signaux - Жесты - Kézjelek - Gestos - Gesti - - - Attack - Angreifen - Atacar - Do ataku - Zaútočit - Attaquer - Атаковать - Támadás - Atacar - Attaccare - - - Advance - Vordringen - Avanzar - Naprzód - Postoupit - Avancer - Продвигаться - Előre - Avançar - Avanzare - - - Go - Los - Adelante - Szybko - Jít - Aller - Идти - Mozgás - Mover-se - Muoversi - - - Follow - Folgen - Seguirme - Za mną - Následovat - Suivre - Следовать - Utánam - Seguir - Seguire - - - Point - Zeigen - Señalar - Wskazać - Ukázat - Pointer - Точка - Mutat - Apontar - Puntare a - - - Up - Aufstehen - Arriba - Do góry - Vztyk - Debout - Вверх - Fel - Acima - Alzarsi - - - Cover - Deckung - Cubrirse - Do osłony - Krýt se - A couvert - Укрыться - Fedezékbe - Proteger-se - Copertura - - - Cease Fire - Feuer einstellen - Alto el fuego - Wstrzymać ogień - Zastavit palbu - Halte au feu - Прекратить огонь - Tüzet szüntess - Cessar Fogo - Cessare il Fuoco - - - Freeze - Keine Bewegung - Alto - Stać - Stát - Halte - Замереть - Állj - Alto - Fermi - - - Hi - Hallo - Hola - Witaj - Ahoj - Salut - Привет - Helló - Olá - Ciao - Put weapon on back Waffe wegstecken @@ -823,5 +691,25 @@ O módulo de gestão de equipe é composto por: a atribuição de cores para os membros da equipe, comando das equipes, juntando-se / deixando equipes. Управление группами позволяет назначать цвета членам групп, брать командование, вступать в группы или покидать их. + + Pass magazine + Magazin geben + + + Primary magazine + Gewehrmagazin + + + Pistol magazine + Pistolenmagazin + + + %1 passed you a %2 magazine. + %1 hat dir ein %2 Magazin gegeben. + + + Show "pass magazine" interaction + Zeige "Magazine geben" Interaktion + diff --git a/addons/inventory/RscDisplayInventory.hpp b/addons/inventory/RscDisplayInventory.hpp index f845f50a35..c3a1904678 100644 --- a/addons/inventory/RscDisplayInventory.hpp +++ b/addons/inventory/RscDisplayInventory.hpp @@ -87,31 +87,37 @@ class RscDisplayInventory { class BackgroundSlotPrimaryMuzzle: BackgroundSlotPrimary { x = X_PART(26.6); y = Y_PART(9.1); - w = W_PART(2.3); + w = W_PART(1.9); h = H_PART(2); }; class BackgroundSlotPrimaryUnderBarrel: BackgroundSlotPrimary { - x = X_PART(29); + x = X_PART(28.6); y = Y_PART(9.1); - w = W_PART(2.3); + w = W_PART(1.9); h = H_PART(2); }; class BackgroundSlotPrimaryFlashlight: BackgroundSlotPrimary { - x = X_PART(31.4); + x = X_PART(30.6); y = Y_PART(9.2); //not sure why different (double check release) - w = W_PART(2.3); + w = W_PART(1.9); h = H_PART(2); }; class BackgroundSlotPrimaryOptics: BackgroundSlotPrimary { - x = X_PART(33.8); + x = X_PART(32.6); y = Y_PART(9.1); - w = W_PART(2.3); + w = W_PART(1.9); + h = H_PART(2); + }; + class BackgroundSlotPrimaryMagazineGL: BackgroundSlotPrimary { + x = X_PART(34.6); + y = Y_PART(9.1); + w = W_PART(1.9); h = H_PART(2); }; class BackgroundSlotPrimaryMagazine: BackgroundSlotPrimary { x = X_PART(36.2); y = Y_PART(9.1); - w = W_PART(2.3); + w = W_PART(1.9); h = H_PART(2); }; class BackgroundSlotSecondary: BackgroundSlotPrimary { @@ -292,31 +298,37 @@ class RscDisplayInventory { class SlotPrimaryMuzzle: SlotPrimary { x = X_PART(26.6); y = Y_PART(9.1); - w = W_PART(2.3); + w = W_PART(1.9); h = H_PART(2); }; class SlotPrimaryUnderBarrel: SlotPrimary { - x = X_PART(29); + x = X_PART(28.6); y = Y_PART(9.1); - w = W_PART(2.3); + w = W_PART(1.9); h = H_PART(2); }; class SlotPrimaryFlashlight: SlotPrimary { - x = X_PART(31.4); + x = X_PART(30.6); y = Y_PART(9.1); - w = W_PART(2.3); + w = W_PART(1.9); h = H_PART(2); }; class SlotPrimaryOptics: SlotPrimary { - x = X_PART(33.8); + x = X_PART(32.6); y = Y_PART(9.1); - w = W_PART(2.3); + w = W_PART(1.9); + h = H_PART(2); + }; + class SlotPrimaryMagazineGL: SlotPrimary { + x = X_PART(34.6); + y = Y_PART(9.1); + w = W_PART(1.9); h = H_PART(2); }; class SlotPrimaryMagazine: SlotPrimary { - x = X_PART(36.2); + x = X_PART(36.6); y = Y_PART(9.1); - w = W_PART(2.3); + w = W_PART(1.9); h = H_PART(2); }; class SlotSecondary: SlotPrimary { diff --git a/addons/laser/CfgVehicles.hpp b/addons/laser/CfgVehicles.hpp index dd3f02a0cc..d8976ac204 100644 --- a/addons/laser/CfgVehicles.hpp +++ b/addons/laser/CfgVehicles.hpp @@ -5,7 +5,7 @@ class CfgVehicles { // @TODO: Changing the model and simulation hides it, but THEN IT DOESNT SPAWN WTF!? model = "\A3\Weapons_F\empty.p3d"; destrType = "DestructNo"; - simulation = "house"; + simulation = "LaserTarget"; class EventHandlers { init = QUOTE(_this call FUNC(laser_init)); diff --git a/addons/logistics_wirecutter/functions/fnc_isFence.sqf b/addons/logistics_wirecutter/functions/fnc_isFence.sqf index 449ffd7b77..878f44cf9a 100644 --- a/addons/logistics_wirecutter/functions/fnc_isFence.sqf +++ b/addons/logistics_wirecutter/functions/fnc_isFence.sqf @@ -19,9 +19,9 @@ params ["_object"]; TRACE_1("params",_object); -local _typeOf = typeOf _object; +private _typeOf = typeOf _object; -local _returnValue = if (_typeOf != "") then { +private _returnValue = if (_typeOf != "") then { //If the fence has configEntry we can check it directly (1 == (getNumber (configFile >> "CfgVehicles" >> _typeOf >> QGVAR(isFence)))); } else { diff --git a/addons/main/script_mod.hpp b/addons/main/script_mod.hpp index a8b5d80778..6345950d8b 100644 --- a/addons/main/script_mod.hpp +++ b/addons/main/script_mod.hpp @@ -5,7 +5,7 @@ #define MAJOR 3 #define MINOR 3 -#define PATCHLVL 2 +#define PATCHLVL 3 #define BUILD 0 #define VERSION MAJOR.MINOR.PATCHLVL.BUILD diff --git a/addons/map/CfgAmmo.hpp b/addons/map/CfgAmmo.hpp index 805e7b3627..9e98d0efea 100644 --- a/addons/map/CfgAmmo.hpp +++ b/addons/map/CfgAmmo.hpp @@ -6,7 +6,7 @@ class CfgAmmo { class F_20mm_White: FlareBase {}; class ACE_FlashlightProxy_White: F_20mm_White { - model = ""; + model = "\A3\Weapons_f\empty"; effectFlare = "FlareShell"; triggerTime = 0; diff --git a/addons/map/CfgVehicles.hpp b/addons/map/CfgVehicles.hpp index 7906de8bb7..7d7f98207f 100644 --- a/addons/map/CfgVehicles.hpp +++ b/addons/map/CfgVehicles.hpp @@ -5,7 +5,7 @@ class CfgVehicles { class ACE_MapFlashlight { displayName = CSTRING(Action_Flashlights); icon = QUOTE(\a3\ui_f\data\IGUI\Cfg\VehicleToggles\lightsiconon_ca.paa); - condition = QUOTE(GVAR(mapIllumination) && visibleMap && (count ([ACE_player] call FUNC(getUnitFlashlights)) > 0)); + condition = QUOTE(GVAR(mapIllumination) && visibleMap && {count ([ACE_player] call FUNC(getUnitFlashlights)) > 0}); statement = "true"; exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; insertChildren = QUOTE(_this call DFUNC(compileFlashlightMenu)); @@ -23,6 +23,7 @@ class CfgVehicles { function = QFUNC(moduleMap); scope = 2; isGlobal = 1; + isSingular = 1; icon = PATHTOF(UI\Icon_Module_Map_ca.paa); class Arguments { class MapIllumination { @@ -82,6 +83,7 @@ class CfgVehicles { function = QFUNC(blueForceTrackingModule); scope = 2; isGlobal = 0; + isSingular = 1; icon = PATHTOF(UI\Icon_Module_BFTracking_ca.paa); class Arguments { class Enabled { diff --git a/addons/map/XEH_postInitClient.sqf b/addons/map/XEH_postInitClient.sqf index c162f8802d..00e9e737cf 100644 --- a/addons/map/XEH_postInitClient.sqf +++ b/addons/map/XEH_postInitClient.sqf @@ -1,5 +1,22 @@ #include "script_component.hpp" +//Delete map glow lights from disconnecting players #2810 +if (isServer) then { + addMissionEventHandler ["HandleDisconnect",{ + params ["_disconnectedPlayer"]; + + if ((!GVAR(mapGlow)) || {isNull _disconnectedPlayer}) exitWith {}; + { + if (_x isKindOf "ACE_FlashlightProxy_White") then { + // ACE_LOGINFO_2("Deleting leftover light [%1:%2] from DC player [%3]", _x, typeOf _x, _disconnectedPlayer); + deleteVehicle _x; + }; + } forEach attachedObjects _disconnectedPlayer; + + nil + }]; +}; + // Exit on Headless as well if (!hasInterface) exitWith {}; @@ -83,7 +100,7 @@ call FUNC(determineZoom); GVAR(glow) = objNull; ["playerInventoryChanged", { - _flashlights = [ACE_player] call FUNC(getUnitFlashlights); + private _flashlights = [ACE_player] call FUNC(getUnitFlashlights); if ((GVAR(flashlightInUse) != "") && !(GVAR(flashlightInUse) in _flashlights)) then { GVAR(flashlightInUse) = ""; }; @@ -122,5 +139,9 @@ GVAR(hasWatch) = true; if (isNull (_this select 0)) exitWith { GVAR(hasWatch) = true; }; - GVAR(hasWatch) = "ItemWatch" in (_this select 1 select 17); + GVAR(hasWatch) = false; + { + if (_x isKindOf ["ItemWatch", configFile >> "CfgWeapons"]) exitWith {GVAR(hasWatch) = true;}; + false + } count (assignedItems ACE_player); }] call EFUNC(common,addEventHandler); diff --git a/addons/map/functions/fnc_blueForceTrackingUpdate.sqf b/addons/map/functions/fnc_blueForceTrackingUpdate.sqf index 71e4e8c818..e9a619b5a4 100644 --- a/addons/map/functions/fnc_blueForceTrackingUpdate.sqf +++ b/addons/map/functions/fnc_blueForceTrackingUpdate.sqf @@ -2,7 +2,7 @@ #include "script_component.hpp" // BEGIN_COUNTER(blueForceTrackingUpdate); -private ["_groupsToDrawMarkers", "_playerSide", "_anyPlayers", "_markerType", "_colour", "_marker"]; +private ["_groupsToDrawMarkers", "_playerSide", "_anyPlayers", "_colour", "_marker"]; // Delete last set of markers (always) { @@ -28,12 +28,10 @@ if (GVAR(BFT_Enabled) and {(!isNil "ACE_player") and {alive ACE_player}}) then { }; { - _markerType = [_x] call EFUNC(common,getMarkerType); + private _markerType = [_x] call EFUNC(common,getMarkerType); + private _colour = format ["Color%1", side _x]; - - _colour = format ["Color%1", side _x]; - - _marker = createMarkerLocal [format ["ACE_BFT_%1", _forEachIndex], [(getPos leader _x) select 0, (getPos leader _x) select 1]]; + private _marker = createMarkerLocal [format ["ACE_BFT_%1", _forEachIndex], [(getPos leader _x) select 0, (getPos leader _x) select 1]]; _marker setMarkerTypeLocal _markerType; _marker setMarkerColorLocal _colour; _marker setMarkerTextLocal (groupID _x); diff --git a/addons/map/functions/fnc_compileFlashlightMenu.sqf b/addons/map/functions/fnc_compileFlashlightMenu.sqf index 0d081bb57c..bc6746f46e 100644 --- a/addons/map/functions/fnc_compileFlashlightMenu.sqf +++ b/addons/map/functions/fnc_compileFlashlightMenu.sqf @@ -18,48 +18,29 @@ #include "script_component.hpp" -params ["_vehicle", "_player", "_parameters"]; +params ["", "_player"]; + +private["_action", "_actions", "_cfg", "_displayName", "_flashlights", "_icon", "_statement"]; _actions = []; _flashlights = [_player] call FUNC(getUnitFlashlights); //add all carried flashlight menus and on/off submenu actions { - _displayName = getText (configFile >> "CfgWeapons" >> _x >> "displayName"); - _icon = getText (configFile >> "CfgWeapons" >> _x >> "picture"); - - _children = { - params ["_vehicle", "_player", "_flashlight"]; - _actions = []; - - _onAction = [ - (_flashlight + "_On"), - "On", - "", - {[_this select 2] call FUNC(switchFlashlight)}, - {GVAR(flashlightInUse) != (_this select 2)}, - {}, - _flashlight - ] call EFUNC(interact_menu,createAction); - - _offAction = [ - (_flashlight + "_Off"), - "Off", - "", - {[""] call FUNC(switchFlashlight)}, - {GVAR(flashlightInUse) == (_this select 2)}, - {}, - _flashlight - ] call EFUNC(interact_menu,createAction); - - _actions pushBack [_onAction, [], _player]; - _actions pushBack [_offAction, [], _player]; - - _actions + _cfg = (configFile >> "CfgWeapons" >> _x); + _displayName = getText (_cfg >> "displayName"); + _icon = getText (_cfg >> "picture"); + + _statement = if (GVAR(flashlightInUse) == _x) then { + _displayName = format [localize LSTRING(turnLightOff), _displayName]; + {[""] call FUNC(switchFlashlight)} + } else { + _displayName = format [localize LSTRING(turnLightOn), _displayName]; + {[_this select 2] call FUNC(switchFlashlight)} }; - _parentAction = [_x, _displayName, _icon, {true}, {true}, _children, _x] call EFUNC(interact_menu,createAction); - _actions pushBack [_parentAction, [], _player]; + _action = [_x, _displayName, _icon, _statement, {true}, {}, _x] call EFUNC(interact_menu,createAction); + _actions pushBack [_action, [], _player]; } forEach _flashlights; -_actions \ No newline at end of file +_actions diff --git a/addons/map/functions/fnc_determineMapLight.sqf b/addons/map/functions/fnc_determineMapLight.sqf index 01f3882f1f..d023573cd9 100644 --- a/addons/map/functions/fnc_determineMapLight.sqf +++ b/addons/map/functions/fnc_determineMapLight.sqf @@ -12,14 +12,13 @@ * Public: No */ #include "script_component.hpp" +params ["_unit"]; -EXPLODE_1_PVT(_this,_unit); - -private ["_isEnclosed","_nearObjects","_light","_ll","_flashlight", "_flareTint", "_lightTint", "_l"]; +private ["_fnc_blendColor", "_lightTint", "_fnc_calcColor", "_l", "_lightLevel", "_vehicle", "_isEnclosed", "_nearObjects", "_light", "_ll", "_flashlight", "_flareTint"]; // Blend two colors _fnc_blendColor = { - EXPLODE_3_PVT(_this,_c1,_c2,_alpha); + params ["_c1", "_c2", "_alpha"]; [(_c1 select 0) * (1 - _alpha) + (_c2 select 0) * _alpha, (_c1 select 1) * (1 - _alpha) + (_c2 select 1) * _alpha, (_c1 select 2) * (1 - _alpha) + (_c2 select 2) * _alpha, @@ -27,16 +26,17 @@ _fnc_blendColor = { }; // Ambient light tint depending on time of day -_lightTint = switch (true) do { - case (sunOrMoon == 1.0) : { [0.5,0.5,0.5,1] }; - case (sunOrMoon > 0.80) : {[[1.0 - overcast,0.2,0,1], [1,1,1,1], (sunOrMoon - 0.8)/0.2] call _fnc_blendColor}; - case (sunOrMoon > 0.50) : {[[0,0,0.1,1], [1.0 - overcast,0.2,0,1], (sunOrMoon - 0.5)/0.3] call _fnc_blendColor}; - case (sunOrMoon <= 0.5) : { [0,0,0.1,1] }; +_lightTint = call { + if (sunOrMoon == 1.0) exitWith { [0.5,0.5,0.5,1] }; + if (sunOrMoon > 0.80) exitWith { [[1.0 - overcast,0.2,0,1], [1,1,1,1], (sunOrMoon - 0.8)/0.2] call _fnc_blendColor }; + if (sunOrMoon > 0.50) exitWith { [[0,0,0.1,1], [1.0 - overcast,0.2,0,1], (sunOrMoon - 0.5)/0.3] call _fnc_blendColor }; + if (sunOrMoon <= 0.5) exitWith { [0,0,0.1,1] }; + [0,0,0,0] }; // Calculates overlay color from tint and light level _fnc_calcColor = { - EXPLODE_2_PVT(_this,_c1,_lightLevel); + params ["_c1", "_lightLevel"]; if (_lightLevel < 0.5) then { _l = _lightLevel / 0.5; @@ -68,7 +68,6 @@ if (_lightLevel > 0.95) exitWith { [false, [0.5,0.5,0.5,0]] }; -private "_vehicle"; _vehicle = vehicle _unit; // Do not obscure the map if the player is on a enclosed vehicle (assume internal illumination) @@ -124,4 +123,4 @@ if (_lightLevel > 0.95) exitWith { }; // Calculate resulting map color -[true, [_lightTint, _lightLevel] call _fnc_calcColor] \ No newline at end of file +[true, [_lightTint, _lightLevel] call _fnc_calcColor] diff --git a/addons/map/functions/fnc_determineZoom.sqf b/addons/map/functions/fnc_determineZoom.sqf index 345fc68583..bdfc9a866b 100644 --- a/addons/map/functions/fnc_determineZoom.sqf +++ b/addons/map/functions/fnc_determineZoom.sqf @@ -13,7 +13,7 @@ #include "script_component.hpp" private ["_grids", "_fourSize", "_sixSize", "_continue", "_size", "_i"]; -_grids = configFile >> "CfgWorlds" >> worldName >> "Grid"; +_grids = (configFile >> "CfgWorlds" >> worldName >> "Grid"); _fourSize = -1; _sixSize = -1; for "_i" from 1 to 10 do { diff --git a/addons/map/functions/fnc_flashlightGlow.sqf b/addons/map/functions/fnc_flashlightGlow.sqf index 5e72a6c183..011489f321 100644 --- a/addons/map/functions/fnc_flashlightGlow.sqf +++ b/addons/map/functions/fnc_flashlightGlow.sqf @@ -16,15 +16,16 @@ #include "script_component.hpp" +private ["_light", "_color", "_class"]; params ["_flashlight"]; _light = GVAR(glow); if (!isNull _light) then {deleteVehicle _light}; if (_flashlight != "") then { - _colour = getText (configFile >> "CfgWeapons" >> _flashlight >> "ItemInfo" >> "FlashLight" >> "ACE_Flashlight_Colour"); - if !(_colour in ["white", "red", "green", "blue", "yellow"]) then {_colour = "white"}; - _class = format["ACE_FlashlightProxy_%1", _colour]; + _color = getText (configFile >> "CfgWeapons" >> _flashlight >> "ItemInfo" >> "FlashLight" >> "ACE_Flashlight_Colour"); + if !(_color in ["white", "red", "green", "blue", "yellow"]) then {_color = "white"}; + _class = format["ACE_FlashlightProxy_%1", _color]; _light = _class createVehicle [0,0,0]; _light attachTo [ACE_player, [0,0.5,-0.1], "head"]; @@ -32,4 +33,4 @@ if (_flashlight != "") then { _light = objNull; }; -GVAR(glow) = _light; \ No newline at end of file +GVAR(glow) = _light; diff --git a/addons/map/functions/fnc_getUnitFlashlights.sqf b/addons/map/functions/fnc_getUnitFlashlights.sqf index 8fb8066374..41874cc0ca 100644 --- a/addons/map/functions/fnc_getUnitFlashlights.sqf +++ b/addons/map/functions/fnc_getUnitFlashlights.sqf @@ -18,7 +18,7 @@ params ["_unit"]; -_flashlights = []; +private _flashlights = []; { if ((isText (configFile >> "CfgWeapons" >> _x >> "ItemInfo" >> "FlashLight" >> "ACE_Flashlight_Colour")) && !(_x in _flashlights)) then { @@ -26,4 +26,4 @@ _flashlights = []; }; } forEach (items _unit); -_flashlights \ No newline at end of file +_flashlights diff --git a/addons/map/functions/fnc_simulateMapLight.sqf b/addons/map/functions/fnc_simulateMapLight.sqf index ec08f14d4c..84fcc32773 100644 --- a/addons/map/functions/fnc_simulateMapLight.sqf +++ b/addons/map/functions/fnc_simulateMapLight.sqf @@ -16,6 +16,7 @@ #include "script_component.hpp" +private ["_hmd", "_flashlight", "_screenSize", "_realViewPortY", "_realViewPortX", "_fillTex", "_colourAlpha", "_shadeAlpha", "_colourList", "_maxColour"]; params ["_mapCtrl", "_mapScale", "_mapCentre", "_lightLevel"]; _hmd = hmd ACE_player; @@ -50,6 +51,7 @@ if (_flashlight == "") then { //ambient shade fill _mapCtrl drawIcon [_fillTex, [1,1,1,_shadeAlpha], _mapCentre, _screenSize, _screenSize, 0, "", 0]; } else { + private ["_mousePos", "_colour", "_size", "_flashTex", "_beamSize", "_viewPortRatioFixY", "_offsetX", "_offsetYDown", "_offsetYUp"]; //mouse pos _mousePos = GVAR(mousePos); @@ -86,4 +88,4 @@ if (_flashlight == "") then { _mapCtrl drawIcon [_fillTex, [1,1,1,_shadeAlpha], [(_mousePos select 0) + _offsetX, (_mousePos select 1)], _screenSize * 2, _beamSize, 0, "", 0]; //right _mapCtrl drawIcon [_fillTex, [1,1,1,_shadeAlpha], [(_mousePos select 0), (_mousePos select 1) - _offsetYDown], _screenSize * 4, _screenSize, 0, "", 0]; //down _mapCtrl drawIcon [_fillTex, [1,1,1,_shadeAlpha], [(_mousePos select 0), (_mousePos select 1) + _offsetYUp], _screenSize * 4, _screenSize * 4, 0, "", 0]; //up -}; \ No newline at end of file +}; diff --git a/addons/map/functions/fnc_updateMapEffects.sqf b/addons/map/functions/fnc_updateMapEffects.sqf index 72f5d0cec1..0e36a6fdd6 100644 --- a/addons/map/functions/fnc_updateMapEffects.sqf +++ b/addons/map/functions/fnc_updateMapEffects.sqf @@ -12,7 +12,7 @@ */ #include "script_component.hpp" - +private ["_mapCtrl", "_mapScale", "_mapCentre", "_light"]; _mapCtrl = findDisplay 12 displayCtrl 51; _mapScale = ctrlMapScale _mapCtrl; _mapCentre = _mapCtrl ctrlMapScreenToWorld [0.5, 0.5]; @@ -73,4 +73,4 @@ if (GVAR(mapLimitZoom)) then { _mapCtrl ctrlMapAnimAdd [0, GVAR(minMapSize) + 0.001, _mapCentre]; ctrlMapAnimCommit _mapCtrl; }; -}; \ No newline at end of file +}; diff --git a/addons/map/stringtable.xml b/addons/map/stringtable.xml index 92547e8632..e7b55c56b0 100644 --- a/addons/map/stringtable.xml +++ b/addons/map/stringtable.xml @@ -256,15 +256,41 @@ Snížit jas Reducir brillo + + Turn On %1 + %1 Aktivieren + Encender %1 + Włącz %1 + Allumer %1 + Zapnout %1 + Accendi %1 + %1 Bekapcsolása + Ativar %1 + Активировать %1 + + + Turn Off %1 + %1 Deaktivieren + Apagar %1 + Wyłącz %1 + Éteindre %1 + Vypnout %1 + Spegni %1 + %1 Kikapcsolása + Desativar %1 + Деактивировать %1 + Set Channel At Start Ust. domyślny kanał Definir canal no início + Установить канал на старте Change the starting marker channel at mission start Ustaw domyślny kanał dla markerów przy starcie misji Muda o canal do marcador no início da missão + Изменить начальный канал для установки маркеров при запуске миссии \ No newline at end of file diff --git a/addons/map_gestures/CfgVehicles.hpp b/addons/map_gestures/CfgVehicles.hpp index f5c2ae8f38..d4c88883e6 100644 --- a/addons/map_gestures/CfgVehicles.hpp +++ b/addons/map_gestures/CfgVehicles.hpp @@ -6,11 +6,13 @@ class CfgVehicles { displayName = CSTRING(moduleSettings_displayName); function = QFUNC(moduleSettings); isGlobal = 0; + isSingular = 1; author = ECSTRING(common,ACETeam); icon = PATHTOF(ui\icon_module_map_gestures_ca.paa); class Arguments { class enabled { displayName = CSTRING(enabled_DisplayName); + description = CSTRING(enabled_description); typeName = "BOOL"; defaultValue = 1; }; @@ -18,7 +20,7 @@ class CfgVehicles { displayName = CSTRING(maxRange_displayName); description = CSTRING(maxRange_description); typeName = "NUMBER"; - defaultValue = 4; + defaultValue = 7; }; class interval { displayName = CSTRING(interval_displayName); @@ -30,13 +32,13 @@ class CfgVehicles { displayName = CSTRING(defaultLeadColor_displayName); description = CSTRING(defaultLeadColor_description); typeName = "STRING"; - defaultValue = "0,0,0,0"; + defaultValue = "1,0.88,0,0.95"; }; class defaultColor { displayName = CSTRING(defaultColor_displayName); description = CSTRING(defaultColor_description); typeName = "STRING"; - defaultValue = "0,0,0,0"; + defaultValue = "1,0.88,0,0.7"; }; }; }; @@ -53,13 +55,13 @@ class CfgVehicles { displayName = CSTRING(leadColor_displayName); description = CSTRING(leadColor_description); typeName = "STRING"; - defaultValue = "0,0,0,0"; + defaultValue = "1,0.88,0,0.95"; }; class color { displayName = CSTRING(color_displayName); description = CSTRING(color_description); typeName = "STRING"; - defaultValue = "0,0,0,0"; + defaultValue = "1,0.88,0,0.7"; }; }; }; diff --git a/addons/map_gestures/XEH_postInit.sqf b/addons/map_gestures/XEH_postInit.sqf index 777463e86a..233ee23c04 100644 --- a/addons/map_gestures/XEH_postInit.sqf +++ b/addons/map_gestures/XEH_postInit.sqf @@ -1,8 +1,13 @@ #include "script_component.hpp" +if (["STMapGestures"] call EFUNC(common,isModLoaded)) exitWith { + ACE_LOGWARNING("st_map_gestures is installed - exiting [remove st_map_gestures.pbo to allow ace version]"); +}; + if (!hasInterface) exitWith {}; ["SettingsInitialized", { + if (!GVAR(enabled)) exitWith {}; [{ if (isNull (findDisplay 12)) exitWith {}; diff --git a/addons/map_gestures/functions/fnc_moduleSettings.sqf b/addons/map_gestures/functions/fnc_moduleSettings.sqf index 99583074fc..56d3235d03 100644 --- a/addons/map_gestures/functions/fnc_moduleSettings.sqf +++ b/addons/map_gestures/functions/fnc_moduleSettings.sqf @@ -17,8 +17,6 @@ */ #include "script_component.hpp" -private ["_defaultColor", "_defaultLeadColor"]; - params ["_logic", "", "_activated"]; if (!_activated || !isServer) exitWith {}; @@ -27,11 +25,19 @@ if (!_activated || !isServer) exitWith {}; [_logic, QGVAR(maxRange), "maxRange"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(interval), "interval"] call EFUNC(common,readSettingFromModule); -_defaultLeadColor = call compile ("[" + (_logic getVariable ["defaultLeadColor", ""]) + "]"); -if (!([_defaultLeadColor] call FUNC(isValidColorArray))) exitWith {ERROR("defaultLeadColor is not a valid color array.")}; +//For default fallback colors, setting to empty ("") will not force on clients +private _defaultLeadColor = _logic getVariable ["defaultLeadColor", ""]; +if (_defaultLeadColor != "") then { + _defaultLeadColor = call compile ("[" + _defaultLeadColor + "]"); + if (!([_defaultLeadColor] call FUNC(isValidColorArray))) exitWith {ERROR("defaultLeadColor is not a valid color array.")}; + [QGVAR(defaultLeadColor), _defaultLeadColor, true, true] call EFUNC(common,setSetting); +}; -_defaultColor = call compile ("[" + (_logic getVariable ["defaultColor", ""]) + "]"); -if (!([_defaultColor] call FUNC(isValidColorArray))) exitWith {ERROR("defaultColor is not a valid color array.")}; +private _defaultColor = _logic getVariable ["defaultColor", ""]; +if (_defaultColor != "") then { + _defaultColor = call compile ("[" + _defaultColor + "]"); + if (!([_defaultColor] call FUNC(isValidColorArray))) exitWith {ERROR("defaultColor is not a valid color array.")}; + [QGVAR(defaultColor), _defaultColor, true, true] call EFUNC(common,setSetting); +}; -[QGVAR(defaultLeadColor), _defaultLeadColor, false, true] call EFUNC(common,setSetting); -[QGVAR(defaultColor), _defaultColor, false, true] call EFUNC(common,setSetting); +ACE_LOGINFO("Map Gestures Module Initialized."); diff --git a/addons/map_gestures/stringtable.xml b/addons/map_gestures/stringtable.xml index 44f9cab571..26ccc15761 100644 --- a/addons/map_gestures/stringtable.xml +++ b/addons/map_gestures/stringtable.xml @@ -5,21 +5,25 @@ Map Gestures Gestos no mapa Gesty na mapie + Жесты на карте Enabled Ativado Aktywne + Включено Map Gesture Max Range Distância para gestos no mapa Maks. zasięg gestów + Макс. дистанция жестов на карте Max range between players to show the map gesture indicator [default: 7 meters] Distância max. entre os jogadores para mostrar o indicador de gesto no mapa [padrão: 7 metros] Maksymalny zasięg, w obrębie którego gesty będą widoczne dla graczy [domyślnie: 7 metrów] + Макс. дистанция между игроками для отображения жестов на карте [по-умолчанию: 7 метров] Lead Default Alpha @@ -45,21 +49,25 @@ Lead Default Color Cor padrão para o líder Domyślny kolor lidera + Лид. цвет по-умолчанию - Fallback Color value for group leaders. + Fallback Color value for group leaders when there is no group setting. [Module: leave blank to not force on clients] Valor de cor alternativa para líderes de grupo Domyślny kolor dla liderów grup. + Значение цвета для лидеров групп. Default Color Cor padrão Kolor domyślny + Цвет по-умолчанию - Fallback Color value. + Fallback Color value when there is no group setting. [Module: leave blank to not force on clients] Valor alternativo de cor Kolor domyślny + Значение цвета. Lead Alpha @@ -85,76 +93,91 @@ Lead Color Cor do líder Kolor lidera + Лид. цвет Color value for group leaders of groups synced with this module. Valor de cor para líderes de grupo sincronizados com este módulo. Kolor dla liderów grup zsynchronizowanych z tym modułem. + Значение цвета для лидеров групп, которые [группы] синхронизированы с этим модулем. Color Cor Kolor + Цвет Color value for group members of groups synced with this module. Valor de cor para membros de grupo sincronizados com este módulo. Kolor dla członków grup zsynchronizowanych z tym modułem. + Значение цвета для членов групп, которые [группы] синхронизированы с этим модулем. Map Gestures - Group Settings Gestos no mapa - Definições de Grupo Gesty na mapie - ustawienia grup + Жесты на карте - настройки групп Update Interval Intervalo de atualizações Interwał aktualizacji + Интервал обновления Time between data updates. Tempo entre atualização de dados Odstęp pomiędzy aktualizacjami danych + Время между обновлениями данных. Group color configurations Configurações de cores de grupo Konf. koloru grup + Конфигурация цвета групп Group color configuration containing arrays of color pairs ([leadColor, color]). Configuração de cores de grupo contendo arrays com pares de cores ([leadColor, color]). Konfiguracja kolorów grup zawierająca tablice par kolorów ([kolorLidera, kolor]). + Конфигурация цвета групп содержит массив цветовых пар ([лид. цвет, цвет]). Hash of Group ID mapped to the Group color configuration index. Hashes de ID de grupos mapeados para o índice de configuração de cor de grupos. Hasz ID grup zmapowanych w indeksie konfiguracji koloru grup. + Хеш ID групп, соответствующих индексам конфигурации цвета групп. GroupID Color configuration mapping Mapeamento de configuração para cores de GroupID Mapowanie kolorów poprzez GroupID + Соответствие ID групп конфигурации цвета групп Enables the Map Gestures. Ativa os gestos no mapa Aktywuje gesty na mapie. + Включает указания на карте. Name Text Color Cor do texto do nome Kolor nazw + Цвет текста имени Color of the name tag text besides the map gestures mark. Cor do texto da etiqueta de nome que fica embaixo da marcação de gestos no mapa. Kolor nazwy gracza obok markera gestu mapy. + Цвет инмени игрока рядом с маркером жестов. Map Gestures Gestos no mapa Gesty na mapie + Жесты на карте diff --git a/addons/medical/CfgVehicles.hpp b/addons/medical/CfgVehicles.hpp index 3a675e9258..8f570147d5 100644 --- a/addons/medical/CfgVehicles.hpp +++ b/addons/medical/CfgVehicles.hpp @@ -17,6 +17,7 @@ class CfgVehicles { function = QUOTE(DFUNC(moduleMedicalSettings)); functionPriority = 1; isGlobal = 1; + isSingular = 1; isTriggerActivated = 0; author = ECSTRING(common,ACETeam); @@ -153,6 +154,7 @@ class CfgVehicles { function = QUOTE(FUNC(moduleAdvancedMedicalSettings)); functionPriority = 10; isGlobal = 2; + isSingular = 1; isTriggerActivated = 0; isDisposable = 0; author = ECSTRING(common,ACETeam); @@ -274,6 +276,7 @@ class CfgVehicles { function = QUOTE(DFUNC(moduleReviveSettings)); functionPriority = 1; isGlobal = 1; + isSingular = 1; isTriggerActivated = 0; author = ECSTRING(common,ACETeam); @@ -430,39 +433,38 @@ class CfgVehicles { #define ARM_LEG_ARMOR_BETTER 5 #define ARM_LEG_ARMOR_CSAT 4 - class Land; - class Man: Land { - class HitPoints; - }; + #define ADD_ACE_HITPOINTS(ARM_ARMOR,LEG_ARMOR) \ + class HitLeftArm { \ + armor = ARM_ARMOR; \ + material = -1; \ + name = "hand_l"; \ + passThrough = 1; \ + radius = 0.08; \ + explosionShielding = 1; \ + visual = "injury_hands"; \ + minimalHit = 0.01; \ + }; \ + class HitRightArm: HitLeftArm { \ + name = "hand_r"; \ + }; \ + class HitLeftLeg { \ + armor = LEG_ARMOR; \ + material = -1; \ + name = "leg_l"; \ + passThrough = 1; \ + radius = 0.1; \ + explosionShielding = 1; \ + visual = "injury_legs"; \ + minimalHit = 0.01; \ + }; \ + class HitRightLeg: HitLeftLeg { \ + name = "leg_r"; \ + }; + class Man; class CAManBase: Man { - class HitPoints: HitPoints { // custom hitpoints. addons might want to adjust these accordingly - class HitLeftArm { - armor = ARM_LEG_ARMOR_DEFAULT; - material = -1; - name = "hand_l"; // @todo hopefully these still include the whole arm + hands - passThrough = 1; - radius = 0.08; - explosionShielding = 1; - visual = "injury_hands"; - minimalHit = 0.01; - }; - class HitRightArm: HitLeftArm { - name = "hand_r"; // @todo hopefully these still include the whole arm + hands - }; - class HitLeftLeg { - armor = ARM_LEG_ARMOR_DEFAULT; - material = -1; - name = "leg_l"; - passThrough = 1; - radius = 0.1; - explosionShielding = 1; - visual = "injury_legs"; - minimalHit = 0.01; - }; - class HitRightLeg: HitLeftLeg { - name = "leg_r"; - }; + class HitPoints { + ADD_ACE_HITPOINTS(ARM_LEG_ARMOR_DEFAULT,ARM_LEG_ARMOR_DEFAULT) }; class ACE_SelfActions { @@ -522,174 +524,82 @@ class CfgVehicles { class B_Soldier_base_F: SoldierWB {}; class B_Soldier_04_f: B_Soldier_base_F { - class HitPoints: HitPoints { - class HitHead; - class HitBody; - class HitHands; - class HitLegs; - class HitLeftArm: HitLeftArm { - armor = ARM_LEG_ARMOR_BETTER; - }; - class HitRightArm: HitRightArm { - armor = ARM_LEG_ARMOR_BETTER; - }; - class HitLeftLeg: HitLeftLeg { - armor = ARM_LEG_ARMOR_BETTER; - }; - class HitRightLeg: HitRightLeg { - armor = ARM_LEG_ARMOR_BETTER; - }; + class HitPoints { + ADD_ACE_HITPOINTS(ARM_LEG_ARMOR_BETTER,ARM_LEG_ARMOR_BETTER) }; }; class B_Soldier_05_f: B_Soldier_base_F { - class HitPoints: HitPoints { - class HitHead; - class HitBody; - class HitHands; - class HitLegs; - class HitLeftArm: HitLeftArm { - armor = ARM_LEG_ARMOR_BETTER; - }; - class HitRightArm: HitRightArm { - armor = ARM_LEG_ARMOR_BETTER; - }; - class HitLeftLeg: HitLeftLeg { - armor = ARM_LEG_ARMOR_BETTER; - }; - class HitRightLeg: HitRightLeg { - armor = ARM_LEG_ARMOR_BETTER; - }; + class HitPoints { + ADD_ACE_HITPOINTS(ARM_LEG_ARMOR_BETTER,ARM_LEG_ARMOR_BETTER) }; }; class I_Soldier_base_F: SoldierGB {}; class I_Soldier_03_F: I_Soldier_base_F { - class HitPoints: HitPoints { - class HitHead; - class HitBody; - class HitHands; - class HitLegs; - class HitLeftArm: HitLeftArm { - armor = ARM_LEG_ARMOR_BETTER; - }; - class HitRightArm: HitRightArm { - armor = ARM_LEG_ARMOR_BETTER; - }; - class HitLeftLeg: HitLeftLeg { - armor = ARM_LEG_ARMOR_BETTER; - }; - class HitRightLeg: HitRightLeg { - armor = ARM_LEG_ARMOR_BETTER; - }; + class HitPoints { + ADD_ACE_HITPOINTS(ARM_LEG_ARMOR_BETTER,ARM_LEG_ARMOR_BETTER) }; }; class I_Soldier_04_F: I_Soldier_base_F { - class HitPoints: HitPoints { - class HitHead; - class HitBody; - class HitHands; - class HitLegs; - class HitLeftArm: HitLeftArm { - armor = ARM_LEG_ARMOR_BETTER; - }; - class HitRightArm: HitRightArm { - armor = ARM_LEG_ARMOR_BETTER; - }; - class HitLeftLeg: HitLeftLeg { - armor = ARM_LEG_ARMOR_BETTER; - }; - class HitRightLeg: HitRightLeg { - armor = ARM_LEG_ARMOR_BETTER; - }; + class HitPoints { + ADD_ACE_HITPOINTS(ARM_LEG_ARMOR_BETTER,ARM_LEG_ARMOR_BETTER) }; }; class O_Soldier_base_F: SoldierEB { - class HitPoints: HitPoints { - class HitHead; - class HitBody; - class HitHands; - class HitLegs; - class HitLeftArm: HitLeftArm { - armor = ARM_LEG_ARMOR_CSAT; - }; - class HitRightArm: HitRightArm { - armor = ARM_LEG_ARMOR_CSAT; - }; - class HitLeftLeg: HitLeftLeg { - armor = ARM_LEG_ARMOR_CSAT; - }; - class HitRightLeg: HitRightLeg { - armor = ARM_LEG_ARMOR_CSAT; - }; + class HitPoints { + ADD_ACE_HITPOINTS(ARM_LEG_ARMOR_CSAT,ARM_LEG_ARMOR_BETTER) + }; + }; + + class O_Soldier_diver_base_F: O_Soldier_base_F { + class HitPoints { + ADD_ACE_HITPOINTS(ARM_LEG_ARMOR_CSAT,ARM_LEG_ARMOR_BETTER) }; }; class O_Soldier_02_F: O_Soldier_base_F { - class HitPoints: HitPoints { - class HitHead; - class HitBody; - class HitHands; - class HitLegs; - class HitLeftArm: HitLeftArm { - armor = ARM_LEG_ARMOR_CSAT; - }; - class HitRightArm: HitRightArm { - armor = ARM_LEG_ARMOR_CSAT; - }; - class HitLeftLeg: HitLeftLeg { - armor = ARM_LEG_ARMOR_CSAT; - }; - class HitRightLeg: HitRightLeg { - armor = ARM_LEG_ARMOR_CSAT; - }; + class HitPoints { + ADD_ACE_HITPOINTS(ARM_LEG_ARMOR_CSAT,ARM_LEG_ARMOR_BETTER) }; }; class O_officer_F: O_Soldier_base_F { - class HitPoints: HitPoints { - class HitHead; - class HitBody; - class HitHands; - class HitLegs; - class HitLeftArm: HitLeftArm { - armor = ARM_LEG_ARMOR_CSAT; // @todo is that suppossed to be the case? - }; - class HitRightArm: HitRightArm { - armor = ARM_LEG_ARMOR_CSAT; - }; - class HitLeftLeg: HitLeftLeg { - armor = ARM_LEG_ARMOR_CSAT; - }; - class HitRightLeg: HitRightLeg { - armor = ARM_LEG_ARMOR_CSAT; - }; + class HitPoints { + ADD_ACE_HITPOINTS(ARM_LEG_ARMOR_CSAT,ARM_LEG_ARMOR_BETTER) }; }; - class O_Protagonist_VR_F: O_Soldier_base_F { - class HitPoints: HitPoints { - class HitHead; - class HitBody; - class HitHands; - class HitLegs; - class HitLeftArm: HitLeftArm { - armor = 2; - }; - class HitRightArm: HitRightArm { - armor = 2; - }; - class HitLeftLeg: HitLeftLeg { - armor = 2; - }; - class HitRightLeg: HitRightLeg { - armor = 2; - }; - }; - }; + //These VR guys already have limb hitpoints that we should be able to use + //Note: the selections are a little weird, eg: class leg_l {name = "leg_l";}; + // class B_Soldier_VR_F: B_Soldier_base_F { { + // class HitPoints { + //Has class hand_l, hand_r, leg_l, leg_r Hitpoints already + // }; + // }; + // class O_Soldier_VR_F: O_Soldier_base_F { { + // class HitPoints { + //Has class hand_l, hand_r, leg_l, leg_r Hitpoints already + // }; + // }; + // class I_Soldier_VR_F: I_Soldier_base_F { { + // class HitPoints { + //Has class hand_l, hand_r, leg_l, leg_r Hitpoints already + // }; + // }; + // class C_Soldier_VR_F: C_man_1 { + // class HitPoints { + //Has class hand_l, hand_r, leg_l, leg_r Hitpoints already + // }; + // }; + // class O_Protagonist_VR_F: O_Soldier_base_F { + // class HitPoints { + //Has class hand_l, hand_r, leg_l, leg_r Hitpoints already + // }; + // }; class MapBoard_altis_F; class ACE_bodyBagObject: MapBoard_altis_F { diff --git a/addons/medical/functions/fnc_displayPatientInformation.sqf b/addons/medical/functions/fnc_displayPatientInformation.sqf index f73376cb29..222de4463f 100644 --- a/addons/medical/functions/fnc_displayPatientInformation.sqf +++ b/addons/medical/functions/fnc_displayPatientInformation.sqf @@ -54,7 +54,7 @@ if (_show) then { _allInjuryTexts = []; _genericMessages = []; - if (GVAR(level) >= 2) then { + if (GVAR(level) >= 2 && {([_unit] call FUNC(hasMedicalEnabled))}) then { _partText = [LSTRING(Head), LSTRING(Torso), LSTRING(LeftArm) ,LSTRING(RightArm) ,LSTRING(LeftLeg), LSTRING(RightLeg)] select _selectionN; _genericMessages pushback [localize _partText, [1, 1, 1, 1]]; }; @@ -87,7 +87,7 @@ if (_show) then { _damaged = [false, false, false, false, false, false]; _selectionBloodLoss = [0,0,0,0,0,0]; - if (GVAR(level) >= 2) then { + if (GVAR(level) >= 2 && {([_target] call FUNC(hasMedicalEnabled))}) then { _openWounds = _target getvariable [QGVAR(openWounds), []]; private "_amountOf"; { diff --git a/addons/medical/functions/fnc_handleDamage.sqf b/addons/medical/functions/fnc_handleDamage.sqf index 4174f3a0f3..6d955e72fd 100644 --- a/addons/medical/functions/fnc_handleDamage.sqf +++ b/addons/medical/functions/fnc_handleDamage.sqf @@ -16,7 +16,7 @@ */ #include "script_component.hpp" -params ["_unit", "_selection", "_damage", "_shooter", "_projectile"]; +params ["_unit", "_selection", "_damage", "_shooter", "_projectile", "_hitPointIndex"]; TRACE_5("ACE_DEBUG: HandleDamage Called",_unit, _selection, _damage, _shooter, _projectile); // bug, apparently can fire for remote units in special cases @@ -43,7 +43,7 @@ if (_selection == "legs") exitWith {_unit getHit "legs"}; // This will convert new selection names into selection names that the medical system understands // TODO This should be cleaned up when we revisit the medical system at a later stage // and instead we should deal with the new hitpoints directly -_selection = [_selection] call FUNC(translateSelections); +_selection = [_unit, _selection, _hitPointIndex] call FUNC(translateSelections); _this set [1, _selection]; // ensure that the parameters are set correctly // If the damage is being weird, we just tell it to fuck off. Ignore: "hands", "legs", "?" diff --git a/addons/medical/functions/fnc_modifyMedicalAction.sqf b/addons/medical/functions/fnc_modifyMedicalAction.sqf index 8feaa7bfca..d16ab762d5 100644 --- a/addons/medical/functions/fnc_modifyMedicalAction.sqf +++ b/addons/medical/functions/fnc_modifyMedicalAction.sqf @@ -19,7 +19,7 @@ params ["_target", "_player", "_selectionN", "_actionData"]; -if (GVAR(level) < 2) exitwith { +if (GVAR(level) < 2 || {!([_target] call FUNC(hasMedicalEnabled))}) exitwith { private ["_pointDamage"]; _pointDamage = (_target getvariable [QGVAR(bodyPartStatus), [0,0,0,0,0,0]]) select _selectionN; diff --git a/addons/medical/functions/fnc_translateSelections.sqf b/addons/medical/functions/fnc_translateSelections.sqf index 410005888e..f2fe4c1de9 100644 --- a/addons/medical/functions/fnc_translateSelections.sqf +++ b/addons/medical/functions/fnc_translateSelections.sqf @@ -4,29 +4,39 @@ * Aims to deal with the new hitpoint system introduced in Arma3 v1.50 and later. * * Arguments: - * 0: selection name + * 0: Unit + * 1: selection name + * 2: HitPoint Index * * Return Value: * translated selection name * * Example: - * ["pelvis"] call ace_medical_fnc_translateSelections + * [bob, "pelvis", 4] call ace_medical_fnc_translateSelections * Returns "body" * * Public: No */ +#include "script_component.hpp" #define HEAD_SELECTIONS ["face_hub", "neck", "head"] +#define HEAD_HITPOINTS ["hitface", "hitneck", "hithead"] #define TORSO_SELECTIONS ["pelvis", "spine1", "spine2", "spine3", "body"] +#define TORSO_HITPOINTS ["hitpelvis", "hitabdomen", "hitdiaphragm", "hitchest", "hitbody"] #define L_ARM_SELECTIONS ["hand_l"] +#define L_ARM_HITPOINTS ["hitleftarm", "hand_l"] #define R_ARM_SELECTIONS ["hand_r"] +#define R_ARM_HITPOINTS ["hitrightarm", "hand_r"] #define L_LEG_SELECTIONS ["leg_l"] +#define L_LEG_HITPOINTS ["hitleftleg", "leg_l"] #define R_LEG_SELECTIONS ["leg_r"] +#define R_LEG_HITPOINTS ["hitrightleg", "leg_r"] -params ["_selection"]; +params ["_unit", "_selection", "_hitPointIndex"]; -if (_selection in HEAD_SELECTIONS) exitwith {"head"}; -if (_selection in TORSO_SELECTIONS) exitwith {"body"}; +if (_selection == "") exitWith {""}; +if (_selection in HEAD_SELECTIONS) exitWith {"head"}; +if (_selection in TORSO_SELECTIONS) exitWith {"body"}; // Not necessary unless we get more hitpoints variants in an next arma update /*if (_selection in L_ARM_SELECTIONS) exitwith {"hand_l"}; @@ -34,4 +44,20 @@ if (_selection in R_ARM_SELECTIONS) exitwith {"hand_r"}; if (_selection in L_LEG_SELECTIONS) exitwith {"leg_l"}; if (_selection in R_LEG_SELECTIONS) exitwith {"leg_r"};*/ +//Backup method to detect weird selections/hitpoints +if ((_selection == "?") || {!(_selection in GVAR(SELECTIONS))}) exitWith { + if (_hitPointIndex < 0) exitWith {_selection}; + private _hitPoint = toLower configName ((configProperties [(configFile >> "CfgVehicles" >> (typeOf _unit) >> "HitPoints")]) select _hitPointIndex); + TRACE_4("Weird sel/hit", _unit, _selection, _hitPointIndex, _hitPoint); + + if (_hitPoint in HEAD_HITPOINTS) exitWith {"head"}; + if (_hitPoint in TORSO_HITPOINTS) exitWith {"body"}; + if (_hitPoint in L_ARM_HITPOINTS) exitWith {"hand_l"}; + if (_hitPoint in R_ARM_HITPOINTS) exitWith {"hand_r"}; + if (_hitPoint in L_LEG_HITPOINTS) exitWith {"leg_l"}; + if (_hitPoint in R_LEG_HITPOINTS) exitWith {"leg_r"}; + + _selection +}; + _selection; diff --git a/addons/medical/functions/fnc_treatmentAdvanced_bandage.sqf b/addons/medical/functions/fnc_treatmentAdvanced_bandage.sqf index aa3669c227..cf18475866 100644 --- a/addons/medical/functions/fnc_treatmentAdvanced_bandage.sqf +++ b/addons/medical/functions/fnc_treatmentAdvanced_bandage.sqf @@ -19,6 +19,9 @@ #include "script_component.hpp" params ["_caller", "_target", "_selectionName", "_className", "_items", "", ["_specificSpot", -1]]; +[_target, "activity", LSTRING(Activity_bandagedPatient), [[_caller] call EFUNC(common,getName)]] call FUNC(addToLog); +[_target, "activity_view", LSTRING(Activity_bandagedPatient), [[_caller] call EFUNC(common,getName)]] call FUNC(addToLog); // TODO expand message + if !([_target] call FUNC(hasMedicalEnabled)) exitwith { _this call FUNC(treatmentBasic_bandage); }; @@ -30,7 +33,4 @@ if !([_target] call FUNC(hasMedicalEnabled)) exitwith { }; }foreach _items;*/ -[_target, "activity", LSTRING(Activity_bandagedPatient), [[_caller] call EFUNC(common,getName)]] call FUNC(addToLog); -[_target, "activity_view", LSTRING(Activity_bandagedPatient), [[_caller] call EFUNC(common,getName)]] call FUNC(addToLog); // TODO expand message - true; diff --git a/addons/medical/stringtable.xml b/addons/medical/stringtable.xml index 0a75d67583..5c3d03a85d 100644 --- a/addons/medical/stringtable.xml +++ b/addons/medical/stringtable.xml @@ -2111,6 +2111,7 @@ %1 used Personal Aid Kit %1 użył apteczki %1 utilizou KPS + %1 использовал аптечку Heavily wounded @@ -2963,7 +2964,7 @@ Allow AI to go unconscious - Позволить ботам терять сознание + Позволить ботам терять сознание (вместо мгновенной смерти) Czy AI może być nieprzytomne od odniesionych obrażeń? Permita a la IA caer inconsciente KI kann bewusstlos werden diff --git a/addons/medical_menu/CfgVehicles.hpp b/addons/medical_menu/CfgVehicles.hpp index 7bbe7db2ad..d2bbf55fd1 100644 --- a/addons/medical_menu/CfgVehicles.hpp +++ b/addons/medical_menu/CfgVehicles.hpp @@ -10,6 +10,7 @@ class CfgVehicles { function = QUOTE(DFUNC(module)); functionPriority = 1; isGlobal = 0; + isSingular = 1; isTriggerActivated = 0; author = ECSTRING(common,ACETeam); class Arguments { diff --git a/addons/medical_menu/XEH_postInit.sqf b/addons/medical_menu/XEH_postInit.sqf index 4435511b8f..ad1acabdb3 100644 --- a/addons/medical_menu/XEH_postInit.sqf +++ b/addons/medical_menu/XEH_postInit.sqf @@ -19,7 +19,7 @@ GVAR(pendingReopen) = false; ["ACE3 Common", QGVAR(displayMenuKeyPressed), localize LSTRING(DisplayMenuKey), { - local _target = cursorTarget; + private _target = cursorTarget; if (!((_target isKindOf "CAManBase") && {[ACE_player, _target] call FUNC(canOpenMenu)})) then {_target = ACE_player}; // Conditions: canInteract diff --git a/addons/medical_menu/functions/fnc_updateBodyImage.sqf b/addons/medical_menu/functions/fnc_updateBodyImage.sqf index afe84a59d3..1e8067a7f6 100644 --- a/addons/medical_menu/functions/fnc_updateBodyImage.sqf +++ b/addons/medical_menu/functions/fnc_updateBodyImage.sqf @@ -20,7 +20,7 @@ params ["_selectionBloodLoss", "_damaged", "_display"]; // Handle the body image coloring -local _availableSelections = [50, 51, 52, 53, 54, 55]; +private _availableSelections = [50, 51, 52, 53, 54, 55]; { private ["_red", "_green", "_blue"]; diff --git a/addons/medical_menu/functions/fnc_updateUIInfo.sqf b/addons/medical_menu/functions/fnc_updateUIInfo.sqf index bcc9811905..56a22689db 100644 --- a/addons/medical_menu/functions/fnc_updateUIInfo.sqf +++ b/addons/medical_menu/functions/fnc_updateUIInfo.sqf @@ -62,7 +62,7 @@ _damaged = [false, false, false, false, false, false]; _selectionBloodLoss = [0, 0, 0, 0, 0, 0]; _allInjuryTexts = []; -if (EGVAR(medical,level) >= 2) then { +if ((EGVAR(medical,level) >= 2) && {([_target] call EFUNC(medical,hasMedicalEnabled))}) then { _openWounds = _target getVariable [QEGVAR(medical,openWounds), []]; private "_amountOf"; { diff --git a/addons/microdagr/CfgVehicles.hpp b/addons/microdagr/CfgVehicles.hpp index ee16870fe0..3fcf92beaa 100644 --- a/addons/microdagr/CfgVehicles.hpp +++ b/addons/microdagr/CfgVehicles.hpp @@ -38,6 +38,7 @@ class CfgVehicles { function = QFUNC(moduleMapFill); scope = 2; isGlobal = 0; + isSingular = 1; icon = QUOTE(PATHTOF(UI\Icon_Module_microDAGR_ca.paa)); functionPriority = 0; class Arguments { diff --git a/addons/microdagr/README.md b/addons/microdagr/readme.md similarity index 100% rename from addons/microdagr/README.md rename to addons/microdagr/readme.md diff --git a/addons/missileguidance/CfgAmmo.hpp b/addons/missileguidance/CfgAmmo.hpp index 64146b8e7e..fc0546f797 100644 --- a/addons/missileguidance/CfgAmmo.hpp +++ b/addons/missileguidance/CfgAmmo.hpp @@ -26,7 +26,7 @@ class CfgAmmo { thrustTime = 1.07; thrust = 530; fuseDistance = 2; - + effectsMissileInit = "MissileDAR1"; effectsMissile = "missile2"; whistleDist = 4; @@ -34,34 +34,34 @@ class CfgAmmo { // Turn off arma crosshair-guidance manualControl = 0; - + // ACE uses these values trackOversteer = 1; trackLead = 0; - + // Begin ACE guidance Configs class ADDON { enabled = 1; - + minDeflection = 0.00025; // Minium flap deflection for guidance maxDeflection = 0.001; // Maximum flap deflection for guidance incDeflection = 0.0005; // The incrmeent in which deflection adjusts. - + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode - + // Guidance type for munitions defaultSeekerType = "SALH"; - seekerTypes[] = { "SALH", "LIDAR", "SARH", "Optic", "Thermal", "GPS", "SACLOS", "MCLOS" }; - + seekerTypes[] = { "SALH", "LIDAR", "SARH", "Optic", "Thermal", "GPS", "SACLOS", "MCLOS" }; + defaultSeekerLockMode = "LOAL"; - seekerLockModes[] = { "LOAL", "LOBL" }; - + seekerLockModes[] = { "LOAL", "LOBL" }; + seekerAngle = 90; // Angle in front of the missile which can be searched seekerAccuracy = 1; // seeker accuracy multiplier - + seekerMinRange = 1; seekerMaxRange = 2500; // Range from the missile which the seeker can visually search - + // Attack profile type selection defaultAttackProfile = "LIN"; attackProfiles[] = { "LIN", "DIR", "MID", "HI" }; @@ -71,10 +71,12 @@ class CfgAmmo { class ACE_Hydra70_DAGR: M_PG_AT { displayName = CSTRING(Hydra70_DAGR); displayNameShort = CSTRING(Hydra70_DAGR_Short); - + description = CSTRING(Hydra70_DAGR_Desc); descriptionShort = CSTRING(Hydra70_DAGR_Desc); + EGVAR(rearm,caliber) = 70; + //Explicity add guidance config class ADDON: ADDON {}; }; @@ -82,14 +84,14 @@ class CfgAmmo { class ACE_Hellfire_AGM114K: ACE_Hydra70_DAGR { displayName = CSTRING(Hellfire_AGM114K); displayNameShort = CSTRING(Hellfire_AGM114K_Short); - + description = CSTRING(Hellfire_AGM114K_desc); descriptionShort = CSTRING(Hellfire_AGM114K_desc); - + // @TODO: placeholder model to at least make it look different model = "\A3\Weapons_F\Ammo\Missile_AT_03_fly_F"; proxyShape = "\A3\Weapons_F\Ammo\Missile_AT_03_F"; - + hit = 1400; indirectHit = 71; indirectHitRange = 4.5; @@ -98,7 +100,7 @@ class CfgAmmo { //Explicity add guidance config class ADDON: ADDON {}; }; - + // Titan class M_Titan_AT: MissileBase {}; diff --git a/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf b/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf index 70ef644384..26f605e347 100644 --- a/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf +++ b/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf @@ -18,10 +18,8 @@ #include "script_component.hpp" -private ["_logic", "_units", "_activated","_ambianceSounds", "_soundFiles", "_minimalDistance","_maximalDistance", "_minimalDistance", "_maxDelayBetweenSounds", "_allUnits", "_newPos", "_targetUnit", "_soundToPlay", "_soundPath", "_unparsedSounds", "_list", "_splittedList", "_nilCheckPassedList"]; -_logic = [_this,0,objNull,[objNull]] call BIS_fnc_param; -_units = [_this,1,[],[[]]] call BIS_fnc_param; -_activated = [_this,2,true,[true]] call BIS_fnc_param; +private ["_ambianceSounds", "_minimalDistance","_maximalDistance", "_minimalDistance", "_maxDelayBetweenSounds", "_missionRoot", "_unparsedSounds", "_splittedList", "_soundPath"]; +params ["_logic", "_units", "_activated"]; // We only play this on the locality of the logic, since the sounds are broadcasted across the network if (_activated && local _logic) then { @@ -34,51 +32,49 @@ if (_activated && local _logic) then { _volume = (_logic getVariable ["soundVolume", 30]) max 1; _followPlayers = _logic getVariable ["followPlayers", false]; - _splittedList = [_unparsedSounds, ","] call BIS_fnc_splitString; + _splittedList = _unparsedSounds splitString ","; + _missionRoot = str missionConfigFile select [0, count str missionConfigFile - 15]; - _nilCheckPassedList = ""; { _x = [_x] call EFUNC(common,stringRemoveWhiteSpace); - _splittedList set [_forEachIndex, _x]; - }forEach _splittedList; - _soundPath = [(str missionConfigFile), 0, -15] call BIS_fnc_trimString; - { if (isClass (missionConfigFile >> "CfgSounds" >> _x)) then { - _ambianceSounds pushBack (_soundPath + (getArray(missionConfigFile >> "CfgSounds" >> _x >> "sound") select 0)); + // CfgSounds accepts a leading backslash, but a double backslash + // is not accepted in the path, so we have to filter that. + _soundPath = getArray (missionConfigFile >> "CfgSounds" >> _x >> "sound") select 0; + if (_soundPath select [0,1] == "\") then { + _ambianceSounds pushBack (_missionRoot + (_soundPath select [1])); + } else { + _ambianceSounds pushBack (_missionRoot + _soundPath); + }; } else { if (isClass (configFile >> "CfgSounds" >> _x)) then { _ambianceSounds pushBack ((getArray(configFile >> "CfgSounds" >> _x >> "sound") select 0)); + } else { + ACE_LOGERROR_1("Ambient Sounds: Sound ""%1"" not found.",_x); }; }; - }forEach _splittedList; + + false + } count _splittedList; if (count _ambianceSounds == 0) exitWith {}; { - if !([".", _x, true] call BIS_fnc_inString) then { + if ((_x find ".") == -1) then { _ambianceSounds set [_forEachIndex, _x + ".wss"]; }; - }forEach _ambianceSounds; + } forEach _ambianceSounds; [{ - private ["_args", "_logic", "_ambianceSounds", "_minimalDistance", "_maximalDistance", "_minDelayBetweensounds", "_maxDelayBetweenSounds", "_volume", "_followPlayers","_lastTimePlayed", "_newPos"]; - _args = _this select 0; - _logic = _args select 0; - _minDelayBetweensounds = _args select 4; - _maxDelayBetweenSounds = _args select 5; - _lastTimePlayed = _args select 8; + private ["_newPos", "_allUnits", "_targetUnit"]; + params ["_args", "_pfhHandle"]; + _args params ["_logic", "_ambianceSounds", "_minimalDistance", "_maximalDistance", "_minDelayBetweensounds", "_maxDelayBetweenSounds", "_volume", "_followPlayers", "_lastTimePlayed"]; if (!alive _logic) exitWith { - [(_this select 1)] call cba_fnc_removePerFrameHandler; + [_pfhHandle] call cba_fnc_removePerFrameHandler; }; if (ACE_time - _lastTimePlayed >= ((_minDelayBetweensounds + random(_maxDelayBetweenSounds)) min _maxDelayBetweenSounds)) then { - _ambianceSounds = _args select 1; - _minimalDistance = _args select 2; - _maximalDistance = _args select 3; - - _volume = _args select 6; - _followPlayers = _args select 7; // Find all players in session. _allUnits = if (isMultiplayer) then {playableUnits} else {[ACE_player]}; @@ -87,7 +83,7 @@ if (_activated && local _logic) then { if (count _allUnits > 0) then { // Select a target unit at random. - _targetUnit = _allUnits select (round(random((count _allUnits)-1))); + _targetUnit = _allUnits call BIS_fnc_selectRandom; // find the position from which we are going to play this sound from. _newPos = (getPos _targetUnit); @@ -112,7 +108,7 @@ if (_activated && local _logic) then { // If no unit is to close to this position, we will play the sound. if ({(_newPos distance _x < (_minimalDistance / 2))}count _allUnits == 0) then { - playSound3D [_ambianceSounds select (round(random((count _ambianceSounds)-1))), ObjNull, false, _newPos, _volume, 1, 1000]; + playSound3D [_ambianceSounds call BIS_fnc_selectRandom, objNull, false, _newPos, _volume, 1, 1000]; _args set [8, ACE_time]; }; }; diff --git a/addons/mk6mortar/CfgVehicles.hpp b/addons/mk6mortar/CfgVehicles.hpp index b351e440b4..481687f89f 100644 --- a/addons/mk6mortar/CfgVehicles.hpp +++ b/addons/mk6mortar/CfgVehicles.hpp @@ -52,6 +52,7 @@ class CfgVehicles { function = QFUNC(moduleInit); scope = 2; isGlobal = 0; + isSingular = 1; icon = QUOTE(PATHTOF(UI\Icon_Module_mk6_ca.paa)); functionPriority = 0; class Arguments { diff --git a/addons/modules/XEH_postInit.sqf b/addons/modules/XEH_postInit.sqf index 62d16f42ce..1935714dc8 100644 --- a/addons/modules/XEH_postInit.sqf +++ b/addons/modules/XEH_postInit.sqf @@ -4,27 +4,32 @@ ["InitSettingsFromModules", { // TODO This is a basic and limited implementation that mimics some of the functionality from the A3 module framework, but not all of it. // We have to execute this in the postInit XEH because on object init, the parameters of the modules are not yet available. They are if we execute it at the start of postInit execution. + + private _uniqueModulesHandled = []; { [_x] call { - private ["_logic", "_logicType", "_config", "_isGlobal", "_isDisposable", "_isPersistent","_function"]; - _logic = _this select 0; - _logicType = typeof _logic; + params ["_logic"]; + private _logicType = typeof _logic; _logic hideobject true; if (_logic getvariable [QGVAR(initalized), false]) exitwith {}; - _config = (configFile >> "CfgVehicles" >> _logicType); + private _config = (configFile >> "CfgVehicles" >> _logicType); if !(isClass _config) exitwith {}; - // isGlobal = 1; - _isGlobal = getNumber (_config >> "isGlobal") > 0; - _isDisposable = getNumber (_config >> "isDisposable") > 0; - _isPersistent = getNumber (_config >> "isPersistent") > 0 || getnumber (_config >> "isGlobal") > 1; - _function = getText (_config >> "function"); + private _isGlobal = getNumber (_config >> "isGlobal") > 0; + private _isDisposable = getNumber (_config >> "isDisposable") > 0; + private _isPersistent = getNumber (_config >> "isPersistent") > 0 || getnumber (_config >> "isGlobal") > 1; + private _isSingular = getNumber (_config >> "isSingular") > 0; + private _function = getText (_config >> "function"); if (isnil _function) then { _function = compile _function; } else { _function = missionNamespace getvariable _function; }; + if (_isSingular && {_logicType in _uniqueModulesHandled}) then { //ToDo: should this be an exit? + ACE_LOGWARNING_1("Module [%1] - More than 1 singular module placed", _logicType); + }; + if (_isSingular) then {_uniqueModulesHandled pushBack _logicType;}; if (_isGlobal || isServer) then { [_logic, (synchronizedObjects _logic), true] call _function; @@ -38,7 +43,7 @@ deleteVehicle _logic; }; }; - }foreach GVAR(moduleInitCollection); + } forEach GVAR(moduleInitCollection); if (isServer) then { GVAR(serverModulesRead) = true; diff --git a/addons/movement/CfgMoves.hpp b/addons/movement/CfgMoves.hpp index 50d3e3ab2b..a828c5278c 100644 --- a/addons/movement/CfgMoves.hpp +++ b/addons/movement/CfgMoves.hpp @@ -114,26 +114,11 @@ class CfgMovesMaleSdr: CfgMovesBasic { leftHandIKCurve[] = {}; }; - // enable optics in prone left and right stance - class AidlPpneMstpSrasWrflDnon_G0S; - class AadjPpneMstpSrasWrflDleft: AidlPpneMstpSrasWrflDnon_G0S { - enableOptics = 1; - }; - class AadjPpneMstpSrasWrflDright: AidlPpneMstpSrasWrflDnon_G0S { - enableOptics = 1; - }; + // enable optics in prone down stance class AadjPpneMstpSrasWrflDup; class AadjPpneMstpSrasWrflDdown: AadjPpneMstpSrasWrflDup { enableOptics = 1; }; - - class AidlPpneMstpSrasWpstDnon_G0S; - class AadjPpneMstpSrasWpstDleft: AidlPpneMstpSrasWpstDnon_G0S { - enableOptics = 2; - }; - class AadjPpneMstpSrasWpstDright: AidlPpneMstpSrasWpstDnon_G0S { - enableOptics = 2; - }; class AadjPpneMstpSrasWpstDup; class AadjPpneMstpSrasWpstDdown: AadjPpneMstpSrasWpstDup { enableOptics = 2; diff --git a/addons/nametags/CfgVehicles.hpp b/addons/nametags/CfgVehicles.hpp index f6e28095b4..7ca13b5aeb 100644 --- a/addons/nametags/CfgVehicles.hpp +++ b/addons/nametags/CfgVehicles.hpp @@ -7,6 +7,7 @@ class CfgVehicles { function = QFUNC(moduleNameTags); scope = 2; isGlobal = 1; + isSingular = 1; icon = QUOTE(PATHTOF(UI\Icon_Module_NameTags_ca.paa)); class Arguments { class showPlayerNames { diff --git a/addons/nametags/XEH_postInit.sqf b/addons/nametags/XEH_postInit.sqf index b828d70005..ef9268b9a6 100644 --- a/addons/nametags/XEH_postInit.sqf +++ b/addons/nametags/XEH_postInit.sqf @@ -22,42 +22,6 @@ GVAR(showNamesTime) = -10; {false}, [29, [false, false, false]], false] call cba_fnc_addKeybind; //LeftControl Key -// Monitor the assigned teams, and propegate them appropriately for the player -// This allows for assigned team colors to match across the entire group -[{ - private["_leader", "_playerIsLeader", "_unitTeam"]; - if (!(isNull ACE_player) && { alive ACE_player } ) then { - _leader = leader (group ACE_player); - _playerIsLeader = false; - - if(alive _leader) then { - if(_leader == ACE_player) then { - _playerIsLeader = true; - }; - }; - - if (_playerIsLeader) then { - { - if(alive _x) then { - _unitTeam = _x getVariable [QGVAR(teamAssignment),"MAIN"]; - if (_unitTeam != assignedTeam _x) then { - _x setVariable [QGVAR(teamAssignment), assignedTeam _x,true]; - }; - }; - } forEach units (group ACE_player); - } else { - { - if(alive _x) then { - _unitTeam = _x getVariable [QGVAR(teamAssignment),"MAIN"]; - if (_unitTeam != assignedTeam _x) then { - _x assignTeam _unitTeam; - }; - }; - } forEach units (group ACE_player); - }; - }; -}, 5, []] call CBA_fnc_addPerFrameHandler; - // Wait until the colors are defined before starting to draw the nametags ["SettingsInitialized", { // Draw handle diff --git a/addons/nametags/functions/fnc_initIsSpeaking.sqf b/addons/nametags/functions/fnc_initIsSpeaking.sqf index 4d4d576c52..3b8aea497a 100644 --- a/addons/nametags/functions/fnc_initIsSpeaking.sqf +++ b/addons/nametags/functions/fnc_initIsSpeaking.sqf @@ -41,7 +41,7 @@ if (isClass (configFile >> "cfgPatches" >> "acre_api")) then { ACE_LOGINFO("ACRE Detected."); DFUNC(isSpeaking) = { params ["_unit"]; - (([_unit] call acre_api_fnc_isSpeaking) || {[ACE_player] call acre_api_fnc_isBroadcasting}) && {!(_unit getVariable ["ACE_isUnconscious", false])} + ([_unit] call acre_api_fnc_isSpeaking) && {!(_unit getVariable ["ACE_isUnconscious", false])} }; } else { if (isClass (configFile >> "cfgPatches" >> "task_force_radio")) then { diff --git a/addons/nametags/stringtable.xml b/addons/nametags/stringtable.xml index d3616d18f4..61a2b3f5a2 100644 --- a/addons/nametags/stringtable.xml +++ b/addons/nametags/stringtable.xml @@ -1,4 +1,4 @@ - + diff --git a/addons/optionsmenu/CfgVehicles.hpp b/addons/optionsmenu/CfgVehicles.hpp index 1357417add..cbe03a4cfb 100644 --- a/addons/optionsmenu/CfgVehicles.hpp +++ b/addons/optionsmenu/CfgVehicles.hpp @@ -8,6 +8,7 @@ class CfgVehicles { function = QUOTE(DFUNC(moduleAllowConfigExport)); functionPriority = 1; isGlobal = 1; + isSingular = 1; isTriggerActivated = 0; author = ECSTRING(common,ACETeam); class Arguments { diff --git a/addons/optionsmenu/stringtable.xml b/addons/optionsmenu/stringtable.xml index 6b4cad396b..cd4cc429b0 100644 --- a/addons/optionsmenu/stringtable.xml +++ b/addons/optionsmenu/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -356,6 +356,7 @@ Pošle debug informace do RPT a schránky. Protokolliert Debug-Informationen im RPT und speichert sie in der Zwischenablage. Envia informação de depuração para RPT e área de transferência. + Отправляет отладочную информацию в RPT и буфер обмена. Headbug Fix @@ -415,4 +416,4 @@ Logística - + \ No newline at end of file diff --git a/addons/overpressure/functions/fnc_cacheOverPressureValues.sqf b/addons/overpressure/functions/fnc_cacheOverPressureValues.sqf index 0717065c43..8de8af6375 100644 --- a/addons/overpressure/functions/fnc_cacheOverPressureValues.sqf +++ b/addons/overpressure/functions/fnc_cacheOverPressureValues.sqf @@ -24,9 +24,9 @@ private ["_array", "_type", "_return", "_config" /*, "_priority"*/]; // get Priority Array from Config _array = [ - getNumber (configFile >> "CfgWeapons" >> QGVAR(priority)), - getNumber (configFile >> "CfgMagazines" >> QGVAR(priority)), - getNumber (configFile >> "CfgAmmo" >> QGVAR(priority)) + getNumber (configFile >> "CfgWeapons" >> _weapon >> QGVAR(priority)), + getNumber (configFile >> "CfgMagazines" >> _magazine >> QGVAR(priority)), + getNumber (configFile >> "CfgAmmo" >> _ammo >> QGVAR(priority)) ]; TRACE_1("Proiroity Array",_array); diff --git a/addons/overpressure/functions/fnc_fireLauncherBackblast.sqf b/addons/overpressure/functions/fnc_fireLauncherBackblast.sqf index 1653fce9e1..e457e023c6 100644 --- a/addons/overpressure/functions/fnc_fireLauncherBackblast.sqf +++ b/addons/overpressure/functions/fnc_fireLauncherBackblast.sqf @@ -41,14 +41,14 @@ _var params["_backblastAngle","_backblastRange","_backblastDamage"]; // Damage to others private "_affected"; -_affected = getPos _projectile nearEntities ["CAManBase", _backblastRange]; +_affected = (ASLtoAGL _position) nearEntities ["CAManBase", _backblastRange]; // Let each client handle their own affected units -["overpressure", _affected, [_firer, _position, _direction, _weapon]] call EFUNC(common,targetEvent); +["overpressure", _affected, [_firer, _position, _direction, _weapon, _magazine, _ammo]] call EFUNC(common,targetEvent); // Damage to the firer private "_distance"; -_distance = [_position, _direction, _backblastRange] call FUNC(getDistance); +_distance = [_position, _direction, _backblastRange, _firer] call FUNC(getDistance); TRACE_1("Distance",_distance); diff --git a/addons/overpressure/functions/fnc_fireOverpressureZone.sqf b/addons/overpressure/functions/fnc_fireOverpressureZone.sqf index 3068928ba4..02de0eb311 100644 --- a/addons/overpressure/functions/fnc_fireOverpressureZone.sqf +++ b/addons/overpressure/functions/fnc_fireOverpressureZone.sqf @@ -40,7 +40,7 @@ _var params["_dangerZoneAngle","_dangerZoneRange","_dangerZoneDamage"]; // Damage to others private "_affected"; -_affected = getPos _projectile nearEntities ["CAManBase", _dangerZoneRange]; +_affected = (ASLtoAGL _position) nearEntities ["CAManBase", _dangerZoneRange]; // Let each client handle their own affected units ["overpressure", _affected, [_firer, _position, _direction, _weapon, _magazine, _ammo]] call EFUNC(common,targetEvent); diff --git a/addons/overpressure/functions/fnc_getDistance.sqf b/addons/overpressure/functions/fnc_getDistance.sqf index 3b3103d951..cabdd267fa 100644 --- a/addons/overpressure/functions/fnc_getDistance.sqf +++ b/addons/overpressure/functions/fnc_getDistance.sqf @@ -7,60 +7,45 @@ * 0: Pos ASL of origin (ARRAY> * 1: Direction * 2: Max distance to search + * 3: Shooter * * Return value: - * Distance to intersection (+- 0.1 m) + * Distance to intersection (999 if distance is greater than max) + * + * Example: + * [[1823.41,5729.05,6.66627], [-0.953255,0.109689,-0.281554], 15, ace_player] call ace_overpressure_fnc_getDistance + * */ #include "script_component.hpp" -EXPLODE_3_PVT(_this,_posASL,_direction,_maxDistance); +params ["_posASL", "_direction", "_maxDistance", "_shooter"]; +TRACE_3("params",_posASL,_direction,_maxDistance); -private ["_distance", "_interval", "_line", "_intersections", "_terrainIntersect", "_lastTerrainIntersect"]; +private _intersections = lineIntersectsSurfaces [_posASL, _posASL vectorAdd (_direction vectorMultiply _maxDistance), _shooter, objNull, true, 99]; -_distance = _maxDistance; -_interval = _distance; -_line = [_posASL, []]; -_terrainIntersect = false; -_lastTerrainIntersect = false; +TRACE_1("lineIntersectsSurfaces",_intersections); -while { - _interval > 0.1 -} do { - _lastTerrainIntersect = _terrainIntersect; - _interval = _interval / 2; +private _distance = 999; - _line set [1, _posASL vectorAdd (_direction vectorMultiply _distance)]; +{ + _x params ["_intersectPosASL", "_surfaceNormal", "_intersectObject"]; - _intersections = { - _x isKindOf "Static" || {_x isKindOf "AllVehicles"} - } count (lineIntersectsWith _line); + //Hit something solid that can reflect - (Static covers Building) + if ((isNull _intersectObject) || {(_intersectObject isKindOf "Static") || {_intersectObject isKindOf "AllVehicles"}}) exitWith { + _distance = _posASL vectorDistance _intersectPosASL; + TRACE_3("hit solid object",_distance,_intersectObject,typeOf _intersectObject); - _terrainIntersect = if (_intersections > 0) then { - false - } else { - terrainIntersectASL _line + if (isNull _intersectObject) then { //Terrain: + // Calculate the angle between the terrain and the back blast direction + _angle = 90 - acos (- (_surfaceNormal vectorDotProduct _direction)); + TRACE_3("Terrain Intersect",_surfaceNormal,_direction,_angle); + // Angles is below 25deg, no backblast at all + if (_angle < 25) exitWith {_distance = 999}; + // Angles is below 45deg the distance is increased according to the difference + if (_angle < 45) exitWith {_distance = _distance * (5 - 4 * sqrt ((_angle - 25)/20))}; + // Angles above 45degcreate full backblast + }; }; - - _distance = _distance + ([1, -1] select (_intersections > 0 || _terrainIntersect)) * _interval; - - if (_distance > _maxDistance) exitWith {_distance = 999}; -}; - -if (_distance > _maxDistance) exitWith {_distance}; - -// If the intersection was with the terrain, check slope -if (_terrainIntersect || _lastTerrainIntersect) exitWith { - private ["_slope","_angle"]; - _slope = surfaceNormal (_posASL vectorAdd (_direction vectorMultiply _distance)); - // Calculate the angle between the terrain and the back blast direction - _angle = 90 - acos (- (_slope vectorDotProduct _direction)); - - //systemChat format ["Angle: %1", _angle]; - // Angles is below 25º, no backblast at all - if (_angle < 25) exitWith {_distance = 999}; - // Angles is below 45º the distance is increased according to the difference - if (_angle < 45) exitWith {_distance = _distance * (5 - 4 * sqrt ((_angle - 25)/20))}; - // Angles above 45º create full backblast -}; +} forEach _intersections; _distance diff --git a/addons/overpressure/functions/fnc_overpressureDamage.sqf b/addons/overpressure/functions/fnc_overpressureDamage.sqf index a39aec3c14..f9c58050e0 100644 --- a/addons/overpressure/functions/fnc_overpressureDamage.sqf +++ b/addons/overpressure/functions/fnc_overpressureDamage.sqf @@ -30,12 +30,6 @@ _var params["_overpressureAngle","_overpressureRange","_overpressureDamage"]; TRACE_4("Parameters:",_overpressureAngle,_overpressureRange,_overpressureDamage,_weapon); -private "_pos"; -_pos = _posASL; -if (!surfaceIsWater _pos) then { - _pos = ASLtoATL _pos; -}; - { if (local _x && {_x != _firer} && {vehicle _x == _x}) then { private ["_targetPositionASL", "_relativePosition", "_axisDistance", "_distance", "_angle", "_line", "_line2"]; @@ -68,4 +62,4 @@ if (!surfaceIsWater _pos) then { }; }; }; -} forEach (_pos nearEntities ["CAManBase", _overpressureRange]); +} forEach ((ASLtoAGL _posASL) nearEntities ["CAManBase", _overpressureRange]); diff --git a/addons/realisticnames/CfgVehicles.hpp b/addons/realisticnames/CfgVehicles.hpp index c3288815dd..9aea632247 100644 --- a/addons/realisticnames/CfgVehicles.hpp +++ b/addons/realisticnames/CfgVehicles.hpp @@ -308,6 +308,9 @@ class CfgVehicles { class O_Heli_Light_02_F: Heli_Light_02_base_F { displayName = CSTRING(Heli_Light_02_Name); }; + class O_Heli_Light_02_v2_F: Heli_Light_02_base_F { + displayName = CSTRING(Heli_Light_02_v2_Name); + }; class Heli_Light_02_unarmed_base_F; class O_Heli_Light_02_unarmed_F: Heli_Light_02_unarmed_base_F { displayName = CSTRING(Heli_Light_02_unarmed_Name); diff --git a/addons/realisticnames/stringtable.xml b/addons/realisticnames/stringtable.xml index 5f84a4f16d..fbf1e37226 100644 --- a/addons/realisticnames/stringtable.xml +++ b/addons/realisticnames/stringtable.xml @@ -817,6 +817,17 @@ Ka-60 Kasatka Ka-60 Kasatka + + Ka-60 Kasatka (Black & White) + Ka-60 Kasatka (černobílá) + Ka-60 Kasatka (noir et blanc) + Ka-60 Kasatka (Schwarz-weiß) + Ka-60 Kasatka (bianco e nero) + Ka-60 Kasatka (czarno-biały) + Ka-60 Kasatka (preto e branco) + Ka-60 Касатка (белый и черный) + Ka-60 Kasatka (blanco y negro) + Ka-60 Kasatka (unarmed) Ka-60 Kasatka (unbewaffnet) diff --git a/addons/rearm/$PBOPREFIX$ b/addons/rearm/$PBOPREFIX$ new file mode 100644 index 0000000000..7acbc38009 --- /dev/null +++ b/addons/rearm/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\rearm \ No newline at end of file diff --git a/addons/rearm/ACE_Settings.hpp b/addons/rearm/ACE_Settings.hpp new file mode 100644 index 0000000000..f4d6562807 --- /dev/null +++ b/addons/rearm/ACE_Settings.hpp @@ -0,0 +1,9 @@ +class ACE_Settings { + class GVAR(level) { + displayName = CSTRING(RearmSettings_level_DisplayName); + description = CSTRING(RearmSettings_level_Description); + value = 0; + typeName = "SCALAR"; + values[] = {CSTRING(RearmSettings_vehicle), CSTRING(RearmSettings_magazine), CSTRING(RearmSettings_caliber)}; + }; +}; diff --git a/addons/rearm/CfgAmmo.hpp b/addons/rearm/CfgAmmo.hpp new file mode 100644 index 0000000000..2443ab91a5 --- /dev/null +++ b/addons/rearm/CfgAmmo.hpp @@ -0,0 +1,200 @@ +class CfgAmmo { + + class BombCore; + class BombBase : BombCore { + GVAR(caliber) = 250; // Default caliber for bombs + }; + class LaserBombCore : BombCore { + GVAR(caliber) = 250; // Default caliber for bombs + }; + class MissileCore; + class MissileBase : MissileCore { + GVAR(caliber) = 250; // Default caliber for missiles + }; + class Missile_AA_04_F : MissileBase { + GVAR(dummy) = QGVAR(Missile_AA_04_F); + }; + class Missile_AA_03_F : Missile_AA_04_F { + GVAR(dummy) = QGVAR(Missile_AA_03_F); + }; + + class Rocket_04_HE_F : MissileBase { + GVAR(caliber) = 70; + GVAR(dummy) = QGVAR(Rocket_04_HE_F); + }; + class Rocket_03_HE_F : Rocket_04_HE_F { + GVAR(dummy) = QGVAR(Rocket_03_HE_F); + }; + class Rocket_04_AP_F : Rocket_04_HE_F { + GVAR(dummy) = QGVAR(Rocket_04_AP_F); + }; + class Rocket_03_AP_F : Rocket_04_AP_F { + GVAR(dummy) = QGVAR(Rocket_03_AP_F); + }; + class M_PG_AT : MissileBase { + GVAR(caliber) = 70; + GVAR(dummy) = QGVAR(M_PG_AT); + }; + class Missile_AGM_02_F : MissileBase { + GVAR(dummy) = QGVAR(Missile_AGM_02_F); + }; + class Missile_AGM_01_F : Missile_AGM_02_F { + GVAR(dummy) = QGVAR(Missile_AGM_01_F); + }; + + class RocketCore; + class RocketBase : RocketCore { + GVAR(caliber) = 70; // Default caliber for rockets + }; + class R_80mm_HE : RocketBase { + GVAR(caliber) = 80; + GVAR(dummy) = QGVAR(R_80mm_HE); + }; + class R_60mm_HE : R_80mm_HE { + GVAR(caliber) = 60; + GVAR(dummy) = QGVAR(R_60mm_HE); + }; + class R_Hydra_HE : RocketBase { + GVAR(dummy) = QGVAR(R_Hydra_HE); + }; + + class BulletBase; + class B_19mm_HE : BulletBase { + GVAR(caliber) = 19; + }; + + class B_20mm : BulletBase { + GVAR(caliber) = 20; + }; + + class B_25mm : BulletBase { + GVAR(caliber) = 25; + }; + + class B_30mm_AP : BulletBase { + GVAR(caliber) = 30; + }; + class B_30mm_HE : B_19mm_HE { + GVAR(caliber) = 30; + }; + class Gatling_30mm_HE_Plane_CAS_01_F : BulletBase { + GVAR(caliber) = 30; + }; + + class B_35mm_AA : BulletBase { + GVAR(caliber) = 35; + }; + + class B_30mm_APFSDS; + class B_40mm_APFSDS : B_30mm_APFSDS { + GVAR(caliber) = 40; + }; + + class B_40mm_GPR : B_30mm_HE { + GVAR(caliber) = 40; + }; + + class GrenadeBase; + class G_40mm_HE : GrenadeBase { + GVAR(caliber) = 39; + }; + + class ShellBase; + class R_230mm_fly : ShellBase { + GVAR(dummy) = QGVAR(R_230mm_fly); + }; + + class Sh_120mm_APFSDS : Shellbase { + GVAR(caliber) = 120; + }; + class Sh_105mm_APFSDS : Sh_120mm_APFSDS { + GVAR(caliber) = 105; + }; + class Sh_125mm_APFSDS : Sh_120mm_APFSDS { + GVAR(caliber) = 125; + }; + + class Sh_120mm_HE : ShellBase { + GVAR(caliber) = 120; + }; + class Sh_125mm_HE : Sh_120mm_HE { + GVAR(caliber) = 125; + }; + class Sh_125mm_HEAT : Sh_125mm_HE { + GVAR(caliber) = 125; + }; + class Sh_105mm_HEAT_MP : Sh_125mm_HEAT { + GVAR(caliber) = 105; + }; + + class Sh_155mm_AMOS : ShellBase { + GVAR(caliber) = 155; + }; + class Sh_82mm_AMOS : Sh_155mm_AMOS { + GVAR(caliber) = 82; + }; + + class Sh_82mm_AMOS_LG; + class Sh_155mm_AMOS_LG : Sh_82mm_AMOS_LG { + GVAR(caliber) = 155; + }; + + class ShotDeployBase; + class Smoke_82mm_AMOS_White : ShotDeployBase { + GVAR(caliber) = 82; + }; + + class FlareCore; + class Flare_82mm_AMOS_White : FlareCore { + GVAR(caliber) = 82; + }; + + class SmokeLauncherAmmo : BulletBase { + GVAR(caliber) = 250; + }; + + class CMflareAmmo : BulletBase { + GVAR(caliber) = 39; + }; + + class SubmunitionBase; + class Sh_82mm_AMOS_guided : SubmunitionBase { + GVAR(caliber) = 82; + }; + class Sh_155mm_AMOS_guided : Sh_82mm_AMOS_guided { + GVAR(caliber) = 155; + }; + class R_230mm_HE : SubmunitionBase { + GVAR(caliber) = 230; + }; + class Mine_155mm_AMOS_range : SubmunitionBase { + GVAR(caliber) = 155; + }; + class Cluster_155mm_AMOS : SubmunitionBase { + GVAR(caliber) = 155; + }; + class Smoke_120mm_AMOS_White : SubmunitionBase { + GVAR(caliber) = 155; + }; + class AT_Mine_155mm_AMOS_range : SubmunitionBase { + GVAR(caliber) = 155; + }; + + class Bo_Mk82 : BombCore { + GVAR(dummy) = QGVAR(Bo_Mk82); + }; + + class Bo_GBU12_LGB : LaserBombCore { + GVAR(caliber) = 250; // Default caliber for bombs + GVAR(dummy) = QGVAR(Bo_GBU12_LGB); + }; + + class Bomb_04_F : LaserBombCore { + GVAR(caliber) = 250; // Default caliber for bombs + GVAR(dummy) = QGVAR(Bomb_04_F); + }; + + class Bomb_03_F : Bomb_04_F { + GVAR(dummy) = QGVAR(Bomb_03_F); + }; +}; diff --git a/addons/rearm/CfgEventHandlers.hpp b/addons/rearm/CfgEventHandlers.hpp new file mode 100644 index 0000000000..93371889e1 --- /dev/null +++ b/addons/rearm/CfgEventHandlers.hpp @@ -0,0 +1,36 @@ +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_preInit)); + }; +}; + + +class Extended_Init_EventHandlers { + class GVAR(defaultCarriedObject) { // TODO check if we need to add all subclasses + class ADDON { + init = QUOTE(_this call DEFUNC(cargo,initObject)); + }; + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_postInit)); + }; +}; + +class Extended_Respawn_EventHandlers { + class CAManBase { + class ADDON { + respawn = QUOTE(call COMPILE_FILE(XEH_respawn)); + }; + }; +}; + +class Extended_Killed_EventHandlers { + class CAManBase { + class ADDON { + killed = QUOTE(_this call FUNC(handleKilled)); + }; + }; +}; diff --git a/addons/rearm/CfgMagazines.hpp b/addons/rearm/CfgMagazines.hpp new file mode 100644 index 0000000000..a509377182 --- /dev/null +++ b/addons/rearm/CfgMagazines.hpp @@ -0,0 +1,56 @@ +class CfgMagazines { + class CA_Magazine; + class 60Rnd_CMFlareMagazine : CA_Magazine { + displayName = CSTRING(Mag_60Rnd_CMFlareMagazine); + }; + + class VehicleMagazine; + class SmokeLauncherMag : VehicleMagazine { + displayName = CSTRING(Mag_SmokeLauncherMag); + }; + class SmokeLauncherMag_boat : VehicleMagazine { + displayName = CSTRING(Mag_SmokeLauncherMag); + }; + + class 1000Rnd_Gatling_30mm_Plane_CAS_01_F : VehicleMagazine { + displayName = CSTRING(Mag_1000Rnd_Gatling_30mm_Plane_CAS_01_F); + }; + class 500Rnd_Cannon_30mm_Plane_CAS_02_F : 1000Rnd_Gatling_30mm_Plane_CAS_01_F { + displayName = CSTRING(Mag_500Rnd_Cannon_30mm_Plane_CAS_02_F); + }; + + class 2Rnd_Missile_AA_04_F : VehicleMagazine { + displayName = CSTRING(Mag_2Rnd_Missile_AA_04_F); + }; + class 2Rnd_Missile_AA_03_F : 2Rnd_Missile_AA_04_F { + displayName = CSTRING(Mag_2Rnd_Missile_AA_03_F); + }; + + class 6Rnd_Missile_AGM_02_F : VehicleMagazine { + displayName = CSTRING(Mag_6Rnd_Missile_AGM_02_F); + }; + class 4Rnd_Missile_AGM_01_F : 6Rnd_Missile_AGM_02_F { + displayName = CSTRING(Mag_4Rnd_Missile_AGM_01_F); + }; + + class 7Rnd_Rocket_04_HE_F : VehicleMagazine { + displayName = CSTRING(Mag_7Rnd_Rocket_04_HE_F); + }; + class 20Rnd_Rocket_03_HE_F : 7Rnd_Rocket_04_HE_F { + displayName = CSTRING(Mag_20Rnd_Rocket_03_HE_F); + }; + + class 7Rnd_Rocket_04_AP_F : 7Rnd_Rocket_04_HE_F { + displayName = CSTRING(Mag_7Rnd_Rocket_04_AP_F); + }; + class 20Rnd_Rocket_03_AP_F : 7Rnd_Rocket_04_AP_F { + displayName = CSTRING(Mag_20Rnd_Rocket_03_AP_F); + }; + + class 4Rnd_Bomb_04_F : VehicleMagazine { + displayName = CSTRING(Mag_4Rnd_Bomb_04_F); + }; + class 2Rnd_Bomb_03_F : 4Rnd_Bomb_04_F { + displayName = CSTRING(Mag_2Rnd_Bomb_03_F); + }; +}; diff --git a/addons/rearm/CfgVehicles.hpp b/addons/rearm/CfgVehicles.hpp new file mode 100644 index 0000000000..d7e8fafed4 --- /dev/null +++ b/addons/rearm/CfgVehicles.hpp @@ -0,0 +1,245 @@ +#define MACRO_REARM_ACTIONS \ + class ACE_Actions { \ + class ACE_MainActions { \ + class GVAR(Rearm) { \ + displayName = CSTRING(Rearm); \ + distance = REARM_ACTION_DISTANCE; \ + condition = QUOTE(_this call FUNC(canRearm)); \ + statement = QUOTE(_player call FUNC(rearm)); \ + exceptions[] = {"isNotInside"}; \ + icon = PATHTOF(ui\icon_rearm_interact.paa); \ + }; \ + }; \ + }; + +#define MACRO_REARM_TRUCK_ACTIONS \ + class ACE_Actions : ACE_Actions { \ + class ACE_MainActions : ACE_MainActions { \ + class GVAR(TakeAmmo) { \ + displayName = CSTRING(TakeAmmo); \ + distance = REARM_ACTION_DISTANCE; \ + condition = QUOTE(_this call FUNC(canTakeAmmo)); \ + insertChildren = QUOTE(_target call FUNC(addRearmActions)); \ + exceptions[] = {"isNotInside"}; \ + showDisabled = 0; \ + priority = 2; \ + icon = PATHTOF(ui\icon_rearm_interact.paa); \ + }; \ + class GVAR(StoreAmmo) { \ + displayName = CSTRING(StoreAmmo); \ + distance = REARM_ACTION_DISTANCE; \ + condition = QUOTE(_this call FUNC(canStoreAmmo)); \ + statement = QUOTE(_this call FUNC(storeAmmo)); \ + exceptions[] = {"isNotInside"}; \ + icon = PATHTOF(ui\icon_rearm_interact.paa); \ + }; \ + }; \ + }; + +class CfgVehicles { + class ACE_Module; + class ACE_moduleRearmSettings : ACE_Module { + scope = 2; + displayName = CSTRING(RearmSettings_Module_DisplayName); + icon = QUOTE(PATHTOF(ui\icon_module_rearm.paa)); + category = "ACE_Logistics"; + function = QFUNC(moduleRearmSettings); + functionPriority = 1; + isGlobal = 0; + isTriggerActivated = 0; + author = ECSTRING(common,ACETeam); + class Arguments { + class level { + displayName = CSTRING(RearmSettings_level_DisplayName); + description = CSTRING(RearmSettings_level_Description); + typeName = "NUMBER"; + class values { + class vehicle { + name = CSTRING(RearmSettings_vehicle); + value = 0; + }; + class magazine { + name = CSTRING(RearmSettings_magazine); + value = 1; + }; + class caliber { + name = CSTRING(RearmSettings_caliber); + value = 2; + default = 1; + }; + }; + }; + }; + class ModuleDescription { + description = CSTRING(RearmSettings_Module_Description); + }; + }; + + class LandVehicle; + class Car : LandVehicle { + MACRO_REARM_ACTIONS + }; + + class Tank : LandVehicle { + MACRO_REARM_ACTIONS + }; + + class StaticWeapon : LandVehicle { + MACRO_REARM_ACTIONS + }; + + class Air; + class Helicopter : Air { + MACRO_REARM_ACTIONS + }; + + class Plane : Air { + MACRO_REARM_ACTIONS + }; + + class Ship; + class Ship_F : Ship { + MACRO_REARM_ACTIONS + }; + + + // Ammo Vehicles (with full inheritance for granted ACE_Actions) + class Car_F : Car {}; + class Truck_F : Car_F {}; + + class Truck_03_base_F : Truck_F {}; + class O_Truck_03_ammo_F : Truck_03_base_F { + transportAmmo = 0; + MACRO_REARM_TRUCK_ACTIONS + }; + + class Truck_02_base_F : Truck_F {}; + class Truck_02_Ammo_base_F : Truck_02_base_F {}; + class I_Truck_02_ammo_F : Truck_02_Ammo_base_F { + transportAmmo = 0; + MACRO_REARM_TRUCK_ACTIONS + }; + class O_Truck_02_Ammo_F : Truck_02_Ammo_base_F { + transportAmmo = 0; + MACRO_REARM_TRUCK_ACTIONS + }; + + class Truck_01_base_F : Truck_F {}; + class B_Truck_01_transport_F : Truck_01_base_F {}; + class B_Truck_01_mover_F : B_Truck_01_transport_F {}; + class B_Truck_01_ammo_F : B_Truck_01_mover_F { + transportAmmo = 0; + MACRO_REARM_TRUCK_ACTIONS + }; + + class Helicopter_Base_F : Helicopter {}; + class Helicopter_Base_H : Helicopter_Base_F {}; + class Heli_Transport_04_base_F : Helicopter_Base_H {}; + class O_Heli_Transport_04_ammo_F : Heli_Transport_04_base_F { + transportAmmo = 0; + MACRO_REARM_TRUCK_ACTIONS + }; + + class Pod_Heli_Transport_04_base_F: StaticWeapon {}; + class Land_Pod_Heli_Transport_04_ammo_F: Pod_Heli_Transport_04_base_F { + transportAmmo = 0; + MACRO_REARM_TRUCK_ACTIONS + }; + + class Slingload_base_F; + class Slingload_01_Base_F: Slingload_base_F { + class ACE_Actions { + class ACE_MainActions { + displayName = ECSTRING(interaction,MainAction); + selection = ""; + distance = 10; + condition = "true"; + }; + }; + }; + + class B_Slingload_01_Ammo_F : Slingload_01_Base_F { + XEH_ENABLED; + transportAmmo = 0; + MACRO_REARM_TRUCK_ACTIONS + }; + + + // Dummy Vehicles + class ThingX; + class GVAR(defaultCarriedObject) : ThingX { + XEH_ENABLED; + displayName = QGVAR(dummy_obj); + scope = 2; + scopeCurator = 2; + model = "\A3\Weapons_F\AmmoBoxes\AmmoBox_F.p3d"; + EGVAR(cargo,size) = 1; + class ACE_Actions { + class ACE_MainActions { + displayName = CSTRING(PickUpAmmo); + distance = REARM_ACTION_DISTANCE; + condition = QUOTE(_this call FUNC(canTakeAmmo)); + statement = QUOTE(_this call FUNC(grabAmmo)); + exceptions[] = {"isNotInside"}; + showDisabled = 0; + priority = 2; + icon = PATHTOF(ui\icon_rearm_interact.paa); + }; + }; + }; + class GVAR(Bo_GBU12_LGB) : GVAR(defaultCarriedObject) { + model = "\A3\Weapons_F\Ammo\Bomb_01_F.p3d"; + }; + class GVAR(Bo_Mk82) : GVAR(defaultCarriedObject) { + model = "\A3\Weapons_F\Ammo\Bomb_02_F"; + }; + class GVAR(Bomb_04_F) : GVAR(defaultCarriedObject) { + model = "\A3\Weapons_F_EPC\Ammo\Bomb_04_F.p3d"; + }; + class GVAR(Bomb_03_F) : GVAR(defaultCarriedObject) { + model = "\A3\Weapons_F_EPC\Ammo\Bomb_03_F.p3d"; + }; + class GVAR(Missile_AA_04_F) : GVAR(defaultCarriedObject) { + model = "\A3\Weapons_F_EPC\Ammo\Missile_AA_04_F.p3d"; + }; + class GVAR(Missile_AA_03_F) : GVAR(defaultCarriedObject) { + model = "\A3\Weapons_F_EPC\Ammo\Missile_AA_03_F.p3d"; + }; + class GVAR(Missile_AGM_02_F) : GVAR(defaultCarriedObject) { + model = "\A3\Weapons_F_EPC\Ammo\Missile_AGM_02_F.p3d"; + }; + class GVAR(Missile_AGM_01_F) : GVAR(defaultCarriedObject) { + model = "\A3\Weapons_F_EPC\Ammo\Missile_AGM_01_F.p3d"; + }; + class GVAR(R_230mm_fly) : GVAR(defaultCarriedObject) { + model = "\A3\Weapons_F\Ammo\Missile_AT_02_F"; + }; + class GVAR(R_230mm_HE) : GVAR(defaultCarriedObject) { + model = "\A3\Weapons_F\Ammo\Missile_AT_02_F"; + }; + class GVAR(M_PG_AT) : GVAR(defaultCarriedObject) { + model = "\A3\Weapons_F\Ammo\Rocket_01_F"; + }; + class GVAR(Rocket_04_HE_F) : GVAR(defaultCarriedObject) { + model = "\A3\Weapons_F_EPC\Ammo\Rocket_04_HE_F.p3d"; + }; + class GVAR(Rocket_03_HE_F) : GVAR(defaultCarriedObject) { + model = "\A3\Weapons_F_EPC\Ammo\Rocket_03_HE_F.p3d"; + }; + class GVAR(Rocket_04_AP_F) : GVAR(defaultCarriedObject) { + model = "\A3\Weapons_F_EPC\Ammo\Rocket_04_AP_F.p3d"; + }; + class GVAR(Rocket_03_AP_F) : GVAR(defaultCarriedObject) { + model = "\A3\Weapons_F_EPC\Ammo\Rocket_03_AP_F.p3d"; + }; + // Using wrong model + class GVAR(R_80mm_HE) : GVAR(defaultCarriedObject) { + model = "\A3\Weapons_F_EPC\Ammo\Rocket_03_HE_F.p3d"; + }; + class GVAR(R_60mm_HE) : GVAR(defaultCarriedObject) { + model = "\A3\Weapons_F_EPC\Ammo\Rocket_03_HE_F.p3d"; + }; + class GVAR(R_Hydra_HE) : GVAR(defaultCarriedObject) { + model = "\A3\Weapons_F_EPC\Ammo\Rocket_03_HE_F.p3d"; + }; +}; diff --git a/addons/rearm/README.md b/addons/rearm/README.md new file mode 100644 index 0000000000..4d6dc966a1 --- /dev/null +++ b/addons/rearm/README.md @@ -0,0 +1,11 @@ +ace_rearm +=============== + +The Rearm module introduces ability to rearm vehicles on different realistic levels. + +## Maintainers + +The people responsible for merging changes to this component or answering potential questions. + +- [GitHawk] (https://github.com/GitHawk) +- [Jonpas] (https://github.com/jonpas) diff --git a/addons/rearm/XEH_postInit.sqf b/addons/rearm/XEH_postInit.sqf new file mode 100644 index 0000000000..25a5d68523 --- /dev/null +++ b/addons/rearm/XEH_postInit.sqf @@ -0,0 +1,4 @@ +#include "script_component.hpp" + +["medical_onUnconscious", {_this call FUNC(handleOnUnconscious)}] call EFUNC(common,addEventHandler); +["playerVehicleChanged", {params ["_unit"]; [_unit] call FUNC(dropAmmo)}] call EFUNC(common,addEventHandler); diff --git a/addons/rearm/XEH_preInit.sqf b/addons/rearm/XEH_preInit.sqf new file mode 100644 index 0000000000..c52423f67f --- /dev/null +++ b/addons/rearm/XEH_preInit.sqf @@ -0,0 +1,30 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP(addRearmActions); +PREP(canRearm); +PREP(canStoreAmmo); +PREP(canTakeAmmo); +PREP(createDummy); +PREP(dropAmmo); +PREP(getConfigMagazines); +PREP(getMaxMagazines); +PREP(getNeedRearmMagazines); +PREP(grabAmmo); +PREP(handleKilled); +PREP(handleUnconscious); +PREP(makeDummy); +PREP(moduleRearmSettings); +PREP(pickUpAmmo); +PREP(rearm); +PREP(rearmEntireVehicle); +PREP(rearmEntireVehicleSuccess); +PREP(rearmEntireVehicleSuccessLocal); +PREP(rearmSuccess); +PREP(rearmSuccessLocal); +PREP(storeAmmo); +PREP(takeAmmo); +PREP(takeSuccess); + +ADDON = true; diff --git a/addons/rearm/XEH_respawn.sqf b/addons/rearm/XEH_respawn.sqf new file mode 100644 index 0000000000..7f0d175d1c --- /dev/null +++ b/addons/rearm/XEH_respawn.sqf @@ -0,0 +1,16 @@ +#include "script_component.hpp" + +private ["_unit"]; + +_unit = _this select 0; + +if !(local _unit) exitWith {}; + +_unit setVariable [QGVAR(selectedWeaponOnRearm), nil]; +_unit setVariable [QGVAR(carriedMagazine), nil]; +_dummy = _unit getVariable [QGVAR(dummy), objNull]; +if !(isNull _dummy) then { + detach _dummy; + deleteVehicle _dummy; +}; +_unit setVariable [QGVAR(dummy), nil]; \ No newline at end of file diff --git a/addons/rearm/config.cpp b/addons/rearm/config.cpp new file mode 100644 index 0000000000..c15721c9df --- /dev/null +++ b/addons/rearm/config.cpp @@ -0,0 +1,20 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_interaction"}; + author[] = {"GitHawk", "Jonpas"}; + authorUrl = "https://ace3mod.com"; + VERSION_CONFIG; + }; +}; + +#include "ACE_Settings.hpp" +#include "CfgEventHandlers.hpp" + +#include "CfgAmmo.hpp" +#include "CfgMagazines.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/rearm/functions/fnc_addRearmActions.sqf b/addons/rearm/functions/fnc_addRearmActions.sqf new file mode 100644 index 0000000000..2011cc73de --- /dev/null +++ b/addons/rearm/functions/fnc_addRearmActions.sqf @@ -0,0 +1,98 @@ +/* + * Author: GitHawk + * Show the resupplyable ammunition of all surrounding vehicles. + * + * Argument: + * 0: Target + * + * Return value: + * ChildActions + * + * Example: + * [tank] call ace_rearm_fnc_addRearmActions + * + * Public: No + */ +#include "script_component.hpp" + +private ["_vehicleActions", "_actions", "_action", "_vehicles", "_vehicle", "_needToAdd", "_magazineHelper", "_turretPath", "_magazines", "_magazine", "_icon", "_cnt"]; +params ["_target"]; + +_vehicles = nearestObjects [_target, ["AllVehicles"], 20]; +if (count _vehicles < 2) exitWith {false}; // Rearming needs at least 2 vehicles + +_vehicleActions = []; +{ + _actions = []; + _vehicle = _x; + _needToAdd = false; + _action = []; + if !((_vehicle == _target) || (_vehicle isKindOf "CAManBase")) then { + _magazineHelper = []; + { + _turretPath = _x; + _magazines = []; + if (_turretPath isEqualTo [-1]) then { + _magazines = [_vehicle, _turretPath] call FUNC(getConfigMagazines); + } else { + _magazines = _vehicle magazinesTurret _turretPath; + }; + { + _magazine = _x; + _cnt = { _x == _magazine } count (_vehicle magazinesTurret _turretPath); + if ((_cnt < ([_vehicle, _turretPath, _magazine] call FUNC(getMaxMagazines))) && !(_magazine in _magazineHelper)) then { + _action = [_magazine, + getText(configFile >> "CfgMagazines" >> _magazine >> "displayName"), + getText(configFile >> "CfgMagazines" >> _magazine >> "picture"), + {_this call FUNC(takeAmmo)}, + {true}, + {}, + [_magazine, _vehicle]] call EFUNC(interact_menu,createAction); + _actions pushBack [_action, [], _target]; + _magazineHelper pushBack _magazine; + _needToAdd = true; + } else { + if (((_vehicle magazineTurretAmmo [_magazine, _turretPath]) < getNumber (configFile >> "CfgMagazines" >> _magazine >> "count")) && !(_magazine in _magazineHelper)) then { + _action = [_magazine, + getText(configFile >> "CfgMagazines" >> _magazine >> "displayName"), + getText(configFile >> "CfgMagazines" >> _magazine >> "picture"), + {_this call FUNC(takeAmmo)}, + {true}, + {}, + [_magazine, _vehicle]] call EFUNC(interact_menu,createAction); + _actions pushBack [_action, [], _target]; + _magazineHelper pushBack _magazine; + _needToAdd = true; + }; + }; + } forEach _magazines; + } forEach REARM_TURRET_PATHS; + }; + if (_needToAdd && !(_vehicle getVariable [QGVAR(disabled), false])) then { + _icon = getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "Icon"); + if !((_icon select [0, 1]) == "\") then { + _icon = ""; + }; + if (GVAR(level) == 0) then { + _action = [_vehicle, + getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName"), + _icon, + {_this call FUNC(rearmEntireVehicle)}, + {true}, + {}, + _vehicle] call EFUNC(interact_menu,createAction); + _vehicleActions pushBack [_action, [], _target]; + } else { + _action = [_vehicle, + getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName"), + _icon, + {}, + {true}, + {}, + []] call EFUNC(interact_menu,createAction); + _vehicleActions pushBack [_action, _actions, _target]; + }; + }; +} forEach _vehicles; + +_vehicleActions diff --git a/addons/rearm/functions/fnc_canRearm.sqf b/addons/rearm/functions/fnc_canRearm.sqf new file mode 100644 index 0000000000..834e6a9202 --- /dev/null +++ b/addons/rearm/functions/fnc_canRearm.sqf @@ -0,0 +1,29 @@ +/* + * Author: GitHawk, Jonpas + * Check if a unit can rearm. + * + * Arguments: + * 0: Target + * 1: Unit + * + * Return Value: + * Can Rearm + * + * Example: + * [player, tank] call ace_rearm_fnc_canRearm + * + * Public: No + */ +#include "script_component.hpp" + +private ["_dummy","_magazineClass"]; +params ["_target", "_unit"]; + +if (GVAR(level) == 0 || {isNull _unit} || {!(_unit isKindOf "CAManBase")} || {!local _unit} || {_target distance _unit > REARM_ACTION_DISTANCE} || {_target getVariable [QGVAR(disabled), false]}) exitWith {false}; + +_dummy = _unit getVariable [QGVAR(dummy), objNull]; +if (isNull _dummy) exitwith {false}; +_magazineClass = _dummy getVariable QGVAR(magazineClass); +if (isNil "_magazineClass") exitWith {false}; + +([_target, _magazineClass] call FUNC(getNeedRearmMagazines)) select 0 diff --git a/addons/rearm/functions/fnc_canStoreAmmo.sqf b/addons/rearm/functions/fnc_canStoreAmmo.sqf new file mode 100644 index 0000000000..4018775d43 --- /dev/null +++ b/addons/rearm/functions/fnc_canStoreAmmo.sqf @@ -0,0 +1,25 @@ +/* + * Author: GitHawk + * Check if a unit can store ammo in an ammo truck. + * + * Arguments: + * 0: Target + * 1: Unit + * + * Return Value: + * Can Store Ammo + * + * Example: + * [player, tank] call ace_rearm_fnc_canStoreAmmo + * + * Public: No + */ +#include "script_component.hpp" + +params ["_target", "_unit"]; + +!(isNull _unit || + {!(_unit isKindOf "CAManBase")} || + {!local _unit} || + {(_target distance _unit) > REARM_ACTION_DISTANCE} || + {isNull (_unit getVariable [QGVAR(dummy), objNull])}) diff --git a/addons/rearm/functions/fnc_canTakeAmmo.sqf b/addons/rearm/functions/fnc_canTakeAmmo.sqf new file mode 100644 index 0000000000..43a96515e5 --- /dev/null +++ b/addons/rearm/functions/fnc_canTakeAmmo.sqf @@ -0,0 +1,25 @@ +/* + * Author: GitHawk + * Check if a unit can pick up ammo. + * + * Arguments: + * 0: Target + * 1: Unit + * + * Return Value: + * Can Pick Up Ammo + * + * Example: + * [player, tank] call ace_rearm_fnc_canTakeAmmo + * + * Public: No + */ +#include "script_component.hpp" + +params ["_target", "_unit"]; + +!(isNull _unit || + {!(_unit isKindOf "CAManBase")} || + {!local _unit} || + {(_target distance _unit) > REARM_ACTION_DISTANCE} || + {!isNull (_unit getVariable [QGVAR(dummy), objNull])}) diff --git a/addons/rearm/functions/fnc_createDummy.sqf b/addons/rearm/functions/fnc_createDummy.sqf new file mode 100644 index 0000000000..f9d335c08a --- /dev/null +++ b/addons/rearm/functions/fnc_createDummy.sqf @@ -0,0 +1,33 @@ +/* + * Author: GitHawk + * Creates a carryable ammunition dummy object. + * + * Arguments: + * 0: Unit + * 1: Magazine Classname + * + * Return Value: + * Created Dummy + * + * Example: + * ["500Rnd_127x99_mag_Tracer_Red"] call ace_rearm_fnc_createDummy + * + * Public: No + */ +#include "script_component.hpp" + +private ["_ammo", "_dummyName", "_dummy"]; +params ["_unit", "_magazineClass"]; + +_ammo = getText (configFile >> "CfgMagazines" >> _magazineClass >> "ammo"); +_dummyName = getText (configFile >> "CfgAmmo" >> _ammo >> QGVAR(dummy)); +_dummy = objNull; +if !(_dummyName == "") then { + _dummy = _dummyName createVehicle (position _unit); +} else { + _dummy = QGVAR(defaultCarriedObject) createVehicle (position _unit); +}; +_dummy allowDamage false; +_dummy setVariable [QGVAR(magazineClass), _magazineClass, true]; + +_dummy diff --git a/addons/rearm/functions/fnc_dropAmmo.sqf b/addons/rearm/functions/fnc_dropAmmo.sqf new file mode 100644 index 0000000000..8fc9ba4945 --- /dev/null +++ b/addons/rearm/functions/fnc_dropAmmo.sqf @@ -0,0 +1,43 @@ +/* + * Author: GitHawk + * Drops a magazine, optionally deletes it and optionally unholsters the wepaon. + * + * Arguments: + * 0: Unit + * 1: Delete dummy object (optional) + * 2: Unholster Weapon (optional) + * + * Return Value: + * None + * + * Example: + * [player, true, true] call ace_rearm_fnc_dropAmmo + * + * Public: No + */ +#include "script_component.hpp" + +private ["_dummy", "_actionID"]; +params ["_unit", ["_delete", false], ["_unholster", true]]; + +_dummy = _unit getVariable [QGVAR(dummy), objNull]; +if !(isNull _dummy) then { + detach _dummy; + if (_delete) then { + deleteVehicle _dummy; + } else { + _dummy setVelocity [0,0,-0.1]; + }; + _unit setVariable [QGVAR(dummy), objNull]; + //_unit setVariable [QEGVAR(dragging,isCarrying), false, true]; // breaks things, since it hides interact menu on _target +}; +_actionID = _unit getVariable [QGVAR(ReleaseActionID), -1]; +if (_actionID != -1) then { + _unit removeAction _actionID; + _unit setVariable [QGVAR(ReleaseActionID), nil]; +}; +[_unit, QGVAR(vehRearm), false] call EFUNC(common,setForceWalkStatus); + +if (_unholster) then { + REARM_UNHOLSTER_WEAPON +}; diff --git a/addons/rearm/functions/fnc_getConfigMagazines.sqf b/addons/rearm/functions/fnc_getConfigMagazines.sqf new file mode 100644 index 0000000000..9662f30ce7 --- /dev/null +++ b/addons/rearm/functions/fnc_getConfigMagazines.sqf @@ -0,0 +1,53 @@ +/* + * Author: GitHawk, Jonpas + * Returns all magazines a turret can hold according to config. + * + * Arguments: + * 0: Target + * 1: Turret Path + * + * Return Value: + * Magazine classes in TurretPath + * + * Example: + * [vehicle, [0]] call ace_rearm_fnc_getConfigMagazines + * + * Public: No + */ +#include "script_component.hpp" + +params ["_target", "_turretPath"]; + +if (isNull _target) exitWith {[]}; + +_cfg = configFile >> "CfgVehicles" >> (typeOf _target) >> "Turrets"; + +if (count _turretPath == 1) then { + _turretPath params ["_subPath"]; + + if (_subPath == -1) exitWith { + _cfg = configFile >> "CfgVehicles" >> (typeOf _target); + }; + + if (count _cfg > _subPath) then { + _cfg = _cfg select _subPath; + } else { + _cfg = nil; + }; +} else { + _turretPath params ["", "_subPath"]; + if (count _cfg > 0) then { + _cfg = (_cfg select 0) >> "Turrets"; + if (count _cfg > _subPath) then { + _cfg = _cfg select _subPath; + } else { + _cfg = nil; + }; + } else { + _cfg = nil; + }; +}; + +if !(isClass _cfg) exitWith {[]}; + +getArray (_cfg >> "magazines") diff --git a/addons/rearm/functions/fnc_getMaxMagazines.sqf b/addons/rearm/functions/fnc_getMaxMagazines.sqf new file mode 100644 index 0000000000..632b5e5918 --- /dev/null +++ b/addons/rearm/functions/fnc_getMaxMagazines.sqf @@ -0,0 +1,26 @@ +/* + * Author: GitHawk, Jonpas + * Calculates the maximum number of magazines a turret can hold according to config. + * + * Arguments: + * 0: Target + * 1: Turret Path + * 2: Magazine Classname + * + * Return Value: + * Number of magazines on the turret path + * + * Example: + * [vehicle, [0], "500Rnd_127x99_mag_Tracer_Red"] call ace_rearm_fnc_getMaxMagazines + * + * Public: No + */ +#include "script_component.hpp" + +private ["_count", "_cfg"]; +params ["_target", "_turretPath", "_magazineClass"]; + +if (isNull _target) exitWith {0}; + +_count = {_x == _magazineClass} count ([_target, _turretPath] call FUNC(getConfigMagazines)); +_count diff --git a/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf b/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf new file mode 100644 index 0000000000..7a591c6c32 --- /dev/null +++ b/addons/rearm/functions/fnc_getNeedRearmMagazines.sqf @@ -0,0 +1,49 @@ +/* + * Author: GitHawk, Jonpas + * Get rearm return value. + * + * Arguments: + * 0: Target + * 1: Magazine Classname + * + * Return Value: + * Return Value + * 0: Can Rearm + * 1: TurretPath + * 2: Magazine Classname + * + * Example: + * [tank, "mag"] call ace_rearm_fnc_getNeedRearmMagazines + * + * Public: No + */ +#include "script_component.hpp" + +private ["_return", "_magazines", "_cnt"]; +params ["_target", "_magazineClass"]; + +_return = [false, [], 0]; +{ + _magazines = []; + if (_x isEqualTo [-1]) then { + _magazines = [_target, _x] call FUNC(getConfigMagazines); + } else { + _magazines = _target magazinesTurret _x; + }; + + if (_magazineClass in _magazines) then { + _cnt = {_x == _magazineClass} count (_target magazinesTurret _x); + + if ((_target magazineTurretAmmo [_magazineClass, _x]) < getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count")) exitWith { + _return = [true, _x, _cnt]; + }; + + if (_cnt < ([_target, _x, _magazineClass] call FUNC(getMaxMagazines))) exitWith { + _return = [true, _x, _cnt]; + }; + }; + + if (_return select 0) exitWith {}; +} forEach REARM_TURRET_PATHS; + +_return diff --git a/addons/rearm/functions/fnc_grabAmmo.sqf b/addons/rearm/functions/fnc_grabAmmo.sqf new file mode 100644 index 0000000000..9b09d1282d --- /dev/null +++ b/addons/rearm/functions/fnc_grabAmmo.sqf @@ -0,0 +1,53 @@ +/* + * Author: GitHawk + * Grabs an dummy ammo. + * + * Arguments: + * 0: Ammo Dummy + * 1: Unit + * + * Return Value: + * None + * + * Example: + * [dummy, player] call ace_rearm_fnc_grabAmmo + * + * Public: No + */ +#include "script_component.hpp" + +params ["_dummy", "_unit"]; + +REARM_HOLSTER_WEAPON +[_unit, QGVAR(vehRearm), true] call EFUNC(common,setForceWalkStatus); + +[ + 5, + [_dummy, _unit], + { + private ["_actionID"]; + params ["_args"]; + _args params ["_dummy", "_unit"]; + [_dummy, _unit] call FUNC(pickUpAmmo); + + _actionID = _unit getVariable [QGVAR(ReleaseActionID), -1]; + if (_actionID != -1) then { + _unit removeAction _actionID; + }; + _actionID = _unit addAction [ + format ["%1", localize ELSTRING(dragging,Drop)], + '(_this select 0) call FUNC(dropAmmo)', + nil, + 20, + false, + true, + "", + '!isNull (_target getVariable [QGVAR(dummy), objNull])' + ]; + _unit setVariable [QGVAR(ReleaseActionID), _actionID]; + }, + "", + localize LSTRING(GrabAction), + {true}, + ["isnotinside"] +] call EFUNC(common,progressBar); diff --git a/addons/rearm/functions/fnc_handleKilled.sqf b/addons/rearm/functions/fnc_handleKilled.sqf new file mode 100644 index 0000000000..b0cdabaed5 --- /dev/null +++ b/addons/rearm/functions/fnc_handleKilled.sqf @@ -0,0 +1,23 @@ +/* + * Author: GitHawk, Jonpas + * Handles medical on set dead event. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [unit] call ace_rearm_fnc_handleKilled + * + * Public: No + */ +#include "script_component.hpp" + +params ["_unit"]; + +if (!local _unit) exitWith {}; + +_unit setVariable [QGVAR(selectedWeaponOnRearm), nil]; +[_unit, false, false] call FUNC(dropAmmo); diff --git a/addons/rearm/functions/fnc_handleUnconscious.sqf b/addons/rearm/functions/fnc_handleUnconscious.sqf new file mode 100644 index 0000000000..f9d703f4ec --- /dev/null +++ b/addons/rearm/functions/fnc_handleUnconscious.sqf @@ -0,0 +1,23 @@ +/* + * Author: GitHawk, Jonpas + * Handles medical on unconscious event. + * + * Arguments: + * 0: Unit + * 1: Is Unconscious + * + * Return Value: + * None + * + * Example: + * [unit] call ace_rearm_fnc_handleUnconscious + * + * Public: No + */ +#include "script_component.hpp" + +params ["_unit", "_isUnconscious"]; + +if (!local _unit || {!_isUnconscious}) exitWith {}; + +[_unit, false, false] call FUNC(dropAmmo); diff --git a/addons/rearm/functions/fnc_makeDummy.sqf b/addons/rearm/functions/fnc_makeDummy.sqf new file mode 100644 index 0000000000..97ab46fdbc --- /dev/null +++ b/addons/rearm/functions/fnc_makeDummy.sqf @@ -0,0 +1,23 @@ +/* + * Author: GitHawk + * Make a dummy object by disabling collision and turning it. + * + * Arguments: + * 0: Object + * 1: Vector dirAndUp + * + * Return Value: + * None + * + * Example: + * [dummy, [[1,0,0],[0,0,1]]] call ace_rearm_fnc_makeDummy + * + * Public: No + */ +#include "script_component.hpp" + +params ["_obj", "_dirAndUp"]; + +_obj setVectorDirAndUp _dirAndUp; +_obj allowDamage false; +player disableCollisionWith _obj; diff --git a/addons/rearm/functions/fnc_moduleRearmSettings.sqf b/addons/rearm/functions/fnc_moduleRearmSettings.sqf new file mode 100644 index 0000000000..ec5edd1666 --- /dev/null +++ b/addons/rearm/functions/fnc_moduleRearmSettings.sqf @@ -0,0 +1,26 @@ +/* + * Author: GitHawk + * Module for adjusting the refuel settings. + * + * Arguments: + * 0: The module logic + * 1: Synchronized units + * 2: Activated + * + * Return Value: + * None + * + * Example; + * function = "ace_rearm_fnc_moduleRearmSettings" + * + * Public: No + */ +#include "script_component.hpp" + +params ["_logic", "", "_activated"]; + +if (!_activated) exitWith {}; + +[_logic, QGVAR(level), "level"] call EFUNC(common,readSettingFromModule); + +diag_log text format ["[ACE]: Rearm Module Initialized on level: %1", GVAR(level)]; diff --git a/addons/rearm/functions/fnc_pickUpAmmo.sqf b/addons/rearm/functions/fnc_pickUpAmmo.sqf new file mode 100644 index 0000000000..eaaa55ade6 --- /dev/null +++ b/addons/rearm/functions/fnc_pickUpAmmo.sqf @@ -0,0 +1,31 @@ +/* + * Author: GitHawk + * Starts progress bar for picking up a specific kind of magazine from the ground. + * + * Arguments: + * 0: Ammo Dummy + * 1: Unit + * + * Return Value: + * None + * + * Example: + * [target, player] call ace_rearm_fnc_pickUpAmmo + * + * Public: No + */ +#include "script_component.hpp" + +private ["_magazineClass"]; +params ["_target", "_unit"]; + +_dummy = _unit getVariable [QGVAR(dummy), objNull]; +if !(isNull _dummy) exitWith {}; + +//_target attachTo [_unit, [0,0.7,0], "pelvis"]; +_target attachTo [_unit, [0,1,0], "pelvis"]; +{ + [[_target, [[-1,0,0],[0,0,1]]], QFUNC(makeDummy), _x] call EFUNC(common,execRemoteFnc); +} count (position _unit nearObjects ["CAManBase", 100]); +_unit setVariable [QGVAR(dummy), _target]; +//_unit setVariable [QEGVAR(dragging,isCarrying), true, true]; // breaks things, since it hides interact menu on _target diff --git a/addons/rearm/functions/fnc_rearm.sqf b/addons/rearm/functions/fnc_rearm.sqf new file mode 100644 index 0000000000..3208dbfb6f --- /dev/null +++ b/addons/rearm/functions/fnc_rearm.sqf @@ -0,0 +1,75 @@ +/* + * Author: GitHawk + * Starts progress bar for rearming a vehicle. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [player] call ace_rearm_fnc_rearm + * + * Public: No + */ +#include "script_component.hpp" + +private ["_magazineClass", "_ammo", "_tmpCal", "_cal", "_idx", "_needRearmMags", "_magazineDisplayName"]; +params ["_unit"]; + +_dummy = _unit getVariable [QGVAR(dummy), objNull]; +if (isNull _dummy) exitwith {false}; +_magazineClass = _dummy getVariable QGVAR(magazineClass); +if (isNil "_magazineClass") exitWith {false}; + +_ammo = getText (configFile >> "CfgMagazines" >> _magazineClass >> "ammo"); +_tmpCal = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_caliber"); +_cal = 8; +if (_tmpCal > 0) then { + _cal = _tmpCal; +} else { + _tmpCal = getNumber (configFile >> "CfgAmmo" >> _ammo >> QGVAR(caliber)); + if (_tmpCal > 0) then { + _cal = _tmpCal; + } else { + diag_log format ["[ACE] ERROR: Undefined Ammo [%1 : %2]", _ammo, inheritsFrom (configFile >> "CfgAmmo" >> _ammo)]; + if (_ammo isKindOf "BulletBase") then { + _cal = 8; + } else { + _cal = 100; + }; + }; +}; +_cal = round _cal; +_idx = REARM_CALIBERS find _cal; +if (_idx == -1) then { + _idx = 2; +}; + +// Get magazines that can be rearmed +_needRearmMags = [_target, _magazineClass] call FUNC(getNeedRearmMagazines); +_needRearmMags params ["_needRearm", "_turretPath", "_cnt"]; + +// Exit if no magazines need rearming +if (!_needRearm) exitWith { + diag_log format ["[ACE] ERROR: Could not find turret for %1 in %2", _magazineClass, typeOf _target]; +}; + +//hint format ["Magazine: %1\nAmmo: %2\nCaliber: %3\nIndex: %4\nTurretPath: %5\nREARM_DURATION_REARM: %6\nCount: %7", _magazine, _ammo, _cal, _idx, _turretPath, (REARM_DURATION_REARM select _idx), (REARM_COUNT select _idx)]; + +_magazineDisplayName = getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"); +if (_magazineDisplayName == "") then { + _magazineDisplayName = _magazineClass; + diag_log format ["[ACE] ERROR: Magazine is missing display name [%1]", _magazineClass]; +}; + +[ + (REARM_DURATION_REARM select _idx), + [_target, _unit, _turretPath, _cnt, _magazineClass, (REARM_COUNT select _idx)], + FUNC(rearmSuccess), + "", + format [localize LSTRING(RearmAction), getText(configFile >> "CfgVehicles" >> (typeOf _target) >> "displayName"), _magazineDisplayName], + {true}, + ["isnotinside"] +] call EFUNC(common,progressBar); diff --git a/addons/rearm/functions/fnc_rearmEntireVehicle.sqf b/addons/rearm/functions/fnc_rearmEntireVehicle.sqf new file mode 100644 index 0000000000..c1c08dce52 --- /dev/null +++ b/addons/rearm/functions/fnc_rearmEntireVehicle.sqf @@ -0,0 +1,30 @@ +/* + * Author: GitHawk + * Starts progress bar for rearming an entire vehicle. + * + * Arguments: + * 0: Ammo Truck + * 1: Unit + * 2: Vehicle to be armed + * + * Return Value: + * None + * + * Example: + * [ammo_truck, player, tank] call ace_rearm_fnc_rearmEntireVehicle + * + * Public: No + */ +#include "script_component.hpp" + +params ["_target", "_unit", "_vehicle"]; // _target is for future possible finite ammo, _unit placeholder + +[ + 10, + _vehicle, + FUNC(rearmEntireVehicleSuccess), + "", + format [localize LSTRING(BasicRearmAction), getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName")], + {true}, + ["isnotinside"] +] call EFUNC(common,progressBar); diff --git a/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf b/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf new file mode 100644 index 0000000000..cddce3ac3a --- /dev/null +++ b/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf @@ -0,0 +1,33 @@ +/* + * Author: GitHawk + * Rearm an entire vehicle. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * None + * + * Example: + * [tank] call ace_rearm_fnc_rearmEntireVehicleSuccess + * + * Public: No + */ +#include "script_component.hpp" + +private ["_turretPath", "_magazines", "_magazine", "_currentMagazines", "_maxMagazines", "_maxRounds", "_currentRounds"]; +params ["_vehicle"]; + +if (isServer) then { + { + _turretOwnerID = _vehicle turretOwner _x; + if (_turretOwnerID == 0) then { + [[_vehicle, _x], QFUNC(rearmEntireVehicleSuccessLocal), _target] call EFUNC(common,execRemoteFnc); + } else { + EGVAR(common,remoteFnc) = [[_vehicle, _x], QFUNC(rearmEntireVehicleSuccessLocal), 0]; + _turretOwnerID publicVariableClient QEGVAR(common,remoteFnc); + }; + } count REARM_TURRET_PATHS; +} else { + [_this, QFUNC(rearmEntireVehicleSuccess), 1] call EFUNC(common,execRemoteFnc); +}; diff --git a/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf b/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf new file mode 100644 index 0000000000..962ffa4c0a --- /dev/null +++ b/addons/rearm/functions/fnc_rearmEntireVehicleSuccessLocal.sqf @@ -0,0 +1,48 @@ +/* + * Author: GitHawk + * Rearm an entire turret locally. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * None + * + * Example: + * [tank, [0]] call ace_rearm_fnc_rearmEntireVehicleSuccessLocal + * + * Public: No + */ +#include "script_component.hpp" + +private ["_magazines", "_magazine", "_currentMagazines", "_maxMagazines", "_maxRounds", "_currentRounds"]; +params ["_vehicle", "_turretPath"]; + +_magazines = []; +if (_turretPath isEqualTo [-1]) then { + _magazines = [_vehicle, _turretPath] call FUNC(getConfigMagazines); +} else { + _magazines = _vehicle magazinesTurret _turretPath; +}; +{ + _magazine = _x; + _currentMagazines = { _x == _magazine } count (_vehicle magazinesTurret _turretPath); + _maxMagazines = [_vehicle, _turretPath, _magazine] call FUNC(getMaxMagazines); + _maxRounds = getNumber (configFile >> "CfgMagazines" >> _magazine >> "count"); + _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; + }; + if (_currentMagazines < _maxMagazines) then { + _vehicle setMagazineTurretAmmo [_magazine, _maxRounds, _turretPath]; + for "_idx" from 1 to (_maxMagazines - _currentMagazines) do { + _vehicle addMagazineTurret [_magazine, _turretPath]; + }; + } else { + _vehicle setMagazineTurretAmmo [_magazine, _maxRounds, _turretPath]; + }; +} foreach _magazines; diff --git a/addons/rearm/functions/fnc_rearmSuccess.sqf b/addons/rearm/functions/fnc_rearmSuccess.sqf new file mode 100644 index 0000000000..7c9b151a39 --- /dev/null +++ b/addons/rearm/functions/fnc_rearmSuccess.sqf @@ -0,0 +1,44 @@ +/* + * Author: GitHawk + * Rearms a vehicle. + * + * Arguments: + * 0: Params + * 0: Target + * 1: Unit + * 2: Turret Path + * 3: Number of magazines + * 4: Magazine Classname + * 5: Number of rounds + * + * Return Value: + * None + * + * Example: + * [[vehicle, player, [-1], 2, "5000Rnd_762x51_Belt", 500]] call ace_rearm_fnc_rearmSuccess + * + * Public: No + */ +#include "script_component.hpp" + +private ["_dummy", "_weaponSelect", "_turretOwnerID"]; +params ["_args"]; +_args params ["_target", "_unit", "_turretPath", "_numMagazines", "_magazineClass", "_numRounds"]; + +//hint format ["Target: %1\nTurretPath: %2\nNumMagazines: %3\nMagazine: %4\nNumRounds: %5", _target, _turretPath, _numMagazines, _magazineClass, _numRounds]; + +if (local _unit) then { + [_unit, true, true] call FUNC(dropAmmo); +}; + +if (isServer) then { + _turretOwnerID = _target turretOwner _turretPath; + if (_turretOwnerID == 0) then { + [_this, QFUNC(rearmSuccessLocal), _target] call EFUNC(common,execRemoteFnc); + } else { + EGVAR(common,remoteFnc) = [_this, QFUNC(rearmSuccessLocal), 0]; + _turretOwnerID publicVariableClient QEGVAR(common,remoteFnc); + }; +} else { + [_this, QFUNC(rearmSuccess), 1] call EFUNC(common,execRemoteFnc); +}; diff --git a/addons/rearm/functions/fnc_rearmSuccessLocal.sqf b/addons/rearm/functions/fnc_rearmSuccessLocal.sqf new file mode 100644 index 0000000000..f869690808 --- /dev/null +++ b/addons/rearm/functions/fnc_rearmSuccessLocal.sqf @@ -0,0 +1,82 @@ +/* + * Author: GitHawk + * Rearms a vehicle on the turret owner. + * + * Arguments: + * 0: Params + * 0: Target + * 1: Unit + * 2: Turret Path + * 3: Number of magazines + * 4: Magazine Classname + * 5: Number of rounds + * + * Return Value: + * None + * + * Example: + * [[vehicle, player, [-1], 2, "5000Rnd_762x51_Belt", 500]] call ace_rearm_fnc_rearmSuccess + * + * Public: No + */ +#include "script_component.hpp" + +private ["_rounds", "_currentRounds", "_maxMagazines", "_dummy", "_weaponSelect"]; +params ["_args"]; +_args params ["_target", "_unit", "_turretPath", "_numMagazines", "_magazineClass", "_numRounds"]; + +//hint format ["Target: %1\nTurretPath: %2\nNumMagazines: %3\nMagazine: %4\nNumRounds: %5\nUnit: %6", _target, _turretPath, _numMagazines, _magazineClass, _numRounds, _unit]; + +_rounds = getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "count"); +_currentRounds = 0; + +_maxMagazines = [_target, _turretPath, _magazineClass] call FUNC(getMaxMagazines); +if (_maxMagazines == 1) then { + if (GVAR(level) == 1) then { + // Fill magazine completely + _target setMagazineTurretAmmo [_magazineClass, _rounds, _turretPath]; + ["displayTextStructured", [_unit], [[LSTRING(Hint_RearmedTriple), _rounds, + getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"), + getText(configFile >> "CfgVehicles" >> (typeOf _target) >> "displayName")], 3, _unit]] call EFUNC(common,targetEvent); + } else { + // Fill only at most _numRounds + _target setMagazineTurretAmmo [_magazineClass, ((_target magazineTurretAmmo [_magazineClass, _turretPath]) + _numRounds) min _rounds, _turretPath]; + ["displayTextStructured", [_unit], [[LSTRING(Hint_RearmedTriple), _numRounds, + getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"), + getText(configFile >> "CfgVehicles" >> (typeOf _target) >> "displayName")], 3, _unit]] call EFUNC(common,targetEvent); + }; +} else { + for "_idx" from 1 to _maxMagazines do { + _currentRounds = _target magazineTurretAmmo [_magazineClass, _turretPath]; + if (_currentRounds > 0) exitWith { + if (GVAR(level) == 2) then { + //hint format ["Target: %1\nTurretPath: %2\nNumMagazines: %3\nMaxMagazines %4\nMagazine: %5\nNumRounds: %6\nMagazine: %7", _target, _turretPath, _numMagazines, _maxMagazines, _currentRounds, _numRounds, _magazineClass]; + // Fill only at most _numRounds + if ((_currentRounds + _numRounds) > _rounds) then { + _target setMagazineTurretAmmo [_magazineClass, _rounds, _turretPath]; + if (_numMagazines < _maxMagazines) then { + _target addMagazineTurret [_magazineClass, _turretPath]; + _target setMagazineTurretAmmo [_magazineClass, _currentRounds + _numRounds - _rounds, _turretPath]; + }; + } else { + _target setMagazineTurretAmmo [_magazineClass, _currentRounds + _numRounds, _turretPath]; + }; + ["displayTextStructured", [_unit], [[LSTRING(Hint_RearmedTriple), _numRounds, + getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"), + getText(configFile >> "CfgVehicles" >> (typeOf _target) >> "displayName")], 3, _unit]] call EFUNC(common,targetEvent); + } else { + // Fill current magazine completely and fill next magazine partially + _target setMagazineTurretAmmo [_magazineClass, _rounds, _turretPath]; + if (_numMagazines < _maxMagazines) then { + _target addMagazineTurret [_magazineClass, _turretPath]; + _target setMagazineTurretAmmo [_magazineClass, _currentRounds, _turretPath]; + }; + ["displayTextStructured", [_unit], [[LSTRING(Hint_RearmedTriple), _rounds, + getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"), + getText(configFile >> "CfgVehicles" >> (typeOf _target) >> "displayName")], 3, _unit]] call EFUNC(common,targetEvent); + }; + }; + _target removeMagazineTurret [_magazineClass, _turretPath]; + _numMagazines = _numMagazines - 1; + }; +}; diff --git a/addons/rearm/functions/fnc_storeAmmo.sqf b/addons/rearm/functions/fnc_storeAmmo.sqf new file mode 100644 index 0000000000..e23efe0d7c --- /dev/null +++ b/addons/rearm/functions/fnc_storeAmmo.sqf @@ -0,0 +1,34 @@ +/* + * Author: GitHawk + * Stores ammo in an ammo truck. + * + * Arguments: + * 0: Target + * 1: Unit + * + * Return Value: + * None + * + * Example: + * [player, dummy] call ace_rearm_fnc_storeAmmo + * + * Public: No + */ +#include "script_component.hpp" + +private "_dummy"; +params ["_target", "_unit"]; + +_dummy = _unit getVariable [QGVAR(dummy), objNull]; +if (isNull _dummy) exitwith {}; + + +[ + 5, + _unit, + {params ["_unit"]; [_unit, true, true] call FUNC(dropAmmo)}, + "", + format [localize LSTRING(StoreAmmoAction), getText(configFile >> "CfgMagazines" >> (_dummy getVariable QGVAR(magazineClass)) >> "displayName"), getText(configFile >> "CfgVehicles" >> (typeOf _target) >> "displayName")], + {true}, + ["isnotinside"] +] call EFUNC(common,progressBar); diff --git a/addons/rearm/functions/fnc_takeAmmo.sqf b/addons/rearm/functions/fnc_takeAmmo.sqf new file mode 100644 index 0000000000..4f3ef7c9ef --- /dev/null +++ b/addons/rearm/functions/fnc_takeAmmo.sqf @@ -0,0 +1,61 @@ +/* + * Author: GitHawk + * Starts progress bar for picking up a specific kind of magazine from an ammo truck. + * + * Arguments: + * 0: Ammo Truck + * 1: Unit + * 2: Params + * 0: Magazine Classname + * 1: Vehicle to be armed + * + * Return Value: + * None + * + * Example: + * [ammo_truck, player, ["500Rnd_127x99_mag_Tracer_Red", tank]] call ace_rearm_fnc_takeAmmo + * + * Public: No + */ +#include "script_component.hpp" + +private ["_ammo", "_tmpCal", "_cal", "_idx"]; + +params ["_target", "_unit", "_args"]; +_args params ["_magazineClass", "_vehicle"]; + +_ammo = getText (configFile >> "CfgMagazines" >> _magazineClass >> "ammo"); +_tmpCal = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_caliber"); +_cal = 8; +if (_tmpCal > 0) then { + _cal = _tmpCal; +} else { + _tmpCal = getNumber (configFile >> "CfgAmmo" >> _ammo >> QGVAR(caliber)); + if (_tmpCal > 0) then { + _cal = _tmpCal; + } else { + diag_log format ["[ACE] ERROR: Undefined Ammo [%1 : %2]", _ammo, inheritsFrom (configFile >> "CfgAmmo" >> _ammo)]; + if (_ammo isKindOf "BulletBase") then { + _cal = 8; + } else { + _cal = 100; + }; + }; +}; +_cal = round _cal; +_idx = REARM_CALIBERS find _cal; +if (_idx == -1 ) then { + _idx = 2; +}; + +REARM_HOLSTER_WEAPON + +[ + (REARM_DURATION_TAKE select _idx), + [_unit, _magazineClass, _target], + FUNC(takeSuccess), + "", + format [localize LSTRING(TakeAction), getText(configFile >> "CfgMagazines" >> _magazineClass >> "displayName"), getText(configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "displayName")], + {true}, + ["isnotinside"] +] call EFUNC(common,progressBar); diff --git a/addons/rearm/functions/fnc_takeSuccess.sqf b/addons/rearm/functions/fnc_takeSuccess.sqf new file mode 100644 index 0000000000..952cfdee08 --- /dev/null +++ b/addons/rearm/functions/fnc_takeSuccess.sqf @@ -0,0 +1,39 @@ +/* + * Author: GitHawk + * Takes a magazine from an ammo truck. + * + * Arguments: + * 0: Params + * 0: Unit + * 1: Magazine Classname + * 2: Ammo Truck + * + * Return Value: + * None + * + * Example: + * [[player, "500Rnd_127x99_mag_Tracer_Red"]] call ace_rearm_fnc_takeSuccess + * + * Public: No + */ +#include "script_component.hpp" + +private ["_ammo", "_dummyName", "_dummy", "_actionID"]; +params ["_args"]; +_args params ["_unit", "_magazineClass", "_target"]; // _target is for future possible finite ammo + +[_unit, QGVAR(vehRearm), true] call EFUNC(common,setForceWalkStatus); +_dummy = [_unit, _magazineClass] call FUNC(createDummy); +[_dummy, _unit] call FUNC(pickUpAmmo); + +_actionID = _unit addAction [ + format ["%1", localize ELSTRING(dragging,Drop)], + '(_this select 0) call FUNC(dropAmmo)', + nil, + 20, + false, + true, + "", + '!isNull (_target getVariable [QGVAR(dummy), objNull])' +]; +_unit setVariable [QGVAR(ReleaseActionID), _actionID]; diff --git a/addons/rearm/functions/script_component.hpp b/addons/rearm/functions/script_component.hpp new file mode 100644 index 0000000000..515b56ddc7 --- /dev/null +++ b/addons/rearm/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\rearm\script_component.hpp" diff --git a/addons/rearm/script_component.hpp b/addons/rearm/script_component.hpp new file mode 100644 index 0000000000..e90e87a422 --- /dev/null +++ b/addons/rearm/script_component.hpp @@ -0,0 +1,31 @@ +#define COMPONENT rearm +#include "\z\ace\addons\main\script_mod.hpp" + +#ifdef DEBUG_ENABLED_REARM + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_REARM + #define DEBUG_SETTINGS DEBUG_SETTINGS_REARM +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + + +#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] +#define REARM_DURATION_REARM [ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 7, 7, 7, 7, 7, 8, 10, 10, 10, 10, 27, 20] +#define REARM_COUNT [500, 500, 400, 100, 50, 50, 40, 25, 34, 24, 10, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1] + + +#define REARM_HOLSTER_WEAPON \ + _unit setVariable [QGVAR(selectedWeaponOnRearm), currentWeapon _unit]; \ + _unit action ["SwitchWeapon", _unit, _unit, 99]; + +#define REARM_UNHOLSTER_WEAPON \ + _weaponSelect = _unit getVariable QGVAR(selectedWeaponOnRearm); \ + _unit selectWeapon _weaponSelect; \ + _unit setVariable [QGVAR(selectedWeaponOnRefuel), nil]; diff --git a/addons/rearm/stringtable.xml b/addons/rearm/stringtable.xml new file mode 100644 index 0000000000..5d7aaf199c --- /dev/null +++ b/addons/rearm/stringtable.xml @@ -0,0 +1,144 @@ + + + + + Rearm Settings + Aufmunitioniereinstellungen + + + This module allows you to tweak repair system settings. + + + Rearm Amount + Aufmunitioniermenge + + + How fast should a vehicle be rearmed? + Wie schnell soll ein Fahrzeug aufmunitioniert werden? + + + Entire Vehicle + Gesamtes Fahrzeug + + + Entire Magazine + Gesamtes Magazin + + + Amount based on caliber + Kaliberbasierte Anzahl + + + Rearm + Aufmunitionieren + + + Rearming %1 with %2 ... + Munitioniere %1 auf mit %2 ... + + + Rearming %1 ... + Munitioniere %1 auf ... + + + Taking %1 for %2 ... + Nehme %1 für %2 ... + + + Take ammo + Munition nehmen + + + Pick up ammo + Munition aufnehmen + + + Store ammo + Munition verstauen + + + Storing %1 in %2 ... + Verstaue %1 in %2 ... + + + Picking up ammo ... + Nehme Munition ... + + + Rearmed %1 rounds of %2 on %3 + %1 Schuss %2 an %3 aufmunitioniert + + + Smoke Screen + Smoke Screen + Kouřová clona + Écran de fumée + Rauchwand + Cortina fumogena + Zasłona dymna + Cortina de fumaça + Дым. завеса + Pantalla de humo + + + Flares + Flares + Světlice + Fusées + Leuchtkörper + Razzi luminosi + Flary + Sinalizadores + ЛТЦ + Bengalas + + + 30mm HEI + 30mm HEI + + + 30mm HEI-T + 30mm HEI-T + + + AIM-9 Sidewinder + AIM-9 Sidewinder + + + Wympel R-73 + Wympel R-73 + + + AGM-65 Maverick + AGM-65 Maverick + + + Kh-25MTP + Kh-25MTP + + + Hydra 70 HE + Hydra 70 HE + + + S-8 HE + S-8 HE + + + Hydra 70 AP + Hydra 70 AP + + + S-8 AP + S-8 AP + + + GBU-12 + GBU-12 + + + FAB-250M-54 + FAB-250M-54 + + + diff --git a/addons/rearm/ui/icon_module_rearm.paa b/addons/rearm/ui/icon_module_rearm.paa new file mode 100644 index 0000000000..173e3eaff7 Binary files /dev/null and b/addons/rearm/ui/icon_module_rearm.paa differ diff --git a/addons/rearm/ui/icon_rearm_interact.paa b/addons/rearm/ui/icon_rearm_interact.paa new file mode 100644 index 0000000000..fe2a9a1235 Binary files /dev/null and b/addons/rearm/ui/icon_rearm_interact.paa differ diff --git a/addons/refuel/$PBOPREFIX$ b/addons/refuel/$PBOPREFIX$ new file mode 100644 index 0000000000..2a68bfaf74 --- /dev/null +++ b/addons/refuel/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\refuel \ No newline at end of file diff --git a/addons/refuel/ACE_Settings.hpp b/addons/refuel/ACE_Settings.hpp new file mode 100644 index 0000000000..0ae0accaad --- /dev/null +++ b/addons/refuel/ACE_Settings.hpp @@ -0,0 +1,8 @@ +class ACE_Settings { + class GVAR(rate) { + displayName = CSTRING(RefuelSettings_speed_DisplayName); + description = CSTRING(RefuelSettings_speed_Description); + value = 1; + typeName = "SCALAR"; + }; +}; diff --git a/addons/refuel/CfgEventHandlers.hpp b/addons/refuel/CfgEventHandlers.hpp new file mode 100644 index 0000000000..f1a9f1a3c8 --- /dev/null +++ b/addons/refuel/CfgEventHandlers.hpp @@ -0,0 +1,27 @@ +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_postInit)); + }; +}; + +class Extended_Respawn_EventHandlers { + class CAManBase { + class ADDON { + respawn = QUOTE(call COMPILE_FILE(XEH_respawn)); + }; + }; +}; + +class Extended_Killed_EventHandlers { + class CAManBase { + class ADDON { + killed = QUOTE(_this call FUNC(handleKilled)); + }; + }; +}; \ No newline at end of file diff --git a/addons/refuel/CfgVehicles.hpp b/addons/refuel/CfgVehicles.hpp new file mode 100644 index 0000000000..33ddddb8b0 --- /dev/null +++ b/addons/refuel/CfgVehicles.hpp @@ -0,0 +1,631 @@ +#define MACRO_REFUEL_ACTIONS \ + class ACE_Actions: ACE_Actions { \ + class ACE_MainActions: ACE_MainActions { \ + class GVAR(Refuel) { \ + displayName = CSTRING(Refuel); \ + distance = REFUEL_ACTION_DISTANCE; \ + condition = "true"; \ + statement = ""; \ + showDisabled = 0; \ + priority = 2; \ + icon = PATHTOF(ui\icon_refuel_interact.paa); \ + class GVAR(TakeNozzle) { \ + displayName = CSTRING(TakeNozzle); \ + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTakeNozzle)); \ + statement = QUOTE([ARR_3(_player,_target,objNull)] call FUNC(TakeNozzle)); \ + exceptions[] = {"isNotInside"}; \ + icon = PATHTOF(ui\icon_refuel_interact.paa); \ + }; \ + class GVAR(CheckFuelCounter) { \ + displayName = CSTRING(CheckFuelCounter); \ + condition = "true"; \ + statement = QUOTE([ARR_2(_player,_target)] call FUNC(readFuelCounter)); \ + exceptions[] = {"isNotInside"}; \ + icon = PATHTOF(ui\icon_refuel_interact.paa); \ + }; \ + class GVAR(CheckFuel) { \ + displayName = CSTRING(CheckFuel); \ + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canCheckFuel)); \ + statement = QUOTE([ARR_2(_player,_target)] call FUNC(checkFuel)); \ + exceptions[] = {"isNotInside"}; \ + icon = PATHTOF(ui\icon_refuel_interact.paa); \ + }; \ + class GVAR(Connect) { \ + displayName = CSTRING(Connect); \ + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canConnectNozzle)); \ + statement = QUOTE([ARR_2(_player,_target)] call DFUNC(connectNozzle)); \ + exceptions[] = {"isNotInside"}; \ + icon = PATHTOF(ui\icon_refuel_interact.paa); \ + }; \ + class GVAR(Return) { \ + displayName = CSTRING(Return); \ + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canReturnNozzle)); \ + statement = QUOTE([ARR_2(_player,_target)] call DFUNC(returnNozzle)); \ + exceptions[] = {"isNotInside"}; \ + icon = PATHTOF(ui\icon_refuel_interact.paa); \ + }; \ + }; \ + }; \ + }; + +#define MACRO_CONNECT_ACTIONS \ + class ACE_Actions { \ + class ACE_MainActions { \ + class GVAR(Refuel) { \ + displayName = CSTRING(Refuel); \ + distance = REFUEL_ACTION_DISTANCE; \ + condition = "true"; \ + statement = ""; \ + showDisabled = 0; \ + priority = 2; \ + icon = PATHTOF(ui\icon_refuel_interact.paa); \ + class GVAR(Connect) { \ + displayName = CSTRING(Connect); \ + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canConnectNozzle)); \ + statement = QUOTE([ARR_2(_player,_target)] call DFUNC(connectNozzle)); \ + exceptions[] = {"isNotInside"}; \ + icon = PATHTOF(ui\icon_refuel_interact.paa); \ + }; \ + }; \ + }; \ + }; + +#define MACRO_NOZZLE_ACTIONS \ + class ACE_Actions { \ + class ACE_MainActions { \ + displayName = CSTRING(Refuel); \ + distance = REFUEL_ACTION_DISTANCE; \ + condition = "true"; \ + statement = ""; \ + showDisabled = 0; \ + priority = 2; \ + icon = PATHTOF(ui\icon_refuel_interact.paa); \ + class GVAR(PickUpNozzle) { \ + displayName = CSTRING(TakeNozzle); \ + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTakeNozzle)); \ + statement = QUOTE([ARR_3(_player,objNull,_target)] call FUNC(TakeNozzle)); \ + exceptions[] = {"isNotInside"}; \ + icon = PATHTOF(ui\icon_refuel_interact.paa); \ + }; \ + class GVAR(TurnOn) { \ + displayName = CSTRING(TurnOn); \ + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTurnOn)); \ + statement = QUOTE([ARR_2(_player,_target)] call DFUNC(turnOn)); \ + exceptions[] = {"isNotInside"}; \ + icon = PATHTOF(ui\icon_refuel_interact.paa); \ + }; \ + class GVAR(TurnOff) { \ + displayName = CSTRING(TurnOff); \ + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTurnOff)); \ + statement = QUOTE([ARR_2(_player,_target)] call DFUNC(turnOff)); \ + exceptions[] = {"isNotInside"}; \ + icon = PATHTOF(ui\icon_refuel_interact.paa); \ + }; \ + class GVAR(Disconnect) { \ + displayName = CSTRING(Disconnect); \ + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canDisconnect)); \ + statement = QUOTE([ARR_2(_player,_target)] call DFUNC(disconnect)); \ + exceptions[] = {"isNotInside"}; \ + icon = PATHTOF(ui\icon_refuel_interact.paa); \ + }; \ + }; \ + }; + +class CfgVehicles { + class ACE_Module; + class ACE_moduleRefuelSettings : ACE_Module { + scope = 2; + displayName = CSTRING(RefuelSettings_Module_DisplayName); + icon = QUOTE(PATHTOF(ui\icon_module_refuel.paa)); + category = "ACE_Logistics"; + function = QFUNC(moduleRefuelSettings); + functionPriority = 1; + isGlobal = 0; + isTriggerActivated = 0; + author = ECSTRING(common,ACETeam); + class Arguments { + class rate { + displayName = CSTRING(RefuelSettings_speed_DisplayName); + description = CSTRING(RefuelSettings_speed_Description); + typeName = "NUMBER"; + defaultValue = 10; + }; + }; + }; + + class ThingX; + class ACE_refuel_fuelNozzle : ThingX { + XEH_ENABLED; + MACRO_NOZZLE_ACTIONS + displayName = QGVAR(fuelNozzle); + scope = 2; + scopeCurator = 2; + model = "\A3\Structures_F_Heli\VR\Helpers\Sign_sphere10cm_F.p3d"; + }; + + class All; + + class Static : All {}; + + class Building : Static {}; + + class NonStrategic : Building {}; + + class HouseBase: NonStrategic {}; + + class House: HouseBase {}; + + class House_F : House {}; + + class House_Small_F : House_F { + class ACE_Actions { + class ACE_MainActions { + displayName = ECSTRING(interaction,MainAction); + selection = ""; + distance = 10; + condition = "true"; + }; + }; + }; + + class AllVehicles : All { + GVAR(flowRate) = 1; + }; + class Land : AllVehicles {}; + class LandVehicle : Land {}; + class Car : LandVehicle { + MACRO_CONNECT_ACTIONS + }; + + class Tank : LandVehicle { + MACRO_CONNECT_ACTIONS + GVAR(flowRate) = 4; + }; + + class StaticWeapon : LandVehicle { + MACRO_CONNECT_ACTIONS + }; + + class Air : AllVehicles { + GVAR(flowRate) = 8; + }; + + class Helicopter : Air { + MACRO_CONNECT_ACTIONS + GVAR(fuelCapacity) = 1500; + }; + + class Helicopter_Base_F : Helicopter {}; + + class Helicopter_Base_H : Helicopter_Base_F { + GVAR(fuelCapacity) = 3000; + }; + + class Plane : Air { + MACRO_CONNECT_ACTIONS + GVAR(fuelCapacity) = 2000; + GVAR(flowRate) = 16; + }; + + class Plane_Base_F : Plane {}; + + class Ship : AllVehicles {}; + + class Ship_F : Ship { + MACRO_CONNECT_ACTIONS + GVAR(fuelCapacity) = 2000; + GVAR(flowRate) = 4; + }; + + class Boat_Civil_01_base_F : Ship_F { + GVAR(fuelCapacity) = 200; + }; + + class Boat_F : Ship_F { + GVAR(flowRate) = 1; + }; + + class Boat_Armed_01_base_F : Boat_F { + GVAR(fuelCapacity) = 300; + }; + class Rubber_duck_base_F : Boat_F { + GVAR(fuelCapacity) = 30; + }; + class SDV_01_base_F : Boat_F { + // SDV is using electrical propulsion + GVAR(fuelCapacity) = 0; + }; + + class Car_F : Car { + // Assuming large vehicle tank + GVAR(fuelCapacity) = 60; + }; + + class Kart_01_Base_F : Car_F { + GVAR(fuelCapacity) = 8; + }; + + class Offroad_01_base_F: Car_F {}; + + class Wheeled_APC_F: Car_F { + // Assuming average APC tank + GVAR(fuelCapacity) = 300; + }; + + class Hatchback_01_base_F: Car_F { + // Assume normal vehicle tank + GVAR(fuelCapacity) = 50; + }; + + class Quadbike_01_base_F : Car_F { + // Assuming usual Yamaha quad + GVAR(fuelCapacity) = 10; + }; + + class MRAP_01_base_F: Car_F { + // M-ATV + // No data, assuming similar to Fennek + GVAR(fuelCapacity) = 230; + }; + + class MRAP_02_base_F: Car_F { + // Punisher + // No data, assuming similar to Fennek + GVAR(fuelCapacity) = 230; + }; + + class MRAP_03_base_F: Car_F { + // Fennek + GVAR(fuelCapacity) = 230; + }; + + class APC_Wheeled_01_base_F: Wheeled_APC_F { + // Patria = LAV + GVAR(fuelCapacity) = 269; + }; + + class Truck_F : Car_F { + GVAR(fuelCapacity) = 400; + GVAR(flowRate) = 2; + }; + + class Truck_01_base_F: Truck_F { + // HEMTT + GVAR(fuelCapacity) = 583; + }; + + class B_Truck_01_transport_F : Truck_01_base_F {}; + + class B_Truck_01_mover_F: B_Truck_01_transport_F {}; + + class Truck_02_base_F: Truck_F { + // KamAZ + // Assuming similar to Ural + GVAR(fuelCapacity) = 400; + }; + + class Truck_03_base_F: Truck_F { + // Tempest + // Assuming heavier than KamAZ + GVAR(fuelCapacity) = 600; + }; + + class Van_01_base_F : Truck_F { + // Small Truck + // Assuming 80L as in Ford Transit + GVAR(fuelCapacity) = 80; + }; + + class Van_01_fuel_base_F: Van_01_base_F { + transportFuel = 0; //1k + MACRO_REFUEL_ACTIONS + GVAR(hooks[]) = {{0.38,-3.17,-.7},{-0.41,-3.17,-.7}}; + GVAR(fuelCargo) = 2000; + }; + + class Tank_F: Tank { + GVAR(fuelCapacity) = 1200; + }; + + class APC_Tracked_01_base_F: Tank_F { + // Namer + // Assuming Merkava fuel + GVAR(fuelCapacity) = 1400; + }; + + class B_APC_Tracked_01_base_F: APC_Tracked_01_base_F {}; + + class B_APC_Tracked_01_CRV_F: B_APC_Tracked_01_base_F { + transportFuel = 0; //3k + MACRO_REFUEL_ACTIONS + GVAR(hooks[]) = {{-1.08,-4.81,-.8}}; + GVAR(fuelCargo) = 1000; + }; + + class APC_Tracked_02_base_F : Tank_F { + // BM-2T + // Assuming 1 L/km + GVAR(fuelCapacity) = 1000; + }; + + class APC_Tracked_03_base_F: Tank_F { + // FV 510 + // Assuming 1 L/km + GVAR(fuelCapacity) = 660; + }; + + class MBT_01_base_F: Tank_F { + // Merkava IV + GVAR(fuelCapacity) = 1400; + }; + + class MBT_02_base_F: Tank_F { + // T100 Black Eagle + // Assuming T80 + GVAR(fuelCapacity) = 1100; + }; + + class MBT_03_base_F: Tank_F { + // Leopard + GVAR(fuelCapacity) = 1160; + }; + + class MBT_01_arty_base_F : MBT_01_base_F { + // Assuming similar 2S3 + GVAR(fuelCapacity) = 830; + }; + + class MBT_02_arty_base_F : MBT_02_base_F { + // Assuming similar 2S3 + GVAR(fuelCapacity) = 830; + }; + + class Heli_Attack_01_base_F : Helicopter_Base_F { + // Commanche + }; + + class Heli_Attack_02_base_F : Helicopter_Base_F { + // Mi-48 Kajman + }; + + class Heli_Light_01_base_F : Helicopter_Base_H { + // MH-6 + GVAR(fuelCapacity) = 242; + }; + + class Heli_Light_02_base_F : Helicopter_Base_H { + // Ka-60 Kasatka + GVAR(fuelCapacity) = 1450; + }; + + class Heli_light_03_base_F : Helicopter_Base_F { + // AW159 + GVAR(fuelCapacity) = 1004; + }; + + class Heli_Transport_01_base_F : Helicopter_Base_H { + // Ghost Hawk + // Assuming similar UH60 + GVAR(fuelCapacity) = 1360; + }; + + class Heli_Transport_02_base_F : Helicopter_Base_H { + // AW101 + GVAR(fuelCapacity) = 3222; + }; + + class Heli_Transport_03_base_F : Helicopter_Base_H { + // Chinook 47I + GVAR(fuelCapacity) = 3914; + }; + + class Heli_Transport_04_base_F : Helicopter_Base_H { + // Mi-290 Taru + GVAR(fuelCapacity) = 3914; + }; + + class Plane_CAS_01_base_F : Plane_Base_F { + // Assuming similar to A10 + GVAR(fuelCapacity) = 6223; + }; + + class Plane_CAS_02_base_F : Plane_Base_F { + // Yak-130 + GVAR(fuelCapacity) = 2099; + }; + + class UAV_01_base_F : Helicopter_Base_F { + // Darter is electrical + GVAR(fuelCapacity) = 0; + }; + + class UAV : Plane {}; + + class UAV_02_base_F : UAV { + // Assuming similar YAHBON-R2 + GVAR(fuelCapacity) = 270; + }; + + class UGV_01_base_F : Car_F { + // Stomper + GVAR(fuelCapacity) = 100; + }; + + class Plane_Fighter_03_base_F : Plane_Base_F { + // L-159 ALCA + GVAR(fuelCapacity) = 1914; + }; + + // Vanilla fuel vehicles + class Truck_02_fuel_base_F : Truck_02_base_F { + transportFuel = 0; //3k + MACRO_REFUEL_ACTIONS + GVAR(hooks[]) = {{0.99,-3.47,-0.67},{-1.04,-3.47,-0.67}}; + GVAR(fuelCargo) = 10000; + }; + + class B_Truck_01_fuel_F : B_Truck_01_mover_F { + transportFuel = 0; //3k + MACRO_REFUEL_ACTIONS + GVAR(hooks[]) = {{.28,-4.99,-.3},{-.25,-4.99,-.3}}; + GVAR(fuelCargo) = 10000; + }; + + class O_Truck_03_fuel_F : Truck_03_base_F { + transportFuel = 0; //3k + MACRO_REFUEL_ACTIONS + GVAR(hooks[]) = {{1.3,-1.59,-.62},{-1.16,-1.59,-.62}}; + GVAR(fuelCargo) = 10000; + }; + + class Slingload_base_F; + class Slingload_01_Base_F: Slingload_base_F { + class ACE_Actions { + class ACE_MainActions { + displayName = ECSTRING(interaction,MainAction); + selection = ""; + distance = 10; + condition = "true"; + }; + }; + }; + + class B_Slingload_01_Fuel_F : Slingload_01_Base_F { + XEH_ENABLED; + transportFuel = 0; //3k + MACRO_REFUEL_ACTIONS + GVAR(hooks[]) = {{0.55,3.02,-0.5},{-0.52,3.02,-0.5}}; + GVAR(fuelCargo) = 10000; + }; + + class O_Heli_Transport_04_fuel_F : Heli_Transport_04_base_F { + transportFuel = 0; //3k + MACRO_REFUEL_ACTIONS + GVAR(hooks[]) = {{-1.52,1.14,-1.18}}; + GVAR(fuelCargo) = 10000; + }; + + class Pod_Heli_Transport_04_base_F: StaticWeapon {}; + class Land_Pod_Heli_Transport_04_fuel_F: Pod_Heli_Transport_04_base_F { + transportFuel = 0; //3k + MACRO_REFUEL_ACTIONS + GVAR(hooks[]) = {{-1.49,1.41,-.3}}; + GVAR(fuelCargo) = 10000; + }; + + // Vanilla buildings + class Land_Fuelstation_Feed_F : House_Small_F { + XEH_ENABLED; + transportFuel = 0; //50k + MACRO_REFUEL_ACTIONS + GVAR(hooks[]) = {{0,0,-0.5}}; + GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; + }; + + class Land_fs_feed_F : House_Small_F { + XEH_ENABLED; + transportFuel = 0; //50k + MACRO_REFUEL_ACTIONS + GVAR(hooks[]) = {{-0.4,0.022,-.23}}; + GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; + }; + + /* // Barrels found in config \ + BarrelHelper : Misc_thing 100 + BarrelBase : BarrelHelper 100 + Barrels : BarrelBase 400 + Barrel1 : BarrelBase 100 + Barrel2 : BarrelBase 100 + Barrel3 : BarrelBase 100 + Barrel4 : BarrelBase 100 + Barrel5 : BarrelBase 100 + Barrel6 : BarrelBase 100 + Wooden_barrel : BarrelBase 100 + Wooden_barrels : Wooden_barrel 400 + */ + + // Trucks + // Src: HEMTT http://www.inetres.com/gp/military/cv/eng/M977.html 583L > 483km + // Src: https://en.wikipedia.org/wiki/Heavy_Expanded_Mobility_Tactical_Truck 587L > 483km + // Src: https://en.wikipedia.org/wiki/Kamaz_Typhoon ? > 1200km + // Src: https://en.wikipedia.org/wiki/Humvee 95L + // Src: https://en.wikipedia.org/wiki/RG-33 80 gal = 302 + // Src: MTVR http://oshkoshdefense.com/wp-content/uploads/2013/08/MTVR_StndCargo_SS_6-13-11.pdf 295L + // Src: M1078 http://tarakia.weebly.com/ta-vehicles.html 219L + // Src: https://en.wikipedia.org/wiki/Ural-4320 360L + // Src: http://www.automobile-catalog.com/car/2012/1024400/gaz_233011_tigr.html 138L + // Src: https://en.wikipedia.org/wiki/UAZ-469 78L + // Src: https://en.wikipedia.org/wiki/GAZ-66 210L + + // Tracked IFV + // Src: https://en.wikipedia.org/wiki/Marder_%28IFV%29 652L > 520km + // Src: https://en.wikipedia.org/wiki/Tanque_Argentino_Mediano ~250L > 500km (200L additional tank for 400km range boost) + // Src: https://en.wikipedia.org/wiki/ACEC_Cobra 309L > 600km + // Src: https://en.wikipedia.org/wiki/Egyptian_Infantry_Fighting_Vehicle 454L > 482km + // Src: https://en.wikipedia.org/wiki/Lazika 400L > 400-450km + // Src: https://en.wikipedia.org/wiki/Type_73_Armored_Personnel_Carrier 450L > 300km + // Src: https://en.wikipedia.org/wiki/BMP-1 462L > 500-600km + // Src: http://www.inetres.com/gp/military/cv/inf/BMP-1.html 460L > 600km + // Src: http://www.inetres.com/gp/military/cv/inf/BMP-2.html 460L > 600km + // Src: http://www.inetres.com/gp/military/cv/inf/M2.html 662L > 483-402km + // Src: https://en.wikipedia.org/wiki/2T_Stalker ? > 1000km + // Src: https://en.wikipedia.org/wiki/Namer ? > 500km + // Src: https://en.wikipedia.org/wiki/Warrior_tracked_armoured_vehicle ? > 660km + // Src: http://www.globalsecurity.org/military/systems/ground/m113-specs.htm 360L + // Src: http://afvdb.50megs.com/usa/m2bradley.html 746L + // Src: https://en.wikipedia.org/wiki/BMD-1 300L + // Trend: 1-2 L/km + + // Wheeled IFV/APC + // Src: https://en.wikipedia.org/wiki/BTR-60 290L > 500km + // Src: http://www.inetres.com/gp/military/cv/inf/BTR-70.html 350L > 600km + // Src: http://www.inetres.com/gp/military/cv/inf/BTR-80.html 300L > 600km + // Src: https://en.wikipedia.org/wiki/Mowag_Piranha 4x4 200L > 700km + // Src: https://en.wikipedia.org/wiki/Mowag_Piranha 6x6 200L > 500km + // Src: https://en.wikipedia.org/wiki/ERC_90_Sagaie 242L > 700km + // Src: https://en.wikipedia.org/wiki/V%C3%A9hicule_de_l%27Avant_Blind%C3%A9 310L > 1200km + // Src: https://en.wikipedia.org/wiki/Panhard_M3 165L > 600km + // Src: https://fr.wikipedia.org/wiki/V%C3%A9hicule_blind%C3%A9_de_combat_d%27infanterie 400L > 750km + // Src: https://de.wikipedia.org/wiki/Sp%C3%A4hwagen_Fennek 230L > 460-1000km + // Src: http://www.inetres.com/gp/military/cv/inf/LAV.html 269L > 660km + // Src: http://www.inetres.com/gp/military/cv/inf/M1126.html 200L > 531km + // Src: https://en.wikipedia.org/wiki/Patria_AMV ? > 600-850km + // Src: https://en.wikipedia.org/wiki/Otokar_Arma ? > 700km + // Trend: 0.3-0.6 L/km + + // MBT + // Src: http://www.inetres.com/gp/military/cv/tank/Leopard2.html 1200L > 550km + // Src: http://www.inetres.com/gp/military/cv/tank/M1.html 1909L > 479km + // Src: https://en.wikipedia.org/wiki/T-80 1100L > 335km + // Src: https://en.wikipedia.org/wiki/T-72 1200L > 490km + // Trend: 2-4 L/km + + // Artillery + // Src: http://www.inetres.com/gp/military/cv/arty/M109.html 511L > 349km + // Src: https://en.wikipedia.org/wiki/2S3_Akatsiya 830L > 500km + + // Other + // https://en.wikipedia.org/wiki/ZSU-23-4 515L + + // Helicopter + // Src: http://www.bga-aeroweb.com/Defense/UH-1Y-Venom.html 1172kg / 0.81 kg/L = 1447L + // Src: http://www.bga-aeroweb.com/Defense/AH-1Z-Viper.html 1296kg / 0.81 kg/L = 1600L + // Src: http://www.army-technology.com/projects/black_hawk/ 1360L + // Src: http://www.bga-aeroweb.com/Defense/CH-47-Chinook.html 3914L + // Src: http://helicopters.axlegeeks.com/l/61/Boeing-AH-64-Apache 375 gal = 1420L + // Src: https://en.wikipedia.org/wiki/Mil_Mi-8 3700l + // Src: Google Ka-52 1870L + // Src: http://www.airforce-technology.com/projects/hind/ 1500kg / 0.81 L/kg = 1851L + // Src: https://en.wikipedia.org/wiki/MD_Helicopters_MH-6_Little_Bird 242L + // Src: http://www.globalsecurity.org/military/world/europe/aw159-specs.htm 1004L + // Src: https://en.wikipedia.org/wiki/AgustaWestland_AW101 3 * 1074L = 3222L + // Src: http://www.aviastar.org/helicopters_eng/ka-62.php 1450L + + // Planes + // Src: http://www.theaviationzone.com/factsheets/c130j.asp 20820kg / 0.81 kg/L = 25704L + // Src: http://www.avialogs.com/viewer/avialogs-documentviewer.php?id=3298 p29 1644 gal = 6223L + // Src: http://www.airforce-technology.com/projects/su25/ 3600L + // Src: http://www.thaitechnics.com/aircraft/L159.html 1551kg / 0.81 kg/L = 1914L + // Src: https://en.wikipedia.org/wiki/Yakovlev_Yak-130 1700kg / 0.81 kg/L = 2099L + // Src: http://www.adcom-systems.com/ENG/UAV/YAHBON-R2/Overview.html 270L +}; diff --git a/addons/refuel/README.md b/addons/refuel/README.md new file mode 100644 index 0000000000..6e3d226693 --- /dev/null +++ b/addons/refuel/README.md @@ -0,0 +1,11 @@ +ace_refuel +=============== + +The Refuel module introduces ability to refuel vehicles on different realistic levels. + +## Maintainers + +The people responsible for merging changes to this component or answering potential questions. + +- [GitHawk] (https://github.com/GitHawk) +- [Jonpas] (https://github.com/jonpas) diff --git a/addons/refuel/XEH_postInit.sqf b/addons/refuel/XEH_postInit.sqf new file mode 100644 index 0000000000..682ebaf094 --- /dev/null +++ b/addons/refuel/XEH_postInit.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +["medical_onUnconscious", {_this call FUNC(handleOnUnconscious)}] call EFUNC(common,addEventHandler); diff --git a/addons/refuel/XEH_preInit.sqf b/addons/refuel/XEH_preInit.sqf new file mode 100644 index 0000000000..691df0478d --- /dev/null +++ b/addons/refuel/XEH_preInit.sqf @@ -0,0 +1,32 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP(canCheckFuel); +PREP(canConnectNozzle); +PREP(canDisconnect); +PREP(canReturnNozzle); +PREP(canTakeNozzle); +PREP(canTurnOff); +PREP(canTurnOn); +PREP(checkFuel); +PREP(connectNozzle); +PREP(connectNozzleAction); +PREP(disconnect); +PREP(dropNozzle); +PREP(getFuel); +PREP(handleKilled); +PREP(handleUnconscious); +PREP(makeJerryCan); +PREP(moduleRefuelSettings); +PREP(readFuelCounter); +PREP(refuel); +PREP(reset); +PREP(resetLocal); +PREP(returnNozzle); +PREP(setFuel); +PREP(takeNozzle); +PREP(turnOff); +PREP(turnOn); + +ADDON = true; diff --git a/addons/refuel/XEH_respawn.sqf b/addons/refuel/XEH_respawn.sqf new file mode 100644 index 0000000000..39225f2521 --- /dev/null +++ b/addons/refuel/XEH_respawn.sqf @@ -0,0 +1,11 @@ +#include "script_component.hpp" + +private ["_unit"]; + +_unit = _this select 0; + +if !(local _unit) exitWith {}; + +[_unit, QGVAR(vehAttach), false] call EFUNC(common,setForceWalkStatus); +_unit setVariable [QGVAR(selectedWeaponOnRefuel), nil]; +_unit setVariable [QGVAR(isRefueling), false]; diff --git a/addons/refuel/config.cpp b/addons/refuel/config.cpp new file mode 100644 index 0000000000..6140cefe8c --- /dev/null +++ b/addons/refuel/config.cpp @@ -0,0 +1,17 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + units[] = {}; + weapons[] = {"ACE_refuel_fuelNozzle"}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_interaction"}; + author[] = {"GitHawk"}; + authorUrl = ""; + VERSION_CONFIG; + }; +}; + +#include "ACE_Settings.hpp" +#include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/refuel/functions/fnc_canCheckFuel.sqf b/addons/refuel/functions/fnc_canCheckFuel.sqf new file mode 100644 index 0000000000..a1584ea333 --- /dev/null +++ b/addons/refuel/functions/fnc_canCheckFuel.sqf @@ -0,0 +1,26 @@ +/* + * Author: Jonpas, GitHawk + * Checks if unit can check fuel. + * + * Arguments: + * 0: Unit + * 1: Fuel Truck/Station + * + * Return Value: + * Can Check Fuel + * + * Example: + * [player, truck] call ace_refuel_fnc_canCheckFuel + * + * Public: No + */ +#include "script_component.hpp" + +params ["_unit", "_target"]; + +!(isNull _unit || + {!(_unit isKindOf "CAManBase")} || + {!local _unit} || + {!alive _target} || + {(_target distance _unit) > REFUEL_ACTION_DISTANCE} || + {(_target call FUNC(getFuel) == REFUEL_INFINITE_FUEL)}) diff --git a/addons/refuel/functions/fnc_canConnectNozzle.sqf b/addons/refuel/functions/fnc_canConnectNozzle.sqf new file mode 100644 index 0000000000..812234818e --- /dev/null +++ b/addons/refuel/functions/fnc_canConnectNozzle.sqf @@ -0,0 +1,26 @@ +/* + * Author: GitHawk + * Check if a unit can connect a fuel nozzle + * + * Arguments: + * 0: Unit + * 1: Target + * + * Return Value: + * Can Connect Nozzle + * + * Example: + * [player, tank] call ace_refuel_fnc_canConnectNozzle + * + * Public: No + */ +#include "script_component.hpp" + +private ["_nozzle"]; +params ["_unit", "_target"]; + +_nozzle = _unit getVariable [QGVAR(nozzle), objNull]; + +!(isNull _nozzle || + {(_target distance _unit) > REFUEL_ACTION_DISTANCE} || + {!isNull (_target getVariable [QGVAR(nozzle), objNull])}) // TODO verify cant connect multiple fuel lines diff --git a/addons/refuel/functions/fnc_canDisconnect.sqf b/addons/refuel/functions/fnc_canDisconnect.sqf new file mode 100644 index 0000000000..50d22702a0 --- /dev/null +++ b/addons/refuel/functions/fnc_canDisconnect.sqf @@ -0,0 +1,29 @@ +/* + * Author: GitHawk + * Check if a unit can disconnect a fuel nozzle + * + * Arguments: + * 0: Unit + * 1: Nozzle + * + * Return Value: + * Can disconnect + * + * Example: + * [player, nozzle] call ace_refuel_fnc_canDisconnect + * + * Public: No + */ +#include "script_component.hpp" + +private ["_sink"]; +params ["_unit", "_nozzle"]; + +if (isNull _unit || + {isNull _nozzle} || + {!(_unit isKindOf "CAManBase")} || + {!local _unit} || + {(_nozzle distance _unit) > REFUEL_ACTION_DISTANCE}) exitWith {false}; + +_sink = _nozzle getVariable [QGVAR(sink), objNull]; +!((isNull _sink) || {_nozzle getVariable [QGVAR(isRefueling), false]}) diff --git a/addons/refuel/functions/fnc_canReturnNozzle.sqf b/addons/refuel/functions/fnc_canReturnNozzle.sqf new file mode 100644 index 0000000000..139c921d34 --- /dev/null +++ b/addons/refuel/functions/fnc_canReturnNozzle.sqf @@ -0,0 +1,24 @@ +/* + * Author: GitHawk + * Check if a unit can return a fuel nozzle + * + * Arguments: + * 0: Unit + * 1: Fuel truck + * + * Return Value: + * Can Return Nozzle + * + * Example: + * [player, fuelTruck] call ace_refuel_fnc_canReturnNozzle + * + * Public: No + */ +#include "script_component.hpp" + +private ["_nozzle"]; +params ["_unit", "_target"]; + +_nozzle = _unit getVariable QGVAR(nozzle); + +(_this call FUNC(canConnectNozzle)) && {_target == (_nozzle getVariable [QGVAR(source), objNull])} diff --git a/addons/refuel/functions/fnc_canTakeNozzle.sqf b/addons/refuel/functions/fnc_canTakeNozzle.sqf new file mode 100644 index 0000000000..85f5b815a5 --- /dev/null +++ b/addons/refuel/functions/fnc_canTakeNozzle.sqf @@ -0,0 +1,27 @@ +/* + * Author: GitHawk + * Check if a unit can take a fuel nozzle + * + * Arguments: + * 0: Unit + * 1: Fuel Station or Nozzle + * + * Return Value: + * Can connect + * + * Example: + * [player, nozzle] call ace_refuel_fnc_canTakeNozzle + * + * Public: No + */ +#include "script_component.hpp" + +params ["_unit", "_target"]; + +if (isNull _unit || + {!(_unit isKindOf "CAManBase")} || + {!local _unit} || + {!alive _target} || + {(_target distance _unit) > REFUEL_ACTION_DISTANCE}) exitWith {false}; + +!(_target getVariable [QGVAR(isConnected), false]) && {!(_unit getVariable [QGVAR(isRefueling), false])} diff --git a/addons/refuel/functions/fnc_canTurnOff.sqf b/addons/refuel/functions/fnc_canTurnOff.sqf new file mode 100644 index 0000000000..7d2d3652e0 --- /dev/null +++ b/addons/refuel/functions/fnc_canTurnOff.sqf @@ -0,0 +1,27 @@ +/* + * Author: GitHawk + * Check if a unit can turn off a fuel nozzle + * + * Arguments: + * 0: Unit + * 1: Nozzle + * + * Return Value: + * Can turn off + * + * Example: + * [player, nozzle] call ace_refuel_fnc_canTurnOff + * + * Public: No + */ +#include "script_component.hpp" + +params ["_unit", "_nozzle"]; + +if (isNull _unit || + {isNull _nozzle} || + {!(_unit isKindOf "CAManBase")} || + {!local _unit} || + {(_nozzle distance _unit) > REFUEL_ACTION_DISTANCE}) exitWith {false}; + +(_nozzle getVariable [QGVAR(isRefueling), false]) diff --git a/addons/refuel/functions/fnc_canTurnOn.sqf b/addons/refuel/functions/fnc_canTurnOn.sqf new file mode 100644 index 0000000000..3053e699a2 --- /dev/null +++ b/addons/refuel/functions/fnc_canTurnOn.sqf @@ -0,0 +1,30 @@ +/* + * Author: GitHawk + * Check if a unit can turn on a fuel nozzle + * + * Arguments: + * 0: Unit + * 1: Nozzle + * + * Return Value: + * Can turn on + * + * Example: + * [player, nozzle] call ace_refuel_fnc_canTurnOn + * + * Public: No + */ +#include "script_component.hpp" + +params ["_unit", "_nozzle"]; + +if (isNull _unit || + {isNull _nozzle} || + {!(_unit isKindOf "CAManBase")} || + {!local _unit} || + {(_nozzle distance _unit) > REFUEL_ACTION_DISTANCE}) exitWith {false}; + +!(_nozzle getVariable [QGVAR(isRefueling), false]) && + {[_nozzle getVariable QGVAR(source)] call FUNC(getFuel) != 0} && + {!isNull (_nozzle getVariable [QGVAR(sink), objNull])} && + {(fuel (_nozzle getVariable QGVAR(sink))) < 1} diff --git a/addons/refuel/functions/fnc_checkFuel.sqf b/addons/refuel/functions/fnc_checkFuel.sqf new file mode 100644 index 0000000000..b50e9a8171 --- /dev/null +++ b/addons/refuel/functions/fnc_checkFuel.sqf @@ -0,0 +1,40 @@ +/* + * Author: GitHawk + * Get the remaining fuel amount + * + * Arguments: + * 0: Unit + * 1: Fuel Truck + * + * Return Value: + * None + * + * Example: + * [player, fuelTruck] call ace_refuel_fnc_checkFuel + * + * Public: No + */ +#include "script_component.hpp" +private ["_fuel"]; +params ["_unit", "_target"]; + +_fuel = [_target] call FUNC(getFuel); + +[ + 5, + [_unit, _target, _fuel], + { + params ["_args"]; + _args params ["_unit", "_target", "_fuel"]; + if (_fuel > 0 ) then { + ["displayTextStructured", [_unit], [[LSTRING(Hint_RemainingFuel), _fuel], 2, _unit]] call EFUNC(common,targetEvent); + } else { + ["displayTextStructured", [_unit], [LSTRING(Hint_Empty), 2, _unit]] call EFUNC(common,targetEvent); + }; + true + }, + {true}, + localize LSTRING(CheckFuelAction), + {true}, + ["isnotinside"] +] call EFUNC(common,progressBar); diff --git a/addons/refuel/functions/fnc_connectNozzle.sqf b/addons/refuel/functions/fnc_connectNozzle.sqf new file mode 100644 index 0000000000..f5d8d35759 --- /dev/null +++ b/addons/refuel/functions/fnc_connectNozzle.sqf @@ -0,0 +1,65 @@ +/* + * Author: GitHawk et.al. + * Connect a fuel nozzle. + * With code from ace_attach + * + * Arguments: + * 0: Unit + * 1: Target + * + * Return Value: + * None + * + * Example: + * [player, tank] call ace_refuel_fnc_connectNozzle + * + * Public: No + */ +#include "script_component.hpp" + +#define PLACE_WAITING -1 +#define PLACE_CANCEL 0 +#define PLACE_APPROVE 1 + +private ["_nozzle", "_actionID"]; +params ["_unit", "_target"]; + +_nozzle = _unit getVariable [QGVAR(nozzle), objNull]; +if (isNull _nozzle) exitWith {}; + +GVAR(placeAction) = PLACE_WAITING; + +[{[localize LSTRING(Connect_Action), ""] call EFUNC(interaction,showMouseHint)}, []] call EFUNC(common,execNextFrame); +_unit setVariable [QGVAR(placeActionEH), [_unit, "DefaultAction", {true}, {GVAR(placeAction) = PLACE_APPROVE;}] call EFUNC(common,AddActionEventHandler)]; + +_actionID = _unit addAction [format ["%1", localize LSTRING(Cancel)], {GVAR(placeAction) = PLACE_CANCEL;}]; + +[{ + private["_virtualPos", "_virtualPosASL", "_lineInterection"]; + params ["_args","_pfID"]; + _args params ["_unit", "_target", "_nozzle", "_actionID"]; + + _virtualPosASL = (eyePos _unit) vectorAdd (positionCameraToWorld [0,0,0.6]) vectorDiff (positionCameraToWorld [0,0,0]); + if (cameraView == "EXTERNAL") then { + _virtualPosASL = _virtualPosASL vectorAdd ((positionCameraToWorld [0.3,0,0]) vectorDiff (positionCameraToWorld [0,0,0])); + }; + _virtualPos = _virtualPosASL call EFUNC(common,ASLToPosition); + _lineInterection = lineIntersects [eyePos ace_player, _virtualPosASL, ace_player]; + + //Don't allow placing in a bad position: + if (_lineInterection && {GVAR(placeAction) == PLACE_APPROVE}) then {GVAR(placeAction) = PLACE_WAITING;}; + + if ((GVAR(placeAction) != PLACE_WAITING) || + {_unit != ace_player} || + {!([_unit, _target, []] call EFUNC(common,canInteractWith))}) then { + + [_pfID] call CBA_fnc_removePerFrameHandler; + [] call EFUNC(interaction,hideMouseHint); + [_unit, "DefaultAction", (_unit getVariable [QGVAR(placeActionEH), -1])] call EFUNC(common,removeActionEventHandler); + _unit removeAction _actionID; + + if (GVAR(placeAction) == PLACE_APPROVE) then { + [_unit, _target, _virtualPos, _nozzle] call FUNC(ConnectNozzleAction); + }; + }; // TODO add model like in attach/functions/fnc_attach +}, 0, [_unit, _target, _nozzle, _actionID] ] call cba_fnc_addPerFrameHandler; diff --git a/addons/refuel/functions/fnc_connectNozzleAction.sqf b/addons/refuel/functions/fnc_connectNozzleAction.sqf new file mode 100644 index 0000000000..42190aacc6 --- /dev/null +++ b/addons/refuel/functions/fnc_connectNozzleAction.sqf @@ -0,0 +1,106 @@ +/* + * Author: GitHawk et.al. + * Calculates a connection for refueling. + * With code from ace_attach + * + * Arguments: + * 0: Unit + * 1: Target + * 2: Visual Position + * 3: Nozzle + * + * Return Value: + * None + * + * Example: + * [player, tank, [0,0,0], nozzle] call ace_refuel_fnc_connectNozzleAction + * + * Public: No + */ +#include "script_component.hpp" +private ["_startingOffset", "_startDistanceFromCenter", "_closeInUnitVector", "_closeInMax", "_closeInMin", "_closeInDistance", "_endPosTestOffset", "_endPosTest", "_doesIntersect", "_startingPosShifted", "_endASL", "_rate", "_maxFuel"]; + +params ["_unit", "_target", "_startingPosition", "_nozzle"]; +_startingOffset = _target worldToModel _startingPosition; + +_startDistanceFromCenter = vectorMagnitude _startingOffset; +_closeInUnitVector = vectorNormalized (_startingOffset vectorFromTo [0,0,0]); + +_closeInMax = _startDistanceFromCenter; +_closeInMin = 0; + +while {(_closeInMax - _closeInMin) > 0.01} do { + _closeInDistance = (_closeInMax + _closeInMin) / 2; + _endPosTestOffset = _startingOffset vectorAdd (_closeInUnitVector vectorMultiply _closeInDistance); + _endPosTestOffset set [2, (_startingOffset select 2)]; + _endPosTest = _target modelToWorldVisual _endPosTestOffset; + + _doesIntersect = false; + { + if (_doesIntersect) exitWith {}; + _startingPosShifted = _startingPosition vectorAdd _x; + _startASL = if (surfaceIsWater _startingPosShifted) then {_startingPosShifted} else {ATLtoASL _startingPosShifted}; + { + _endPosShifted = _endPosTest vectorAdd _x; + _endASL = if (surfaceIsWater _startingPosShifted) then {_endPosShifted} else {ATLtoASL _endPosShifted}; + + //Uncomment to see the lazor show, and see how the scanning works: + // drawLine3D [_startingPosShifted, _endPosShifted, [1,0,0,1]]; + if (_target in lineIntersectsWith [_startASL, _endASL, _unit]) exitWith {_doesIntersect = true}; + } forEach [[0,0,0.045], [0,0,-0.045], [0,0.045,0], [0,-0.045,0], [0.045,0,0], [-0.045,0,0]]; + } forEach [[0,0,0], [0,0,0.05], [0,0,-0.05]]; + + if (_doesIntersect) then { + _closeInMax = _closeInDistance; + } else { + _closeInMin = _closeInDistance; + }; +}; + +_closeInDistance = (_closeInMax + _closeInMin) / 2; + +//Checks (too close to center or can't attach) +if (((_startDistanceFromCenter - _closeInDistance) < 0.1) || {!([_target, _unit, _itemClassname] call FUNC(canAttach))}) exitWith { + TRACE_2("no valid spot found",_closeInDistance,_startDistanceFromCenter); + [localize LSTRING(Failed)] call EFUNC(common,displayTextStructured); +}; + +//Move it out slightly, for visibility sake (better to look a little funny than be embedded//sunk in the hull and be useless) +_closeInDistance = (_closeInDistance - 0.0085); + +_endPosTestOffset = _startingOffset vectorAdd (_closeInUnitVector vectorMultiply _closeInDistance); +_endPosTestOffset set [2, (_startingOffset select 2)]; + +[ + 2, + [_unit, _nozzle, _target, _endPosTestOffset], + { + private "_actionID"; + params ["_args"]; + _args params ["_unit", "_nozzle", "_target", "_endPosTestOffset"]; + _unit setVariable [QGVAR(nozzle), nil]; + _unit setVariable [QGVAR(isRefueling), false]; + [_unit, QGVAR(vehAttach), false] call EFUNC(common,setForceWalkStatus); + REFUEL_UNHOLSTER_WEAPON + _actionID = _unit getVariable [QGVAR(ReleaseActionID), -1]; + if (_actionID != -1) then { + _unit removeAction _actionID; + _unit setVariable [QGVAR(ReleaseActionID), nil]; + }; + + detach _nozzle; + _nozzle attachTo [_target, _endPosTestOffset]; + _nozzle setVariable [QGVAR(sink), _target, true]; + _nozzle setVariable [QGVAR(isConnected), true, true]; + _target setVariable [QGVAR(nozzle), _nozzle, true]; + + _source = _nozzle getVariable QGVAR(source); + _source setVariable [QGVAR(fuelCounter), [_source] call FUNC(getFuel), true]; + + [_unit, _target, _nozzle, _endPosTestOffset] call FUNC(refuel); + }, + "", + localize LSTRING(ConnectAction), + {true}, + ["isnotinside"] +] call EFUNC(common,progressBar); diff --git a/addons/refuel/functions/fnc_disconnect.sqf b/addons/refuel/functions/fnc_disconnect.sqf new file mode 100644 index 0000000000..e007ddf05f --- /dev/null +++ b/addons/refuel/functions/fnc_disconnect.sqf @@ -0,0 +1,30 @@ +/* + * Author: GitHawk + * Disconnect a fuel nozzle. + * + * Arguments: + * 0: Unit + * 1: Nozzle + * + * Return Value: + * None + * + * Example: + * [player, nozzle] call ace_refuel_fnc_disconnect + * + * Public: No + */ +#include "script_component.hpp" + +private ["_sink"]; +params ["_unit", "_nozzle"]; + +_sink = _nozzle getVariable [QGVAR(sink), objNull]; +if (isNull _sink) exitWith {}; + +_sink setVariable [QGVAR(nozzle), objNull, true]; +_nozzle setVariable [QGVAR(sink), objNull, true]; +_nozzle setVariable [QGVAR(isConnected), false, true]; +[objNull, _nozzle, true] call FUNC(dropNozzle); + +[_unit, objNull, _nozzle] call FUNC(takeNozzle); diff --git a/addons/refuel/functions/fnc_dropNozzle.sqf b/addons/refuel/functions/fnc_dropNozzle.sqf new file mode 100644 index 0000000000..c44c20c059 --- /dev/null +++ b/addons/refuel/functions/fnc_dropNozzle.sqf @@ -0,0 +1,32 @@ +/* + * Author: GitHawk + * Detaches the fuel nozzle, drops it and removes player variables. + * + * Arguments: + * 0: Unit (optional) + * 1: Nozzle + * 2: Disconnect Only + * + * Return Value: + * None + * + * Example: + * [player, nozzle, false] call ace_refuel_fnc_dropNozzle + * [objNull, nozzle, false] call ace_refuel_fnc_dropNozzle + * + * Public: No + */ +#include "script_component.hpp" + +params ["_unit", "_nozzle", ["_disconnectOnly", false]]; + +detach _nozzle; +_nozzle setVariable [QGVAR(isRefueling), false, true]; + +if (_disconnectOnly) exitWith {}; +_nozzle setVelocity [0, 0, 0]; +_nozzle setPosATL [(getPosATL _nozzle) select 0, (getPosATL _nozzle) select 1, 0.05]; + +if (isNull _unit) exitWith {}; +_unit setVariable [QGVAR(isRefueling), false, true]; +_unit setVariable [QGVAR(nozzle), objNull, true]; diff --git a/addons/refuel/functions/fnc_getFuel.sqf b/addons/refuel/functions/fnc_getFuel.sqf new file mode 100644 index 0000000000..9bbb4987be --- /dev/null +++ b/addons/refuel/functions/fnc_getFuel.sqf @@ -0,0 +1,28 @@ +/* + * Author: GitHawk, Jonpas + * Get the remaining fuel amount. + * + * Arguments: + * 0: Target + * + * Return Value: + * Fuel left (in liters) + * + * Example: + * [fuelTruck] call ace_refuel_fnc_getFuel + * + * Public: No + */ +#include "script_component.hpp" + +private ["_fuel"]; +params ["_target"]; + +_fuel = _target getVariable QGVAR(currentFuelCargo); + +if (isNil "_fuel") then { + _fuel = getNumber (configFile >> "CfgVehicles" >> typeOf _target >> QGVAR(fuelCargo)); + _target setVariable [QGVAR(currentFuelCargo), _fuel, true]; +}; + +_fuel diff --git a/addons/refuel/functions/fnc_handleKilled.sqf b/addons/refuel/functions/fnc_handleKilled.sqf new file mode 100644 index 0000000000..897337c062 --- /dev/null +++ b/addons/refuel/functions/fnc_handleKilled.sqf @@ -0,0 +1,26 @@ +/* + * Author: GitHawk, Jonpas + * Handles medical on set dead event. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [player] call ace_refuel_fnc_handleKilled + * + * Public: No + */ +#include "script_component.hpp" + +params ["_unit"]; + +if (!local _unit) exitWith {}; + +_unit setVariable [QGVAR(selectedWeaponOnRefuel), nil]; +_nozzle = _unit getVariable [QGVAR(nozzle), objNull]; +if !(isNull _nozzle) then { + [_unit, _nozzle] call FUNC(dropNozzle); +}; diff --git a/addons/refuel/functions/fnc_handleUnconscious.sqf b/addons/refuel/functions/fnc_handleUnconscious.sqf new file mode 100644 index 0000000000..6a6e561230 --- /dev/null +++ b/addons/refuel/functions/fnc_handleUnconscious.sqf @@ -0,0 +1,29 @@ +/* + * Author: GitHawk, Jonpas + * Handles medical on unconscious event. + * + * Arguments: + * 0: Unit + * 1: Is Unconscious + * + * Return Value: + * None + * + * Example: + * [player, true] call ace_refuel_fnc_handleUnconscious + * + * Public: No + */ +#include "script_component.hpp" + +params ["_unit", "_isUnconscious"]; + +if (!local _unit || {!_isUnconscious}) exitWith {}; + +private "_nozzle"; + +[_unit, QGVAR(vehAttach), false] call EFUNC(common,setForceWalkStatus); +_nozzle = _unit getVariable [QGVAR(nozzle), objNull]; +if !(isNull _nozzle) then { + [_unit, _nozzle] call FUNC(dropNozzle); +}; diff --git a/addons/refuel/functions/fnc_makeJerryCan.sqf b/addons/refuel/functions/fnc_makeJerryCan.sqf new file mode 100644 index 0000000000..3df209196d --- /dev/null +++ b/addons/refuel/functions/fnc_makeJerryCan.sqf @@ -0,0 +1,89 @@ +/* + * Author: GitHawk + * Makes an object into a jerry can. + * + * Arguments: + * 0: Target + * 1: Fuel amount (in liters) + * + * Return Value: + * None + * + * Example: + * [can] call ace_refuel_fnc_makeJerryCan + * + * Public: No + */ +#include "script_component.hpp" + +private ["_actions", "_action"]; +params ["_target", ["_fuelAmount", 20]]; + +if (isNull _target || + {_target isKindOf "AllVehicles"}) exitWith {}; + +[_target, _fuelAmount] call FUNC(setFuel); +_target setVariable [QGVAR(source), _target, true]; + +_actions = []; +// Add pickup +_action = [QGVAR(PickUpNozzle), + localize LSTRING(TakeNozzle), + QUOTE(PATHTOF(ui\icon_refuel_interact.paa)), + {[_player, objNull, _target] call FUNC(TakeNozzle)}, + {[_player, _target] call FUNC(canTakeNozzle)}, + {}, + [], + [0, 0, 0], + REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); +_actions pushBack [_action, [], _target]; + +// Add turnOn +_action = [QGVAR(TurnOn), + localize LSTRING(TurnOn), + QUOTE(PATHTOF(ui\icon_refuel_interact.paa)), + {[_player, _target] call FUNC(turnOn)}, + {[_player, _target] call FUNC(canTurnOn)}, + {}, + [], + [0, 0, 0], + REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); +_actions pushBack [_action, [], _target]; + +// Add turnOff +_action = [QGVAR(TurnOff), + localize LSTRING(TurnOff), + QUOTE(PATHTOF(ui\icon_refuel_interact.paa)), + {[_player, _target] call FUNC(turnOff)}, + {[_player, _target] call FUNC(canTurnOff)}, + {}, + [], + [0, 0, 0], + REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); +_actions pushBack [_action, [], _target]; + +// Add disconnect +_action = [QGVAR(Disconnect), + localize LSTRING(Disconnect), + QUOTE(PATHTOF(ui\icon_refuel_interact.paa)), + {[_player, _target] call FUNC(disconnect)}, + {[_player, _target] call FUNC(canDisconnect)}, + {}, + [], + [0, 0, 0], + REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); +_actions pushBack [_action, [], _target]; + +// Main Action +_action = [QGVAR(Refuel), + localize LSTRING(Refuel), + QUOTE(PATHTOF(ui\icon_refuel_interact.paa)), + {}, + {true}, + {}, + [], + [0, 0, 0], + REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); + +[_target, 0] call EFUNC(interact_menu,addMainAction); +[_target, 0, ["ACE_MainActions"], [_action, _actions, _target]] call EFUNC(interact_menu,addActionToObject); diff --git a/addons/refuel/functions/fnc_moduleRefuelSettings.sqf b/addons/refuel/functions/fnc_moduleRefuelSettings.sqf new file mode 100644 index 0000000000..6cdc78b9f7 --- /dev/null +++ b/addons/refuel/functions/fnc_moduleRefuelSettings.sqf @@ -0,0 +1,24 @@ +/* + * Author: GitHawk + * Module for adjusting the refuel settings. + * + * Arguments: + * 0: The module logic + * 1: units + * 2: activated + * + * Return Value: + * None + * + * Public: No + */ + +#include "script_component.hpp" + +params ["_logic", "_units", "_activated"]; + +if !(_activated) exitWith {}; + +[_logic, QGVAR(rate), "rate"] call EFUNC(common,readSettingFromModule); + +diag_log text format ["[ACE]: Refuel Module Initialized with flow rate: %1", GVAR(rate)]; diff --git a/addons/refuel/functions/fnc_readFuelCounter.sqf b/addons/refuel/functions/fnc_readFuelCounter.sqf new file mode 100644 index 0000000000..af95c044e3 --- /dev/null +++ b/addons/refuel/functions/fnc_readFuelCounter.sqf @@ -0,0 +1,37 @@ +/* + * Author: GitHawk + * Reads the fuel counter. + * + * Arguments: + * 0: Unit + * 1: Fuel Truck + * + * Return Value: + * None + * + * Example: + * [player, fuelTruck] call ace_refuel_fnc_readFuelCounter + * + * Public: No + */ +#include "script_component.hpp" + +params ["_unit", "_target"]; + +[ + 2, + [_unit, _target], + { + private ["_currentFuel", "_fuelCounter"]; + params ["_args"]; + _args params ["_unit", "_target"]; + + _currentFuel = [_target] call FUNC(getFuel); + _fuelCounter = 0.01 * round (100 * ((_target getVariable [QGVAR(fuelCounter), _currentFuel]) - _currentFuel)); + [[LSTRING(Hint_FuelCounter), _fuelCounter], 1.5, _unit] call EFUNC(common,displayTextStructured); + }, + "", + localize LSTRING(CheckFuelCounterAction), + {true}, + ["isnotinside"] +] call EFUNC(common,progressBar); diff --git a/addons/refuel/functions/fnc_refuel.sqf b/addons/refuel/functions/fnc_refuel.sqf new file mode 100644 index 0000000000..ed6eb257cf --- /dev/null +++ b/addons/refuel/functions/fnc_refuel.sqf @@ -0,0 +1,99 @@ +/* + * Author: GitHawk + * Refuels the vehicle. + * + * Arguments: + * 0: Unit + * 1: Target + * 2: Nozzle + * 3: Connection Point + * + * Return Value: + * None + * + * Public: No + */ + +#include "script_component.hpp" + +#define PFH_STEPSIZE 0.1 + +private ["_rate", "_maxFuel"]; +params ["_unit", "_target", "_nozzle", "_connectToPoint"]; + +_rate = getNumber (configFile >> "CfgVehicles" >> (typeOf _target) >> QGVAR(flowRate)) * GVAR(rate) * PFH_STEPSIZE; +_maxFuel = getNumber (configFile >> "CfgVehicles" >> (typeOf _target) >> QGVAR(fuelCapacity)); + +[{ + private ["_source", "_tooFar", "_fuelInSource", "_fuelInSink", "_finished", "_fueling"]; + params ["_args", "_pfID"]; + _args params ["_source", "_sink", "_unit", "_nozzle", "_rate", "_startFuel", "_maxFuel", "_connectFromPoint", "_connectToPoint"]; + + _fueling = _nozzle getVariable [QGVAR(isRefueling), false]; + if (!alive _source || {!alive _sink}) exitWith { + [objNull, _nozzle] call FUNC(dropNozzle); + _nozzle setVariable [QGVAR(isConnected), false, true]; + _nozzle setVariable [QGVAR(sink), objNull, true]; + _sink setVariable [QGVAR(nozzle), objNull, true]; + [_pfID] call cba_fnc_removePerFrameHandler; + }; + _tooFar = ((_sink modelToWorld _connectToPoint) distance (_source modelToWorld _connectFromPoint)) > (REFUEL_HOSE_LENGTH - 2); + if (_tooFar) exitWith { + [LSTRING(Hint_TooFar), 2, _unit] call EFUNC(common,displayTextStructured); + + [objNull, _nozzle] call FUNC(dropNozzle); + _nozzle setVariable [QGVAR(isConnected), false, true]; + _nozzle setVariable [QGVAR(sink), objNull, true]; + _sink setVariable [QGVAR(nozzle), objNull, true]; + [_pfID] call cba_fnc_removePerFrameHandler; + }; + + _finished = false; + if (_fueling) then { + _fuelInSource = [_source] call FUNC(getFuel); + if (_fuelInSource == 0) exitWith { + [LSTRING(Hint_SourceEmpty), 2, _unit] call EFUNC(common,displayTextStructured); + _nozzle setVariable [QGVAR(isRefueling), false, true]; + }; + if !(_fuelInSource == REFUEL_INFINITE_FUEL) then { + _fuelInSource = _fuelInSource - _rate; + }; + if (_fuelInSource < 0 && {_fuelInSource > -1}) then { + _fuelInSource = 0; + _finished = true; + [LSTRING(Hint_SourceEmpty), 2, _unit] call EFUNC(common,displayTextStructured); + }; + + _fuelInSink = (_unit getVariable [QGVAR(tempFuel), _startFuel]) + ( _rate / _maxFuel); + if (_fuelInSink > 1) then { + _fuelInSink = 1; + _finished = true; + [LSTRING(Hint_Completed), 2, _unit] call EFUNC(common,displayTextStructured); + }; + _unit setVariable [QGVAR(tempFuel), _fuelInSink]; + + if !(local _sink) then { + [[_sink, _fuelInSink], "{(_this select 0) setFuel (_this select 1)}", _sink] call EFUNC(common,execRemoteFnc); + } else { + _sink setFuel _fuelInSink; + }; + [_source, _fuelInSource] call FUNC(setFuel); + } else { + _unit setVariable [QGVAR(tempFuel), fuel _sink]; + }; + + if (_finished) exitWith { + _nozzle setVariable [QGVAR(isRefueling), false, true]; + }; +}, +PFH_STEPSIZE, +[_nozzle getVariable QGVAR(source), + _target, + _unit, + _nozzle, + _rate, + fuel _target, + _maxFuel, + _nozzle getVariable [QGVAR(attachPos), [0,0,0]], + _connectToPoint] +] call cba_fnc_addPerFrameHandler; diff --git a/addons/refuel/functions/fnc_reset.sqf b/addons/refuel/functions/fnc_reset.sqf new file mode 100644 index 0000000000..f235180b0e --- /dev/null +++ b/addons/refuel/functions/fnc_reset.sqf @@ -0,0 +1,50 @@ +/* + * Author: GitHawk + * Resets a fuel vehicle in case is got bugged + * + * Arguments: + * 0: Fuel truck + * + * Return Value: + * None + * + * Example: + * [truck] call ace_refuel_fnc_reset + * + * Public: No + */ +#include "script_component.hpp" + +private ["_nozzle", "_nozzleTarget", "_rope"]; +params ["_target"]; + +if (local _target) then { + _target setHitPointDamage ["HitEngine", _target getVariable [QGVAR(engineHit), 0]]; +} else { + [[_target, ["HitEngine", _target getVariable [QGVAR(engineHit), 0]]], "{(_this select 0) setHitPointDamage (_this select 1)}", _target] call EFUNC(common,execRemoteFnc); +}; +_target setVariable [QGVAR(engineHit), nil, true]; +_target setVariable [QGVAR(isConnected), false, true]; + +_nozzle = _target getVariable [QGVAR(ownedNozzle), nil]; +if !(isNil "_nozzle") then { + _nozzleTarget = _nozzle getVariable [QGVAR(sink), nil]; + if !(isNil "_nozzleTarget") then { + _nozzleTarget setVariable [QGVAR(nozzle), nil, true]; + }; + + _rope = _nozzle getVariable [QGVAR(rope), nil]; + if !(isNil "_rope") then { + ropeDestroy _rope; + }; + + { + if (local _x) then { + [_x, _nozzle] call FUNC(resetLocal); + } else { + [[_x, _nozzle], "{_this call FUNC(resetLocal)}", _x] call EFUNC(common,execRemoteFnc); + }; + } count allPlayers; + deleteVehicle _nozzle; +}; +_target setVariable [QGVAR(ownedNozzle), nil, true]; diff --git a/addons/refuel/functions/fnc_resetLocal.sqf b/addons/refuel/functions/fnc_resetLocal.sqf new file mode 100644 index 0000000000..a8b0c184cc --- /dev/null +++ b/addons/refuel/functions/fnc_resetLocal.sqf @@ -0,0 +1,37 @@ +/* + * Author: GitHawk + * Resets a player + * + * Arguments: + * 0: Fuel nozzle + * + * Return Value: + * None + * + * Example: + * [nozzle] call ace_refuel_fnc_resetLocal + * + * Public: No + */ +#include "script_component.hpp" + +params ["_unit", "_nozzle"]; + + +if (isNull _unit || + {isNull _nozzle} || + {!(_unit isKindOf "CAManBase")} || + {!local _unit}) exitWith {}; +private ["_attachedNozzle", "_actionID"]; +_attachedNozzle = _unit getVariable [QGVAR(nozzle), nil]; +if (isNil "_attachedNozzle") exitWith {}; + +if (_nozzle != _attachedNozzle) exitWith {}; + +_actionID = _unit getVariable [QGVAR(ReleaseActionID), -1]; +if (_actionID != -1) then { + _unit removeAction _actionID; + _unit setVariable [QGVAR(isRefueling), false, true]; + _unit setVariable [QGVAR(ReleaseActionID), nil]; + _unit setVariable [QGVAR(nozzle), nil]; +}; diff --git a/addons/refuel/functions/fnc_returnNozzle.sqf b/addons/refuel/functions/fnc_returnNozzle.sqf new file mode 100644 index 0000000000..d3fca33021 --- /dev/null +++ b/addons/refuel/functions/fnc_returnNozzle.sqf @@ -0,0 +1,63 @@ +/* + * Author: GitHawk, Jonpas + * Returns the nozzle back to source vehicle. + * + * Arguments: + * 0: Unit + * 1: Fuel Truck + * + * Return Value: + * Returned Nozzle + * + * Example: + * [player, fuelTruck] call ace_refuel_fnc_returnNozzle + * + * Public: No + */ +#include "script_component.hpp" + +private ["_nozzle", "_dummy", "_actionID"]; +params ["_unit", "_target"]; + +_nozzle = _unit getVariable [QGVAR(nozzle), objNull]; +_source = _nozzle getVariable QGVAR(source); + +if (isNull _nozzle || {_source != _target}) exitWith {false}; + +[ + 2, + [_unit, _nozzle, _target], + { + private "_actionID"; + params ["_args"]; + _args params ["_unit", "_nozzle", "_target"]; + _unit setVariable [QGVAR(nozzle), nil]; + detach _nozzle; + [_unit, QGVAR(vehAttach), false] call EFUNC(common,setForceWalkStatus); + REFUEL_UNHOLSTER_WEAPON + _unit setVariable [QGVAR(isRefueling), false]; + _actionID = _unit getVariable [QGVAR(ReleaseActionID), -1]; + if (_actionID != -1) then { + _unit removeAction _actionID; + _unit setVariable [QGVAR(ReleaseActionID), nil]; + }; + + _target setVariable [QGVAR(isConnected), false, true]; + _target setVariable [QGVAR(ownedNozzle), nil, true]; + ropeDestroy (_nozzle getVariable QGVAR(rope)); + deleteVehicle _nozzle; + + if !(local _target) then { + [[_target, ["HitEngine", _target getVariable [QGVAR(engineHit), 0]]], "{(_this select 0) setHitPointDamage (_this select 1)}", _sink] call EFUNC(common,execRemoteFnc); + } else { + _target setHitPointDamage ["HitEngine", _target getVariable [QGVAR(engineHit), 0]]; + }; + _target setVariable [QGVAR(engineHit), nil, true]; + }, + "", + localize LSTRING(ReturnAction), + {true}, + ["isnotinside"] +] call EFUNC(common,progressBar); + +true diff --git a/addons/refuel/functions/fnc_setFuel.sqf b/addons/refuel/functions/fnc_setFuel.sqf new file mode 100644 index 0000000000..a182d463ae --- /dev/null +++ b/addons/refuel/functions/fnc_setFuel.sqf @@ -0,0 +1,24 @@ +/* + * Author: GitHawk + * Set the remaining fuel amount. + * + * Arguments: + * 0: Fuel Truck + * 1: Amount (in liters) + * + * Return Value: + * None + * + * Example: + * [fuelTruck, 42] call ace_refuel_fnc_setFuel + * + * Public: No + */ +#include "script_component.hpp" +private ["_maxFuel"]; +params ["_target", "_fuel"]; + +if (isNull _target || + {isNil "_fuel"}) exitWith {}; + +_target setVariable [QGVAR(currentFuelCargo), _fuel, true]; diff --git a/addons/refuel/functions/fnc_takeNozzle.sqf b/addons/refuel/functions/fnc_takeNozzle.sqf new file mode 100644 index 0000000000..f6d953cecc --- /dev/null +++ b/addons/refuel/functions/fnc_takeNozzle.sqf @@ -0,0 +1,141 @@ +/* + * Author: GitHawk + * Take a fuel nozzle either from a fuel truck/station or from the ground. + * + * Arguments: + * 0: Unit + * 1: Fuel Truck + * 2: Nozzle (optional) + * + * Return Value: + * None + * + * Example: + * [player, fuelTruck] call ace_refuel_fnc_takeNozzle + * [player, objNull, nozzle] call ace_refuel_fnc_takeNozzle + * + * Public: No + */ +#include "script_component.hpp" + +private ["_endPosOffset"], +params ["_unit", "_target", ["_nozzle", objNull]]; + +[_unit, QGVAR(vehAttach), true] call EFUNC(common,setForceWalkStatus); + +REFUEL_HOLSTER_WEAPON + +_endPosOffset = [0, 0, 0]; +if (isNull _nozzle) then { // func is called on fuel truck + _target setVariable [QGVAR(engineHit), _target getHitPointDamage "HitEngine", true]; + if !(local _target) then { + [[_target, ["HitEngine", 1]], "{(_this select 0) setHitPointDamage (_this select 1)}", _sink] call EFUNC(common,execRemoteFnc); + } else { + _target setHitPointDamage ["HitEngine", 1]; + }; + + _target setVariable [QGVAR(isConnected), true, true]; + _endPosOffset = getArray (configFile >> "CfgVehicles" >> typeOf _target >> "ace_refuel_hooks"); + if (count _endPosOffset == 2) then { + if (_unit distance (_target modelToWorld (_endPosOffset select 0)) < _unit distance (_target modelToWorld (_endPosOffset select 1))) then { + _endPosOffset = _endPosOffset select 0; + } else { + _endPosOffset = _endPosOffset select 1; + }; + } else { + _endPosOffset = _endPosOffset select 0; + }; + [ + 2, + [_unit, _target, _endPosOffset], + { + private ["_newNozzle", "_rope", "_actionID"]; + params ["_args"]; + _args params ["_unit", "_target", "_endPosOffset"]; + + _newNozzle = "ACE_refuel_fuelNozzle" createVehicle position _unit; + _newNozzle attachTo [_unit, [-0.02,-0.05,0], "righthandmiddle1"]; // TODO replace with right coordinates for real model + _unit setVariable [QGVAR(nozzle), _newNozzle]; + + _rope = ropeCreate [_target, _endPosOffset, _newNozzle, [0, 0, 0], REFUEL_HOSE_LENGTH]; + _newNozzle setVariable [QGVAR(attachPos), _endPosOffset, true]; + _newNozzle setVariable [QGVAR(source), _target, true]; + _newNozzle setVariable [QGVAR(rope), _rope, true]; + _target setVariable [QGVAR(ownedNozzle), _newNozzle, true]; + + _unit setVariable [QGVAR(isRefueling), true]; + _actionID = _unit getVariable [QGVAR(ReleaseActionID), -1]; + if (_actionID != -1) then { + _unit removeAction _actionID; + }; + _actionID = _unit addAction [ + format ["%1", localize ELSTRING(dragging,Drop)], + '_unit = _this select 0; _nozzle = _unit getVariable QGVAR(nozzle); [_unit, _nozzle] call FUNC(dropNozzle); [_unit, QGVAR(vehAttach), false] call EFUNC(common,setForceWalkStatus); REFUEL_UNHOLSTER_WEAPON', + nil, + 20, + false, + true, + "", + '!isNull (_target getVariable [QGVAR(nozzle), objNull])' + ]; + _unit setVariable [QGVAR(ReleaseActionID), _actionID]; + }, + "", + localize LSTRING(TakeNozzleAction), + {true}, + ["isnotinside"] + ] call EFUNC(common,progressBar); +} else { // func is called in muzzle either connected or on ground + [ + 2, + [_unit, _nozzle], + { + private ["_actionID"]; + params ["_args"]; + _args params ["_unit", "_nozzle"]; + _nozzle attachTo [_unit, [-0.02,-0.05,0], "righthandmiddle1"]; // TODO replace with right coordinates for real model + _unit setVariable [QGVAR(nozzle), _nozzle]; + + _unit setVariable [QGVAR(isRefueling), true]; + _actionID = _unit getVariable [QGVAR(ReleaseActionID), -1]; + if (_actionID != -1) then { + _unit removeAction _actionID; + }; + _actionID = _unit addAction [ + format ["%1", localize ELSTRING(dragging,Drop)], + '_unit = _this select 0; _nozzle = _unit getVariable QGVAR(nozzle); [_unit, _nozzle] call FUNC(dropNozzle); [_unit, QGVAR(vehAttach), false] call EFUNC(common,setForceWalkStatus); REFUEL_UNHOLSTER_WEAPON', + nil, + 20, + false, + true, + "", + '!isNull (_target getVariable [QGVAR(nozzle), objNull])' + ]; + _unit setVariable [QGVAR(ReleaseActionID), _actionID]; + }, + "", + localize LSTRING(TakeNozzleAction), + {true}, + ["isnotinside"] + ] call EFUNC(common,progressBar); + + _target = _nozzle getVariable QGVAR(source); + _endPosOffset = _nozzle getVariable QGVAR(attachPos); +}; +[{ + private ["_nozzle"]; + params ["_args", "_pfID"]; + _args params ["_unit", "_source", "_endPosOffset"]; + + if (_unit distance (_source modelToWorld _endPosOffset) > (REFUEL_HOSE_LENGTH - 2)) exitWith { + _nozzle = _unit getVariable [QGVAR(nozzle), objNull]; + if !(isNull _nozzle) then { + [_unit, _nozzle] call FUNC(dropNozzle); + REFUEL_UNHOLSTER_WEAPON + + [_unit, QGVAR(vehAttach), false] call EFUNC(common,setForceWalkStatus); + [LSTRING(Hint_TooFar), 2, _unit] call EFUNC(common,displayTextStructured); + }; + [_pfID] call cba_fnc_removePerFrameHandler; + }; +}, 0, [_unit, _target, _endPosOffset]] call cba_fnc_addPerFrameHandler; diff --git a/addons/refuel/functions/fnc_turnOff.sqf b/addons/refuel/functions/fnc_turnOff.sqf new file mode 100644 index 0000000000..115c1eabe2 --- /dev/null +++ b/addons/refuel/functions/fnc_turnOff.sqf @@ -0,0 +1,34 @@ +/* + * Author: GitHawk + * Turn off a fuel nozzle. + * + * Arguments: + * 0: Unit + * 1: Nozzle + * + * Return Value: + * None + * + * Example: + * [nozzle] call ace_refuel_fnc_turnOff + * + * Public: No + */ +#include "script_component.hpp" + +params ["_unit", "_nozzle"]; + +[ + 2, + [_unit, _nozzle], + { + params ["_args"]; + _args params ["_unit", "_nozzle"]; + _nozzle setVariable [QGVAR(isRefueling), false, true]; + [LSTRING(Hint_Stopped), 1.5, _unit] call EFUNC(common,displayTextStructured); + }, + "", + localize LSTRING(TurnOffAction), + {true}, + ["isnotinside"] +] call EFUNC(common,progressBar); diff --git a/addons/refuel/functions/fnc_turnOn.sqf b/addons/refuel/functions/fnc_turnOn.sqf new file mode 100644 index 0000000000..017a8ee021 --- /dev/null +++ b/addons/refuel/functions/fnc_turnOn.sqf @@ -0,0 +1,35 @@ +/* + * Author: GitHawk + * Turn on a fuel nozzle. + * + * Arguments: + * 0: Unit + * 1: Nozzle + * + * Return Value: + * None + * + * Example: + * [player, nozzle] call ace_refuel_fnc_turnOn + * + * Public: No + */ +#include "script_component.hpp" + +params ["_unit", "_nozzle"]; + +[ + 2, + [_unit, _nozzle], + { + private "_source"; + params ["_args"]; + _args params ["_unit", "_nozzle"]; + _nozzle setVariable [QGVAR(isRefueling), true, true]; + [LSTRING(Hint_Started), 1.5, _unit] call EFUNC(common,displayTextStructured); + }, + "", + localize LSTRING(TurnOnAction), + {true}, + ["isnotinside"] +] call EFUNC(common,progressBar); diff --git a/addons/refuel/functions/script_component.hpp b/addons/refuel/functions/script_component.hpp new file mode 100644 index 0000000000..167c1e614a --- /dev/null +++ b/addons/refuel/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\refuel\script_component.hpp" diff --git a/addons/refuel/script_component.hpp b/addons/refuel/script_component.hpp new file mode 100644 index 0000000000..28e6fb7931 --- /dev/null +++ b/addons/refuel/script_component.hpp @@ -0,0 +1,25 @@ +#define COMPONENT refuel +#include "\z\ace\addons\main\script_mod.hpp" + +#ifdef DEBUG_ENABLED_REFUEL + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_ENABLED_REFUEL + #define DEBUG_SETTINGS DEBUG_ENABLED_REFUEL +#endif + +#include "\z\ace\addons\main\script_macros.hpp" + +#define REFUEL_INFINITE_FUEL -1 +#define REFUEL_ACTION_DISTANCE 37 +#define REFUEL_HOSE_LENGTH 12 + +#define REFUEL_HOLSTER_WEAPON \ + _unit setVariable [QGVAR(selectedWeaponOnRefuel), currentWeapon _unit]; \ + _unit action ["SwitchWeapon", _unit, _unit, 99]; + +#define REFUEL_UNHOLSTER_WEAPON \ + _weaponSelect = _unit getVariable QGVAR(selectedWeaponOnRefuel); \ + _unit selectWeapon _weaponSelect; \ + _unit setVariable [QGVAR(selectedWeaponOnRefuel), nil]; diff --git a/addons/refuel/stringtable.xml b/addons/refuel/stringtable.xml new file mode 100644 index 0000000000..c530501346 --- /dev/null +++ b/addons/refuel/stringtable.xml @@ -0,0 +1,129 @@ + + + + + Refuel Settings + Betankungseinst. + + + Flow Rate + Fließrate + + + How fast should a vehicle be refueled? + Wie schnell soll ein Fahrzeug aufgetankt sein? + + + Refuel + Betankung + + + Take fuel nozzle + Zapfpistole nehmen + + + Taking fuel nozzle ... + Nehme Zapfpistole ... + + + Connect fuel nozzle + Zapfpistole anschließen + + + Connecting fuel nozzle ... + Zapfpistole anschließen ... + + + Disconnect fuel nozzle + Zapfpistole entfernen + + + Connect + Anschließen + + + Check remaining fuel + Verbleibenden Kraftstoff überprüfen + + + Checking remaining fuel ... + Überprüfe verbleibenden Kraftstoff ... + + + There are %1 liters left. + Es sind noch %1 Liter übrig. + + + There is no fuel left. + Es ist kein Kraftstoff übrig. + + + Cancel + Abbrechen + + + Failed + Gescheitert + + + Stop fueling + Betankung stoppen + + + Stopping fueling ... + Stoppe Betankung ... + + + Start fueling + Betankung beginnen + + + Starting fueling ... + Beginne Betankung ... + + + %1 Liters fueled + %1 Liters getankt + + + The fuel source is empty. + Die Treibstoffquelle ist leer. + + + Maximum fuel hose length reached. + Maximale Schlauchlänge erreicht. + + + Fueling completed + Betankung abgeschlossen + + + Fueling stopped + Betankung angehalten + + + Fueling started + Betankung begonnen + + + Return fuel nozzle + Zapfpistole zurückstecken + + + Returning fuel nozzle ... + Stecke Zapfpistole zurück ... + + + Check fuel counter + Tankuhr ansehen + + + >Checking fuel counter ... + Betrachte Tankuhr ... + + + %1 liters have been fueled. + %1 Liter wurden getankt. + + + diff --git a/addons/refuel/ui/icon_module_refuel.paa b/addons/refuel/ui/icon_module_refuel.paa new file mode 100644 index 0000000000..84704c13d7 Binary files /dev/null and b/addons/refuel/ui/icon_module_refuel.paa differ diff --git a/addons/refuel/ui/icon_refuel_interact.paa b/addons/refuel/ui/icon_refuel_interact.paa new file mode 100644 index 0000000000..2cc1a9320d Binary files /dev/null and b/addons/refuel/ui/icon_refuel_interact.paa differ diff --git a/addons/reload/functions/fnc_canCheckAmmo.sqf b/addons/reload/functions/fnc_canCheckAmmo.sqf index 8fbb37c726..41a46ea465 100644 --- a/addons/reload/functions/fnc_canCheckAmmo.sqf +++ b/addons/reload/functions/fnc_canCheckAmmo.sqf @@ -25,7 +25,7 @@ if (_target isKindOf "StaticWeapon") exitWith { // no check ammo action on destroyed static weapons if (!alive _target) exitWith {false}; - local _found = false; + private _found = false; { if (_x select 2) exitWith { diff --git a/addons/repair/ACE_Repair.hpp b/addons/repair/ACE_Repair.hpp index a8aac18690..251302a93a 100644 --- a/addons/repair/ACE_Repair.hpp +++ b/addons/repair/ACE_Repair.hpp @@ -4,14 +4,15 @@ class ACE_Repair { displayName = CSTRING(ReplaceWheel); displayNameProgress = CSTRING(ReplacingWheel); - locations[] = {"All"}; + repairLocations[] = {"All"}; requiredEngineer = QGVAR(engineerSetting_Wheel); repairingTime = 10; repairingTimeSelfCoef = 1; items = QGVAR(wheelRepairRequiredItems); condition = QUOTE(call FUNC(canReplaceWheel)); itemConsumed = 0; - + claimObjects[] = {{"ACE_Wheel"}}; + callbackSuccess = QUOTE(call FUNC(doReplaceWheel)); callbackFailure = ""; callbackProgress = ""; @@ -27,6 +28,7 @@ class ACE_Repair { displayNameProgress = CSTRING(RemovingWheel); condition = QUOTE(call FUNC(canRemove)); callbackSuccess = QUOTE(call FUNC(doRemoveWheel)); + claimObjects[] = {}; }; class MiscRepair: ReplaceWheel { displayName = CSTRING(Repairing); // let's make empty string an auto generated string @@ -36,6 +38,7 @@ class ACE_Repair { repairingTime = 15; callbackSuccess = QUOTE(call FUNC(doRepair)); items[] = {"ToolKit"}; + claimObjects[] = {}; }; class RepairTrack: MiscRepair { displayName = CSTRING(Repairing); @@ -43,6 +46,7 @@ class ACE_Repair { condition = QUOTE(call FUNC(canRepairTrack)); callbackSuccess = QUOTE(call FUNC(doRepairTrack)); requiredEngineer = QGVAR(engineerSetting_Wheel); + claimObjects[] = {{"ACE_Track"}}; }; class RemoveTrack: MiscRepair { displayName = CSTRING(RemoveTrack); @@ -57,6 +61,7 @@ class ACE_Repair { condition = QUOTE(call FUNC(canReplaceTrack)); callbackSuccess = QUOTE(call FUNC(doReplaceTrack)); requiredEngineer = QGVAR(engineerSetting_Wheel); + claimObjects[] = {{"ACE_Track"}}; }; class FullRepair: MiscRepair { displayName = CSTRING(fullRepair); diff --git a/addons/repair/CfgVehicles.hpp b/addons/repair/CfgVehicles.hpp index ee31e2c873..3736050543 100644 --- a/addons/repair/CfgVehicles.hpp +++ b/addons/repair/CfgVehicles.hpp @@ -25,6 +25,7 @@ class CfgVehicles { function = QFUNC(moduleRepairSettings); functionPriority = 1; isGlobal = 1; + isSingular = 1; isTriggerActivated = 0; author = ECSTRING(Common,ACETeam); class Arguments { @@ -403,4 +404,7 @@ class CfgVehicles { class B_Quadbike_01_F: Quadbike_01_base_F { GVAR(hitpointPositions[]) = { {"HitEngine", {0, 0.5, -0.7}}, {"HitFuel", {0, 0, -0.5}} }; }; + class Hatchback_01_base_F: Car_F { + GVAR(hitpointPositions[]) = {{"HitBody", {0, 0.7, -0.5}}, {"HitFuel", {0, -1.75, -0.75}}}; + }; }; diff --git a/addons/repair/XEH_preInit.sqf b/addons/repair/XEH_preInit.sqf index f94c230f29..8efa47e7b3 100644 --- a/addons/repair/XEH_preInit.sqf +++ b/addons/repair/XEH_preInit.sqf @@ -17,6 +17,7 @@ PREP(doRepair); PREP(doRepairTrack); PREP(doReplaceTrack); PREP(doReplaceWheel); +PREP(getClaimObjects); PREP(getHitPointString); PREP(getPostRepairDamage); PREP(getWheelHitPointsWithSelections); diff --git a/addons/repair/functions/fnc_addRepairActions.sqf b/addons/repair/functions/fnc_addRepairActions.sqf index 7ebf978088..3887d9eff7 100644 --- a/addons/repair/functions/fnc_addRepairActions.sqf +++ b/addons/repair/functions/fnc_addRepairActions.sqf @@ -1,5 +1,5 @@ /* - * Author: commy2 + * Author: commy2, SilentSpike * Checks if the vehicles class already has the actions initialized, otherwise add all available repair options. Calleed from init EH. * * Arguments: @@ -15,10 +15,12 @@ */ #include "script_component.hpp" -params ["_vehicle"]; -TRACE_1("params", _vehicle); +if (!hasInterface) exitWith {}; -private ["_type", "_initializedClasses", "_condition", "_statement", "_action"]; +params ["_vehicle"]; +TRACE_2("params", _vehicle,typeOf _vehicle); + +private["_action", "_childHitPoint", "_condition", "_groupsConfig", "_hitPoint", "_hitPointsAddedAmount", "_hitPointsAddedNames", "_hitPointsAddedStrings", "_icon", "_initializedClasses", "_name", "_position", "_positionsConfig", "_processedHitPoints", "_selection", "_statement", "_target", "_type"]; _type = typeOf _vehicle; @@ -28,143 +30,141 @@ _initializedClasses = GETMVAR(GVAR(initializedClasses),[]); if (_type in _initializedClasses) exitWith {}; // get all hitpoints and selections -([_vehicle] call EFUNC(common,getHitPointsWithSelections)) params ["_hitPoints", "_hitPointsSelections"]; +(getAllHitPointsDamage _vehicle) params [["_hitPoints", []], ["_hitSelections", []]]; + +if (_hitSelections isEqualTo []) exitWith { ACE_LOGERROR_1("No hit selections (%1)", _type); }; // get hitpoints of wheels with their selections -([_vehicle] call FUNC(getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitPointSelections"]; +([_vehicle] call FUNC(getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; - -private ["_hitPointsAddedNames", "_hitPointsAddedStrings", "_hitPointsAddedAmount"]; _hitPointsAddedNames = []; _hitPointsAddedStrings = []; _hitPointsAddedAmount = []; +_processedHitpoints = []; -// add repair events to this vehicle class { - if (_x in _wheelHitPoints) then { - // add wheel repair action + _selection = _x; + _hitpoint = _hitPoints select _forEachIndex; - private ["_icon", "_selection", "_name", "_text"]; + if (_selection in _wheelHitSelections) then { + // Wheels should always be unique + if (_hitpoint in _processedHitpoints) exitWith {TRACE_3("Duplicate Wheel",_hitpoint,_forEachIndex,_selection);}; - _icon = QUOTE(PATHTOF(ui\tire_ca.paa)); _icon = "A3\ui_f\data\igui\cfg\actions\repair_ca.paa"; - // textDefault = ""; - _selection = _wheelHitPointSelections select (_wheelHitPoints find _x); - // remove wheel action - _name = format ["Remove_%1", _x]; + _position = compile format ["_target selectionPosition ['%1', 'HitPoints'];", _selection]; + + TRACE_3("Adding Wheel Actions",_hitpoint,_forEachIndex,_selection); + + // An action to remove the wheel is required + _name = format ["Remove_%1_%2", _forEachIndex, _hitpoint]; _text = localize LSTRING(RemoveWheel); - _condition = {[_this select 1, _this select 0, _this select 2 select 0, "RemoveWheel"] call DFUNC(canRepair)}; _statement = {[_this select 1, _this select 0, _this select 2 select 0, "RemoveWheel"] call DFUNC(repair)}; - - _action = [_name, _text, _icon, _statement, _condition, {}, [_x], _selection, 2] call EFUNC(interact_menu,createAction); + _action = [_name, _text, _icon, _statement, _condition, {}, [_hitpoint], _position, 2] call EFUNC(interact_menu,createAction); [_type, 0, [], _action] call EFUNC(interact_menu,addActionToClass); - // replace wheel action - _name = format ["Replace_%1", _x]; + // An action to replace the wheel is required + _name = format ["Replace_%1_%2", _forEachIndex, _hitpoint]; _text = localize LSTRING(ReplaceWheel); - _condition = {[_this select 1, _this select 0, _this select 2 select 0, "ReplaceWheel"] call DFUNC(canRepair)}; _statement = {[_this select 1, _this select 0, _this select 2 select 0, "ReplaceWheel"] call DFUNC(repair)}; - - _action = [_name, _text, _icon, _statement, _condition, {}, [_x], _selection, 2] call EFUNC(interact_menu,createAction); + _action = [_name, _text, _icon, _statement, _condition, {}, [_hitpoint], _position, 2] call EFUNC(interact_menu,createAction); [_type, 0, [], _action] call EFUNC(interact_menu,addActionToClass); - } else { - // exit if the hitpoint is in the blacklist, e.g. glasses - if (_x in IGNORED_HITPOINTS) exitWith {}; - - private ["_hitpointGroupConfig", "_inHitpointSubGroup", "_currentHitpoint"]; - - // Get hitpoint groups if available - _hitpointGroupConfig = configFile >> "CfgVehicles" >> _type >> QGVAR(hitpointGroups); - _inHitpointSubGroup = false; - if (isArray _hitpointGroupConfig) then { - // Set variable if current hitpoint is in a sub-group (to be excluded from adding action) - _currentHitpoint = _x; - { - { - if (_x == _currentHitpoint) exitWith { - _inHitpointSubGroup = true; - }; - } forEach (_x select 1); - } forEach (getArray _hitpointGroupConfig); + //Skip glass hitpoints + if (((toLower _hitPoint) find "glass") != -1) exitWith { + TRACE_3("Skipping Glass",_hitpoint,_forEachIndex,_selection); + }; + // Empty selections don't exist + // Empty hitpoints don't contain enough information + if (_selection isEqualTo "") exitWith { TRACE_3("Selection Empty",_hitpoint,_forEachIndex,_selection); }; + if (_hitpoint isEqualTo "") exitWith { TRACE_3("Hitpoint Empty",_hitpoint,_forEachIndex,_selection); }; + //Depends hitpoints shouldn't be modified directly (will be normalized) + if (isText (configFile >> "CfgVehicles" >> _type >> "HitPoints" >> _hitpoint >> "depends")) exitWith { + TRACE_3("Skip Depends",_hitpoint,_forEachIndex,_selection); }; - // Exit if current hitpoint is in sub-group (only main hitpoints get actions) - if (_inHitpointSubGroup) exitWith {}; + // Associated hitpoints can be grouped via config to produce a single repair action + _groupsConfig = configFile >> "CfgVehicles" >> _type >> QGVAR(hitpointGroups); + _childHitPoint = false; + if (isArray _groupsConfig) then { + { + { + if (_hitpoint == _x) exitWith { + _childHitPoint = true; + }; + } forEach (_x select 1); + } forEach (getArray _groupsConfig); + }; + // If the current selection is associated with a child hitpoint, then skip + if (_childHitPoint) exitWith { TRACE_3("childHitpoint",_hitpoint,_forEachIndex,_selection); }; - // exit if the hitpoint is virtual - if (isText (configFile >> "CfgVehicles" >> _type >> "HitPoints" >> _x >> "depends")) exitWith {}; + // Find the action position + _position = compile format ["_target selectionPosition ['%1', 'HitPoints'];", _selection]; - // add misc repair action - private ["_name", "_icon", "_selection", "_customSelectionsConfig"]; + // Custom position can be defined via config for associated hitpoint + _positionsConfig = configFile >> "CfgVehicles" >> _type >> QGVAR(hitpointPositions); + if (isArray _positionsConfig) then { + { + _x params ["_hit", "_pos"]; + if (_hitpoint == _hit) exitWith { + if (typeName _pos == "ARRAY") exitWith { + _position = _pos; // Position in model space + }; + if (typeName _pos == "STRING") exitWith { + _position = compile format ["_target selectionPosition ['%1', 'HitPoints'];", _pos]; + }; + ACE_LOGERROR_3("Invalid custom position %1 of hitpoint %2 in vehicle %3.",_position,_hitpoint,_type); + }; + } forEach (getArray _positionsConfig); + }; - _name = format ["Repair_%1", _x]; + // Prepair the repair action + _name = format ["Repair_%1_%2", _forEachIndex, _selection]; + _icon = "A3\ui_f\data\igui\cfg\actions\repair_ca.paa"; // Find localized string and track those added for numerization - ([_x, "%1", _x, [_hitPointsAddedNames, _hitPointsAddedStrings, _hitPointsAddedAmount]] call FUNC(getHitPointString)) params ["_text", "_trackArray"]; + ([_hitpoint, "%1", _hitpoint, [_hitPointsAddedNames, _hitPointsAddedStrings, _hitPointsAddedAmount]] call FUNC(getHitPointString)) params ["_text", "_trackArray"]; _hitPointsAddedNames = _trackArray select 0; _hitPointsAddedStrings = _trackArray select 1; _hitPointsAddedAmount = _trackArray select 2; - _icon = "A3\ui_f\data\igui\cfg\actions\repair_ca.paa"; - - _selection = ""; - - // Get custom position if available - _customSelectionsConfig = configFile >> "CfgVehicles" >> _type >> QGVAR(hitpointPositions); - if (isArray _customSelectionsConfig) then { - // Loop through custom hitpoint positions array - _currentHitpoint = _x; - { - _x params ["_hitpoint", "_position"]; - // Exit with supplied custom position when same hitpoint name found or print RPT error if it's invalid - if (_hitpoint == _currentHitpoint) exitWith { - if (typeName _position == "ARRAY") exitWith { - _selection = _position; // Position in model space - }; - if (typeName _position == "STRING") exitWith { - _selection = _vehicle selectionPosition _position; // Selection name - }; - ACE_LOGERROR_3("Invalid custom position %1 of hitpoint %2 in vehicle %3.",_position,_hitpoint,_vehicle); - }; - } forEach (getArray _customSelectionsConfig); - }; - - // If position still empty (not a position array or selection name) try extracting from model - if (typeName _selection == "STRING" && {_selection == ""}) then { - _selection = _vehicle selectionPosition (_hitPointsSelections select (_hitPoints find _x)); - }; - - _condition = {[_this select 1, _this select 0, _this select 2 select 0, _this select 2 select 1] call DFUNC(canRepair)}; - _statement = {[_this select 1, _this select 0, _this select 2 select 0, _this select 2 select 1] call DFUNC(repair)}; - - if (_x in TRACK_HITPOINTS) then { - if (_x == "HitLTrack") then { - _selection = [-1.75, 0, -1.75]; + if (_hitpoint in TRACK_HITPOINTS) then { + // Tracks should always be unique + if (_hitpoint in _processedHitpoints) exitWith {TRACE_3("Duplicate Track",_hitpoint,_forEachIndex,_selection);}; + if (_hitpoint == "HitLTrack") then { + _position = [-1.75, 0, -1.75]; } else { - _selection = [1.75, 0, -1.75]; + _position = [1.75, 0, -1.75]; }; - _action = [_name, _text, _icon, _statement, _condition, {}, [_x, "RepairTrack"], _selection, 4] call EFUNC(interact_menu,createAction); + TRACE_4("Adding RepairTrack",_hitpoint,_forEachIndex,_selection,_text); + _condition = {[_this select 1, _this select 0, _this select 2 select 0, "RepairTrack"] call DFUNC(canRepair)}; + _statement = {[_this select 1, _this select 0, _this select 2 select 0, "RepairTrack"] call DFUNC(repair)}; + _action = [_name, _text, _icon, _statement, _condition, {}, [_hitpoint], _position, 4] call EFUNC(interact_menu,createAction); [_type, 0, [], _action] call EFUNC(interact_menu,addActionToClass); } else { - _action = [_name, _text, _icon, _statement, _condition, {}, [_x, "MiscRepair"], _selection, 4] call EFUNC(interact_menu,createAction); + TRACE_4("Adding MiscRepair",_hitpoint,_forEachIndex,_selection,_text); + _condition = {[_this select 1, _this select 0, _this select 2 select 0, "MiscRepair"] call DFUNC(canRepair)}; + _statement = {[_this select 1, _this select 0, _this select 2 select 0, "MiscRepair"] call DFUNC(repair)}; + _action = [_name, _text, _icon, _statement, _condition, {}, [_forEachIndex], _position, 5] call EFUNC(interact_menu,createAction); // Put inside main actions if no other position was found above - if (_selection isEqualTo [0, 0, 0]) then { + if (_position isEqualTo [0,0,0]) then { [_type, 0, ["ACE_MainActions", QGVAR(Repair)], _action] call EFUNC(interact_menu,addActionToClass); } else { [_type, 0, [], _action] call EFUNC(interact_menu,addActionToClass); }; }; - }; -} forEach _hitPoints; -_condition = {[_this select 1, _this select 0, _this select 2 select 0, _this select 2 select 1] call DFUNC(canRepair)}; -_statement = {[_this select 1, _this select 0, _this select 2 select 0, _this select 2 select 1] call DFUNC(repair)}; -_action = [QGVAR(fullRepair), localize LSTRING(fullRepair), "A3\ui_f\data\igui\cfg\actions\repair_ca.paa", _statement, _condition, {}, ["", "fullRepair"], "", 4] call EFUNC(interact_menu,createAction); + _processedHitPoints pushBack _hitPoint; + }; +} forEach _hitSelections; + +_condition = {[_this select 1, _this select 0, "", "fullRepair"] call DFUNC(canRepair)}; +_statement = {[_this select 1, _this select 0, "", "fullRepair"] call DFUNC(repair)}; +_action = [QGVAR(fullRepair), localize LSTRING(fullRepair), "A3\ui_f\data\igui\cfg\actions\repair_ca.paa", _statement, _condition, {}, [], "", 4] call EFUNC(interact_menu,createAction); [_type, 0, ["ACE_MainActions", QGVAR(Repair)], _action] call EFUNC(interact_menu,addActionToClass); + // set class as initialized _initializedClasses pushBack _type; diff --git a/addons/repair/functions/fnc_addSpareParts.sqf b/addons/repair/functions/fnc_addSpareParts.sqf index 4d3197c8e8..74ea0d4c10 100644 --- a/addons/repair/functions/fnc_addSpareParts.sqf +++ b/addons/repair/functions/fnc_addSpareParts.sqf @@ -18,7 +18,6 @@ */ #include "script_component.hpp" -private ["_part"]; params ["_vehicle", ["_amount", 1], ["_part", ""], ["_force", false]]; TRACE_2("params",_vehicle,_amount); diff --git a/addons/repair/functions/fnc_canMiscRepair.sqf b/addons/repair/functions/fnc_canMiscRepair.sqf index 0533f9f4fc..7ebfb5c5a8 100644 --- a/addons/repair/functions/fnc_canMiscRepair.sqf +++ b/addons/repair/functions/fnc_canMiscRepair.sqf @@ -5,38 +5,51 @@ * Arguments: * 0: Unit that does the repairing * 1: Vehicle to repair - * 2: Selected hitpoint + * 2: Selected hitpoint INDEX * * Return Value: * Can Misc Repair * * Example: - * [unit, vehicle, "hitpoint", "classname"] call ace_repair_fnc_canMiscRepair + * [unit, vehicle, 5] call ace_repair_fnc_canMiscRepair * * Public: No */ + #include "script_component.hpp" -private ["_hitpointGroupConfig", "_hitpointGroup", "_postRepairDamage", "_return"]; -params ["_caller", "_target", "_hitPoint"]; +private ["_hitpointGroupConfig", "_hitpointGroup", "_postRepairDamage", "_return", "_hitPointClassname", "_subHitIndex"]; +params ["_caller", "_target", "_hitPointIndex"]; -if !([_unit, _target, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith)) exitWith {false}; +(getAllHitPointsDamage _target) params ["_allHitPoints", "", "_allHitPointDamages"]; + +if !([_caller, _target, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Get hitpoint groups if available _hitpointGroupConfig = configFile >> "CfgVehicles" >> typeOf _target >> QGVAR(hitpointGroups); _hitpointGroup = []; if (isArray _hitpointGroupConfig) then { + _hitPointClassname = _allHitPoints select _hitPointIndex; + // Retrieve hitpoint subgroup if current hitpoint is main hitpoint of a group { + _x params ["_masterHitpoint", "_subHitArray"]; // Exit using found hitpoint group if this hitpoint is leader of any - if (_x select 0 == _hitPoint) exitWith { - _hitpointGroup = _x select 1; + if (_masterHitpoint == _hitPointClassname) exitWith { + { + _subHitIndex = _allHitPoints find _x; + if (_subHitIndex == -1) then { + ERROR("Hitpoint Not Found"); + } else { + _hitpointGroup pushBack _subHitIndex; + }; + } forEach _subHitArray; }; } forEach (getArray _hitpointGroupConfig); }; // Add current hitpoint to the group -_hitpointGroup pushBack _hitPoint; +_hitpointGroup pushBack _hitPointIndex; // Get post repair damage _postRepairDamage = [_caller] call FUNC(getPostRepairDamage); @@ -44,7 +57,7 @@ _postRepairDamage = [_caller] call FUNC(getPostRepairDamage); // Return true if damage can be repaired on any hitpoint in the group, else false _return = false; { - if ((_target getHitPointDamage _x) > _postRepairDamage) exitWith { + if ((_allHitPointDamages select _x) > _postRepairDamage) exitWith { _return = true; }; } forEach _hitpointGroup; diff --git a/addons/repair/functions/fnc_canRepair.sqf b/addons/repair/functions/fnc_canRepair.sqf index 8fb2a4938e..74a4b07dc6 100644 --- a/addons/repair/functions/fnc_canRepair.sqf +++ b/addons/repair/functions/fnc_canRepair.sqf @@ -5,14 +5,14 @@ * Arguments: * 0: Unit that does the repairing * 1: Vehicle to repair - * 2: Selected hitpoint + * 2: Selected hitpoint or hitpointIndex or * 3: Repair Action Classname * * Return Value: * Can Repair * * Example: - * ["something", player] call ace_repair_fnc_canRepair + * [player, car, "HitHull", "MiscRepair"] call ace_repair_fnc_canRepair * * Public: Yes */ @@ -21,22 +21,22 @@ params ["_caller", "_target", "_hitPoint", "_className"]; TRACE_4("params",_caller,_target,_hitPoint,_className); -private ["_config", "_engineerRequired", "_items", "_locations", "_return", "_condition", "_vehicleStateCondition", "_settingName", "_settingItemsArray"]; +private ["_config", "_engineerRequired", "_items", "_return", "_condition", "_vehicleStateCondition", "_settingName", "_settingItemsArray"]; _config = (ConfigFile >> "ACE_Repair" >> "Actions" >> _className); -if !(isClass _config) exitwith {false}; // or go for a default? -if(isEngineOn _target) exitwith {false}; +if !(isClass _config) exitWith {false}; // or go for a default? +if(isEngineOn _target) exitWith {false}; _engineerRequired = if (isNumber (_config >> "requiredEngineer")) then { getNumber (_config >> "requiredEngineer"); } else { // Check for required class - if (isText (_config >> "requiredEngineer")) exitwith { + if (isText (_config >> "requiredEngineer")) exitWith { missionNamespace getVariable [(getText (_config >> "requiredEngineer")), 0]; }; 0; }; -if !([_caller, _engineerRequired] call FUNC(isEngineer)) exitwith {false}; +if !([_caller, _engineerRequired] call FUNC(isEngineer)) exitWith {false}; //Items can be an array of required items or a string to a ACE_Setting array _items = if (isArray (_config >> "items")) then { @@ -49,12 +49,12 @@ _items = if (isArray (_config >> "items")) then { }; _settingItemsArray select (missionNamespace getVariable _settingName); }; -if (count _items > 0 && {!([_caller, _items] call FUNC(hasItems))}) exitwith {false}; +if (count _items > 0 && {!([_caller, _items] call FUNC(hasItems))}) exitWith {false}; _return = true; if (getText (_config >> "condition") != "") then { _condition = getText (_config >> "condition"); - if (isnil _condition) then { + if (isNil _condition) then { _condition = compile _condition; } else { _condition = missionNamespace getVariable _condition; @@ -66,39 +66,47 @@ if (getText (_config >> "condition") != "") then { }; }; -if (!_return) exitwith {false}; +if (!_return) exitWith {false}; -_vehicleStateCondition = if (isText(_config >> "vehicleStateCondition")) then { - missionNamespace getVariable [getText(_config >> "vehicleStateCondition"), 0] -} else { - getNumber(_config >> "vehicleStateCondition") -}; -// if (_vehicleStateCondition == 1 && {!([_target] call FUNC(isInStableCondition))}) exitwith {false}; +// _vehicleStateCondition = if (isText(_config >> "vehicleStateCondition")) then { + // missionNamespace getVariable [getText(_config >> "vehicleStateCondition"), 0] +// } else { + // getNumber(_config >> "vehicleStateCondition") +// }; +// if (_vehicleStateCondition == 1 && {!([_target] call FUNC(isInStableCondition))}) exitWith {false}; -_locations = getArray (_config >> "repairLocations"); -if ("All" in _locations) exitwith {true}; - -private ["_repairFacility", "_repairVeh"]; -_repairFacility = {([_caller] call FUNC(isInRepairFacility)) || ([_target] call FUNC(isInRepairFacility))}; -_repairVeh = {([_caller] call FUNC(isNearRepairVehicle)) || ([_target] call FUNC(isNearRepairVehicle))}; - -{ - if (_x == "field") exitwith {_return = true;}; - if (_x == "RepairFacility" && _repairFacility) exitwith {_return = true;}; - if (_x == "RepairVehicle" && _repairVeh) exitwith {_return = true;}; - if !(isnil _x) exitwith { - private "_val"; - _val = missionNamespace getVariable _x; - if (typeName _val == "SCALAR") then { - _return = switch (_val) do { - case 0: {true}; //useAnywhere - case 1: {call _repairVeh}; //repairVehicleOnly - case 2: {call _repairFacility}; //repairFacilityOnly - case 3: {(call _repairFacility) || {call _repairVeh}}; //vehicleAndFacility - default {false}; //Disabled +private _repairLocations = getArray (_config >> "repairLocations"); +if (!("All" in _repairLocations)) then { + private _repairFacility = {([_caller] call FUNC(isInRepairFacility)) || ([_target] call FUNC(isInRepairFacility))}; + private _repairVeh = {([_caller] call FUNC(isNearRepairVehicle)) || ([_target] call FUNC(isNearRepairVehicle))}; + { + if (_x == "field") exitWith {_return = true;}; + if (_x == "RepairFacility" && _repairFacility) exitWith {_return = true;}; + if (_x == "RepairVehicle" && _repairVeh) exitWith {_return = true;}; + if !(isNil _x) exitWith { + private _val = missionNamespace getVariable _x; + if (typeName _val == "SCALAR") then { + _return = switch (_val) do { + case 0: {true}; //useAnywhere + case 1: {call _repairVeh}; //repairVehicleOnly + case 2: {call _repairFacility}; //repairFacilityOnly + case 3: {(call _repairFacility) || {call _repairVeh}}; //vehicleAndFacility + default {false}; //Disabled + }; }; }; - }; -} forEach _locations; + } forEach _repairLocations; +}; +if (!_return) exitWith {false}; -_return && alive _target; +//Check that there are required objects nearby +private _requiredObjects = getArray (_config >> "claimObjects"); +if (!(_requiredObjects isEqualTo [])) then { + private _objectsAvailable = [_caller, 5, _requiredObjects] call FUNC(getClaimObjects); + if (_objectsAvailable isEqualTo []) then { + TRACE_2("Missing Required Objects",_requiredObjects,_objectsAvailable); + _return = false + }; +}; + +_return && {alive _target}; diff --git a/addons/repair/functions/fnc_canRepairTrack.sqf b/addons/repair/functions/fnc_canRepairTrack.sqf index 0ba01afb87..e1ff4a5628 100644 --- a/addons/repair/functions/fnc_canRepairTrack.sqf +++ b/addons/repair/functions/fnc_canRepairTrack.sqf @@ -1,6 +1,6 @@ /* * Author: commy2 - * Check if the unit can replace given wheel of the vehicle. + * Check if the unit can replace given track of the vehicle. * * Arguments: * 0: Unit that does the repairing @@ -17,27 +17,11 @@ */ #include "script_component.hpp" -params ["_unit", "_target", "_hitPoint", ["_wheel",false]]; -TRACE_4("params",_unit,_target,_hitPoint,_wheel); -// TODO [_unit, _wheel] call EFUNC(common,claim); on start of action +params ["_unit", "_target", "_hitPoint"]; +TRACE_3("params",_unit,_target,_hitPoint); if !([_unit, _target, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith)) exitWith {false}; -if (typeName _wheel == "OBJECT") then { - // not near interpret as objNull - if !(_wheel in nearestObjects [_unit, ["ACE_Track"], 5]) then { - _wheel = objNull; - }; -} else { - _wheel = objNull; +//check for a near track is handled by claimObjects[] config - { - if ([_unit, _x, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith)) exitWith { - _wheel = _x; - }; - } forEach nearestObjects [_unit, ["ACE_Track"], 5]; -}; - -if (isNull _wheel || damage _wheel >= 1) exitWith {false}; - -alive _target && {_target getHitPointDamage _hitPoint > 0} +(_target getHitPointDamage _hitPoint > 0) diff --git a/addons/repair/functions/fnc_canReplaceTrack.sqf b/addons/repair/functions/fnc_canReplaceTrack.sqf index aec3a9f062..a272a0d176 100644 --- a/addons/repair/functions/fnc_canReplaceTrack.sqf +++ b/addons/repair/functions/fnc_canReplaceTrack.sqf @@ -1,12 +1,11 @@ /* * Author: commy2 - * Check if the unit can replace given wheel of the vehicle. + * Check if the unit can replace given track of the vehicle. * * Arguments: * 0: Unit that does the repairing * 1: Vehicle to repair * 2: Selected hitpoint - * 3: Track / (default: false) * * Return Value: * None @@ -18,27 +17,11 @@ */ #include "script_component.hpp" -params ["_unit", "_target", "_hitPoint", ["_track", false]]; -TRACE_4("params",_unit,_target,_hitPoint,_track); -// TODO [_unit, _track] call EFUNC(common,claim); on start of action +params ["_unit", "_target", "_hitPoint"]; +TRACE_3("params",_unit,_target,_hitPoint); if !([_unit, _target, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith)) exitWith {false}; -if (typeName _track == "OBJECT") then { - // not near interpret as objNull - if !(_track in nearestObjects [_unit, ["ACE_Track"], 5]) then { - _track = objNull; - }; -} else { - _track = objNull; +//check for a near track object is handled by claimObjects[] config - { - if ([_unit, _x, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith)) exitWith { - _track = _x; - }; - } forEach nearestObjects [_unit, ["ACE_Track"], 5]; -}; - -if (isNull _track) exitWith {false}; - -alive _target && {_target getHitPointDamage _hitPoint >= 1} +(_target getHitPointDamage _hitPoint >= 1) diff --git a/addons/repair/functions/fnc_canReplaceWheel.sqf b/addons/repair/functions/fnc_canReplaceWheel.sqf index cf7a047f19..0b7f7ad4e7 100644 --- a/addons/repair/functions/fnc_canReplaceWheel.sqf +++ b/addons/repair/functions/fnc_canReplaceWheel.sqf @@ -6,7 +6,6 @@ * 0: Unit that does the repairing * 1: Vehicle to repair * 2: Selected hitpoint - * 3: Wheel / (default: false) * * Return Value: * None @@ -18,31 +17,12 @@ */ #include "script_component.hpp" -params ["_unit", "_target", "_hitPoint", ["_wheel", false]]; -TRACE_4("params",_unit,_target,_hitPoint,_wheel); -// TODO [_unit, _wheel] call EFUNC(common,claim); on start of action -//if !([_unit, _target, _hitpoint, "ReplaceWheel"] call FUNC(canRepair)) exitwith {false}; +params ["_unit", "_target", "_hitPoint"]; +TRACE_3("params",_unit,_target,_hitPoint); if !([_unit, _target, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith)) exitWith {false}; -//if !([_unit, GVAR(engineerSetting_Wheel)] call FUNC(isEngineer)) exitWith {false}; +//check for GVAR(engineerSetting_Wheel) is handeled by requiredEngineer config +//check for a near wheel object is handled by claimObjects[] config -// check for a near wheel -if (typeName _wheel == "OBJECT") then { - // not near interpret as objNull - if !(_wheel in nearestObjects [_unit, ["ACE_Wheel"], 5]) then { - _wheel = objNull; - }; -} else { - _wheel = objNull; - - { - if ([_unit, _x, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith)) exitWith { - _wheel = _x; - }; - } forEach nearestObjects [_unit, ["ACE_Wheel"], 5]; -}; - -if (isNull _wheel) exitWith {false}; - -alive _target && {_target getHitPointDamage _hitPoint >= 1} +(_target getHitPointDamage _hitPoint >= 1) diff --git a/addons/repair/functions/fnc_doFullRepair.sqf b/addons/repair/functions/fnc_doFullRepair.sqf index 6beec4c4c7..ed67a69e99 100644 --- a/addons/repair/functions/fnc_doFullRepair.sqf +++ b/addons/repair/functions/fnc_doFullRepair.sqf @@ -1,23 +1,22 @@ /* * Author: Glowbal - * Called by repair action / progress bar. Raise events to set the new hitpoint damage. + * Fully repairs vehicle * * Arguments: - * 0: Unit that does the repairing + * 0: Unit that does the repairing (not used) * 1: Vehicle to repair - * 2: Selected hitpoint * * Return Value: * None * * Example: - * [unit, vehicle, "hitpoint"] call ace_repair_fnc_doFullRepair + * [unit, vehicle] call ace_repair_fnc_doFullRepair * * Public: No */ #include "script_component.hpp" -params ["_unit", "_vehicle", "_hitPoint"]; -TRACE_3("params",_unit,_vehicle,_hitPoint); +params ["", "_vehicle"]; +TRACE_1("params",_vehicle); _vehicle setDamage 0; diff --git a/addons/repair/functions/fnc_doRemoveTrack.sqf b/addons/repair/functions/fnc_doRemoveTrack.sqf index 68755658ca..d36407b197 100644 --- a/addons/repair/functions/fnc_doRemoveTrack.sqf +++ b/addons/repair/functions/fnc_doRemoveTrack.sqf @@ -19,10 +19,9 @@ params ["_unit", "_vehicle", "_hitPoint"]; TRACE_3("params",_unit,_vehicle,_hitPoint); -// TODO [_unit, _wheel] call EFUNC(common,claim); on start of action + // get current hitpoint damage -private "_hitPointDamage"; -_hitPointDamage = _vehicle getHitPointDamage _hitPoint; +private _hitPointDamage = _vehicle getHitPointDamage _hitPoint; // can't remove destroyed or already removed wheel if (_hitPointDamage >= 1) exitWith {}; @@ -30,10 +29,9 @@ if (_hitPointDamage >= 1) exitWith {}; // don't die by spawning / moving the wheel ["fixCollision", _unit] call EFUNC(common,localEvent); -// spawn wheel -private "_wheel"; -_wheel = ["ACE_Track", getPosASL _unit] call FUNC(spawnObject); -_wheel setdamage _hitPointDamage; +// spawn track +private _newTrack = ["ACE_Track", getPosASL _unit, _hitPointDamage] call FUNC(spawnObject); +TRACE_2("new track created",_newTrack,damage _newTrack); // raise event to set the new hitpoint damage ["setWheelHitPointDamage", _vehicle, [_vehicle, _hitPoint, 1]] call EFUNC(common,targetEvent); diff --git a/addons/repair/functions/fnc_doRemoveWheel.sqf b/addons/repair/functions/fnc_doRemoveWheel.sqf index 0ffeb7ad23..21a152c597 100644 --- a/addons/repair/functions/fnc_doRemoveWheel.sqf +++ b/addons/repair/functions/fnc_doRemoveWheel.sqf @@ -19,10 +19,9 @@ params ["_unit", "_vehicle", "_hitPoint"]; TRACE_3("params",_unit,_vehicle,_hitPoint); -// TODO [_unit, _wheel] call EFUNC(common,claim); on start of action + // get current hitpoint damage -private "_hitPointDamage"; -_hitPointDamage = _vehicle getHitPointDamage _hitPoint; +private _hitPointDamage = _vehicle getHitPointDamage _hitPoint; // can't remove destroyed or already removed wheel if (_hitPointDamage >= 1) exitWith {}; @@ -31,9 +30,8 @@ if (_hitPointDamage >= 1) exitWith {}; ["fixCollision", _unit] call EFUNC(common,localEvent); // spawn wheel -private "_wheel"; -_wheel = ["ACE_Wheel", getPosASL _unit] call FUNC(spawnObject); -_wheel setdamage _hitPointDamage; +private _newWheel = ["ACE_Wheel", getPosASL _unit, _hitPointDamage] call FUNC(spawnObject); +TRACE_2("new wheel created",_newWheel,damage _newWheel); // raise event to set the new hitpoint damage ["setWheelHitPointDamage", _vehicle, [_vehicle, _hitPoint, 1]] call EFUNC(common,targetEvent); diff --git a/addons/repair/functions/fnc_doRepair.sqf b/addons/repair/functions/fnc_doRepair.sqf index 1cf3f77bca..4c063c6c73 100644 --- a/addons/repair/functions/fnc_doRepair.sqf +++ b/addons/repair/functions/fnc_doRepair.sqf @@ -5,61 +5,70 @@ * Arguments: * 0: Unit that does the repairing * 1: Vehicle to repair - * 2: Selected hitpoint + * 2: Selected hitpointIndex * * Return Value: * None * * Example: - * [unit, vehicle, "hitpoint"] call ace_repair_fnc_doRepair + * [unit, vehicle, 6, "MiscRepair"] call ace_repair_fnc_doRepair * * Public: No */ #include "script_component.hpp" -private ["_hitPointDamage", "_text", "_hitpointGroup"]; -params ["_unit", "_vehicle", "_hitPoint"]; -TRACE_3("params",_unit,_vehicle,_hitPoint); +params ["_unit", "_vehicle", "_hitPointIndex"]; +TRACE_3("params",_unit,_vehicle,_hitPointIndex); + +private _postRepairDamageMin = [_unit] call FUNC(getPostRepairDamage); + +(getAllHitPointsDamage _vehicle) params ["_allHitPoints"]; +private _hitPointClassname = _allHitPoints select _hitPointIndex; // get current hitpoint damage -_hitPointDamage = _vehicle getHitPointDamage _hitPoint; +private _hitPointCurDamage = _vehicle getHitIndex _hitPointIndex; -_hitPointDamage = _hitPointDamage - 0.5; -// don't use negative values for damage -_hitPointDamage = _hitPointDamage max ([_unit] call FUNC(getPostRepairDamage)); +// repair a max of 0.5, don't use negative values for damage +private _hitPointNewDamage = (_hitPointCurDamage - 0.5) max _postRepairDamageMin; -// raise event to set the new hitpoint damage -["setVehicleHitPointDamage", _vehicle, [_vehicle, _hitPoint, _hitPointDamage]] call EFUNC(common,targetEvent); +if (_hitPointNewDamage < _hitPointCurDamage) then { + // raise event to set the new hitpoint damage + TRACE_3("repairing main point", _vehicle, _hitPointIndex, _hitPointNewDamage); + ["setVehicleHitPointDamage", _vehicle, [_vehicle, _hitPointIndex, _hitPointNewDamage]] call EFUNC(common,targetEvent); + _hitPointCurDamage = _hitPointNewDamage; +}; // Get hitpoint groups if available -_hitpointGroupConfig = configFile >> "CfgVehicles" >> typeOf _vehicle >> QGVAR(hitpointGroups); -_hitpointGroup = []; +private _hitpointGroupConfig = configFile >> "CfgVehicles" >> typeOf _vehicle >> QGVAR(hitpointGroups); if (isArray _hitpointGroupConfig) then { - // Retrieve group if current hitpoint is leader of any + // Retrieve hitpoint subgroup if current hitpoint is main hitpoint of a group { - if (_x select 0 == _hitPoint) exitWith { - ([_vehicle] call EFUNC(common,getHitPointsWithSelections)) params ["_hitpoints"]; - // Set all sub-group hitpoints' damage to 0, if a hitpoint is invalid print RPT error + _x params ["_masterHitpoint", "_subHitArray"]; + // Exit using found hitpoint group if this hitpoint is leader of any + if (_masterHitpoint == _hitPointClassname) exitWith { { - if (_x in _hitpoints) then { - ["setVehicleHitPointDamage", _vehicle, [_vehicle, _x, 0]] call EFUNC(common,targetEvent); + private _subHitIndex = _allHitPoints find _x; //convert hitpoint classname to index + if (_subHitIndex == -1) then { + ACE_LOGERROR_2("Invalid hitpoint %1 in hitpointGroups of %2",_x,_vehicle); } else { - diag_log text format ["[ACE] ERROR: Invalid hitpoint %1 in hitpointGroups of %2", _x, _vehicle]; + private _subPointCurDamage = _vehicle getHitIndex _hitPointIndex; + private _subPointNewDamage = (_subPointCurDamage - 0.5) max _postRepairDamageMin; + if (_subPointNewDamage < _subPointCurDamage) then { + TRACE_3("repairing sub point", _vehicle, _subHitIndex, _subPointNewDamage); + ["setVehicleHitPointDamage", _vehicle, [_vehicle, _subHitIndex, _subPointNewDamage]] call EFUNC(common,targetEvent); + }; }; - - } forEach (_x select 1); + } forEach _subHitArray; }; } forEach (getArray _hitpointGroupConfig); }; // display text message if enabled if (GVAR(DisplayTextOnRepair)) then { - private ["_textLocalized", "_textDefault"]; - // Find localized string - _textLocalized = localize ([LSTRING(RepairedHitPointFully), LSTRING(RepairedHitPointPartially)] select (_hitPointDamage > 0)); - _textDefault = localize ([LSTRING(RepairedFully), LSTRING(RepairedPartially)] select (_hitPointDamage > 0)); - ([_hitPoint, _textLocalized, _textDefault] call FUNC(getHitPointString)) params ["_text"]; + private _textLocalized = localize ([LSTRING(RepairedHitPointFully), LSTRING(RepairedHitPointPartially)] select (_hitPointCurDamage > 0)); + private _textDefault = localize ([LSTRING(RepairedFully), LSTRING(RepairedPartially)] select (_hitPointCurDamage > 0)); + ([_hitPointClassname, _textLocalized, _textDefault] call FUNC(getHitPointString)) params ["_text"]; // Display text [_text] call EFUNC(common,displayTextStructured); diff --git a/addons/repair/functions/fnc_doRepairTrack.sqf b/addons/repair/functions/fnc_doRepairTrack.sqf index de04e71920..46c94c29f9 100644 --- a/addons/repair/functions/fnc_doRepairTrack.sqf +++ b/addons/repair/functions/fnc_doRepairTrack.sqf @@ -6,43 +6,39 @@ * 0: Unit that does the repairing * 1: Vehicle to repair * 2: Selected hitpoint - * 3: Repair Action Classname + * 3: Repair Action Classname (Not used) + * 4: (Not used) + * 5: (Not used) + * 6: Required Repair Objects * * Return Value: * None * * Example: - * [unit, vehicle, "hitpoint", "classname"] call ace_repair_fnc_doRepairTrack + * [unit, vehicle, "hitpoint", "RepairTrack", [], [], [aTrack]] call ace_repair_fnc_doRepairTrack * * Public: No */ #include "script_component.hpp" -params ["_unit", "_vehicle", "_hitPoint", "_classname"]; -TRACE_4("params",_unit,_vehicle,_hitPoint,_classname); -// TODO [_unit, _wheel] call EFUNC(common,claim); on start of action +params ["_unit", "_vehicle", "_hitPoint", "", "", "", "_claimedObjects"]; +TRACE_4("params",_unit,_vehicle,_hitPoint,_claimedObjects); -private ["_hitPointDamage", "_newDamage", "_wheel"]; +_claimedObjects params [["_track", objNull]]; +if ((isNull _track) || {!([_unit, _track, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith))}) exitWith { + ACE_LOGERROR_1("Bad Track", _claimedObjects); +}; -_wheel = objNull; - -{ - if ([_unit, _x, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith)) exitWith { - _wheel = _x; - }; -} forEach nearestObjects [_unit, ["ACE_Track"], 5]; -if (isNull _wheel) exitwith {}; +// can't use a destroyed track +if ((damage _track) >= 1) exitWith {}; // get current hitpoint damage +private _hitPointDamage = _vehicle getHitPointDamage _hitPoint; +private _damageRepaired = (1 - (damage _track)) / 4; // require 4 tracks to fully replace one side -_hitPointDamage = _vehicle getHitPointDamage _hitPoint; -_newDamage = (1 - (damage _wheel)) / 4; // require 4 tracks to fully replace one side - -// can't replace a destroyed wheel -if ((damage _wheel) >= 1) exitWith {}; // don't die by spawning / moving the wheel -_hitPointDamage = (_hitPointDamage - _newDamage) min 0; -deleteVehicle _wheel; +_hitPointDamage = (_hitPointDamage - _damageRepaired) min 0; +deleteVehicle _track; // raise event to set the new hitpoint damage ["setWheelHitPointDamage", _vehicle, [_vehicle, _hitPoint, _hitPointDamage]] call EFUNC(common,targetEvent); diff --git a/addons/repair/functions/fnc_doReplaceTrack.sqf b/addons/repair/functions/fnc_doReplaceTrack.sqf index a95a669159..9eafe68c9e 100644 --- a/addons/repair/functions/fnc_doReplaceTrack.sqf +++ b/addons/repair/functions/fnc_doReplaceTrack.sqf @@ -1,54 +1,50 @@ /* * Author: commy2 - * Called by repair action / progress bar. Raise events to set the new hitpoint damage. + * Replaces a track. * * Arguments: * 0: Unit that does the repairing * 1: Vehicle to repair * 2: Selected hitpoint - * 3: Repair Action Classname + * 3: Repair Action Classname (Not used) + * 4: (Not used) + * 5: (Not used) + * 6: Required Repair Objects * * Return Value: * None * * Example: - * [unit, vehicle, "hitpoint", "classname"] call ace_repair_fnc_doReplaceTrack + * [unit, vehicle, "hitpoint", "ReplaceTrack", [], [], [aTrack]] call ace_repair_fnc_doReplaceTrack * * Public: No */ #include "script_component.hpp" -params ["_unit", "_vehicle", "_hitPoint", "_classname"]; -TRACE_4("params",_unit,_vehicle,_hitPoint,_classname); -// TODO [_unit, _wheel] call EFUNC(common,claim); on start of action +params ["_unit", "_vehicle", "_hitPoint", "", "", "", "_claimedObjects"]; +TRACE_4("params",_unit,_vehicle,_hitPoint,_claimedObjects); -private["_hitPointDamage", "_wheel"]; - -_wheel = objNull; - -{ - if ([_unit, _x, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith)) exitWith { - _wheel = _x; - }; -} forEach nearestObjects [_unit, ["ACE_Track"], 5]; -if (isNull _wheel) exitwith {}; +_claimedObjects params [["_track", objNull]]; +if ((isNull _track) || {!([_unit, _track, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith))}) exitWith { + ACE_LOGERROR_1("Bad Track", _claimedObjects); +}; // get current hitpoint damage -_hitPointDamage = _vehicle getHitPointDamage _hitPoint; +private _hitPointDamage = _vehicle getHitPointDamage _hitPoint; // can't replace not destroyed wheel if (_hitPointDamage < 1) exitWith {}; -// don't die by spawning / moving the wheel -_hitPointDamage = damage _wheel; +// get track's damage +private _newHitPointDamage = damage _track; -// can't replace a destroyed wheel -if (_hitPointDamage >= 1) exitWith {}; +// can't replace with a destroyed wheel +if (_newHitPointDamage >= 1) exitWith {}; -deleteVehicle _wheel; +deleteVehicle _track; // raise event to set the new hitpoint damage -["setWheelHitPointDamage", _vehicle, [_vehicle, _hitPoint, _hitPointDamage]] call EFUNC(common,targetEvent); +["setWheelHitPointDamage", _vehicle, [_vehicle, _hitPoint, _newHitPointDamage]] call EFUNC(common,targetEvent); // display text message if enabled if (GVAR(DisplayTextOnRepair)) then { diff --git a/addons/repair/functions/fnc_doReplaceWheel.sqf b/addons/repair/functions/fnc_doReplaceWheel.sqf index f10712d65d..ce5e9220dd 100644 --- a/addons/repair/functions/fnc_doReplaceWheel.sqf +++ b/addons/repair/functions/fnc_doReplaceWheel.sqf @@ -1,54 +1,50 @@ /* * Author: commy2 - * Called by repair action / progress bar. Raise events to set the new hitpoint damage. + * Repairs a vehicle's wheel with a ACE_wheel spare part object. * * Arguments: * 0: Unit that does the repairing * 1: Vehicle to repair * 2: Selected hitpoint - * 3: Repair Action Classname + * 3: Repair Action Classname (Not used) + * 4: (Not used) + * 5: (Not used) + * 6: Required Repair Objects * * Return Value: * None * * Example: - * [unit, vehicle, "hitpoint", "classname"] call ace_repair_fnc_doReplaceWheel + * [unit, vehicle, "hitpoint", "ReplaceWheel", [], [], [aWheel]] call ace_repair_fnc_doReplaceWheel * * Public: No */ #include "script_component.hpp" -params ["_unit", "_vehicle", "_hitPoint", "_classname"]; -TRACE_4("params",_unit,_vehicle,_hitPoint,_classname); -// TODO [_unit, _wheel] call EFUNC(common,claim); on start of action +params ["_unit", "_vehicle", "_hitPoint", "", "", "", "_claimedObjects"]; +TRACE_4("params",_unit,_vehicle,_hitPoint,_claimedObjects); -private ["_hitPointDamage", "_wheel"]; - -_wheel = objNull; - -{ - if ([_unit, _x, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith)) exitWith { - _wheel = _x; - }; -} forEach nearestObjects [_unit, ["ACE_Wheel"], 5]; -if (isNull _wheel) exitwith {}; +_claimedObjects params [["_wheel", objNull]]; +if ((isNull _wheel) || {!([_unit, _wheel, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith))}) exitWith { + ACE_LOGWARNING_1("Bad Claimed Wheel", _claimedObjects); +}; // get current hitpoint damage -_hitPointDamage = _vehicle getHitPointDamage _hitPoint; +private _hitPointDamage = _vehicle getHitPointDamage _hitPoint; // can't replace not destroyed wheel if (_hitPointDamage < 1) exitWith {}; -// don't die by spawning / moving the wheel -_hitPointDamage = damage _wheel; +// get replacement wheel's damage +private _newHitPointDamage = damage _wheel; // can't replace a destroyed wheel -if (_hitPointDamage >= 1) exitWith {}; +if (_newHitPointDamage >= 1) exitWith {}; deleteVehicle _wheel; // raise event to set the new hitpoint damage -["setWheelHitPointDamage", _vehicle, [_vehicle, _hitPoint, _hitPointDamage]] call EFUNC(common,targetEvent); +["setWheelHitPointDamage", _vehicle, [_vehicle, _hitPoint, _newHitPointDamage]] call EFUNC(common,targetEvent); // display text message if enabled if (GVAR(DisplayTextOnRepair)) then { diff --git a/addons/repair/functions/fnc_getClaimObjects.sqf b/addons/repair/functions/fnc_getClaimObjects.sqf new file mode 100644 index 0000000000..bc15975d1c --- /dev/null +++ b/addons/repair/functions/fnc_getClaimObjects.sqf @@ -0,0 +1,45 @@ +/* + * Author: PabstMirror + * Returns array of required nearby repair objects (wheels/tracks) + * + * Arguments: + * 0: Unit that does the repairing + * 1: Max range to seach from unit (meters) + * 2: Array of arrays of classnames + * + * Return Value: + * Array of objects, or [] if not all available + * + * Example: + * [player, 5, [["Ace_Track"]]] call ace_repair_fnc_getClaimObjects + * + * Public: Yes + */ +#include "script_component.hpp" + +params ["_unit", "_maxRange", "_objectsToClaim"]; +TRACE_3("params",_unit,_maxRange,_objectsToClaim); + +private _return = []; + +{ + private _requiredList = _x; //eg ["ace_track", "ace_track"] + private _ableToAquire = []; //will be array of ojbects + { + private _nearObjects = nearestObjects [_unit, [_x], _maxRange]; + private _canClaimObject = objNull; + { + if ((!(_x in _ableToAquire)) + && {[_unit, _x, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith)} + &&{(damage _x) < 1} + ) exitWith { _canClaimObject = _x; }; + } forEach _nearObjects; + if (isNull _canClaimObject) exitWith {}; + _ableToAquire pushBack _canClaimObject; + } forEach _x; + TRACE_2("Check required equals available",_requiredList,_ableToAquire); + if ((count _ableToAquire) == (count _requiredList)) exitWith {_return = _ableToAquire}; + false +} count _objectsToClaim; + +_return diff --git a/addons/repair/functions/fnc_getHitPointString.sqf b/addons/repair/functions/fnc_getHitPointString.sqf index 1358e99595..fd108e4b1f 100644 --- a/addons/repair/functions/fnc_getHitPointString.sqf +++ b/addons/repair/functions/fnc_getHitPointString.sqf @@ -13,15 +13,16 @@ * 1: Added Hitpoint (default: []) * * Example: - * [unit, vehicle, "hitpoint"] call ace_repair_fnc_getHitPointString + * ["HitFuel", "Repairing %1 ...", "Repairing HitFuel"] call ace_repair_fnc_getHitPointString * * Public: No */ #include "script_component.hpp" -private ["_track", "_trackNames", "_trackStrings", "_trackAmount", "_text", "_toFind", "_trackIndex", "_combinedString"]; params ["_hitPoint", "_textLocalized", "_textDefault", ["_trackArray", []]]; +private ["_track", "_trackNames", "_trackStrings", "_trackAmount", "_text", "_toFind", "_trackIndex", "_combinedString"]; + _track = if (count _trackArray > 0) then {true} else {false}; _trackNames = []; _trackStrings = []; @@ -37,7 +38,7 @@ if (_track) then { _text = LSTRING(Hit); // Remove "Hit" from hitpoint name if one exists -_toFind = if (_hitPoint find "Hit" == 0) then { +_toFind = if ((toLower _hitPoint) find "hit" == 0) then { [_hitPoint, 3] call CBA_fnc_substr } else { _hitPoint @@ -83,6 +84,7 @@ for "_i" from 0 to (count _hitPoint) do { // Don't display part name if no string is found in stringtable if (_text == LSTRING(Hit)) then { + if (_hitPoint != "") then { ACE_LOGWARNING_1("Hitpoint [%1] - could not be localized", _hitPoint); }; _text = _textDefault; }; diff --git a/addons/repair/functions/fnc_getPostRepairDamage.sqf b/addons/repair/functions/fnc_getPostRepairDamage.sqf index 797f7a4f22..36e4bf39ae 100644 --- a/addons/repair/functions/fnc_getPostRepairDamage.sqf +++ b/addons/repair/functions/fnc_getPostRepairDamage.sqf @@ -19,7 +19,7 @@ params ["_unit"]; TRACE_1("params",_unit); // TODO when near repair station, full repair? -if (([_unit] call FUNC(isInRepairFacility) || {[_unit] call FUNC(isNearRepairVehicle)})) exitwith {0}; +if (([_unit] call FUNC(isInRepairFacility) || {[_unit] call FUNC(isNearRepairVehicle)})) exitWith {0}; if ([_unit, GVAR(engineerSetting_Repair) + 1] call FUNC(isEngineer)) exitWith {GVAR(repairDamageThreshold_Engineer)}; if ([_unit, GVAR(engineerSetting_Repair)] call FUNC(isEngineer)) exitWith {GVAR(repairDamageThreshold)}; diff --git a/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf b/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf index 182c6f54f0..c94d40f163 100644 --- a/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf +++ b/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf @@ -10,7 +10,7 @@ * 1: Wheel hitpoint selections in model coordinates * * Example: - * [unit, vehicle, "hitpoint"] call ace_repair_fnc_getWheelHitPointsWithSelections + * [car1] call ace_repair_fnc_getWheelHitPointsWithSelections * * Public: No */ @@ -19,64 +19,80 @@ params ["_vehicle"]; TRACE_1("params",_vehicle); +private["_bestDist", "_bestIndex", "_wheelBone", "_wheelBoneNameResized", "_wheelCenter", "_wheelCenterPos", "_wheelHitPoint", "_wheelHitPointSelection", "_wheelHitPointSelections", "_wheelHitPoints", "_wheelName", "_xDist", "_xPos"]; + // get the vehicles wheel config private "_wheels"; _wheels = configfile >> "CfgVehicles" >> typeOf _vehicle >> "Wheels"; // exit with nothing if the vehicle has no wheels class -if !(isClass _wheels) exitWith {[[],[]]}; +if !(isClass _wheels) exitWith {TRACE_1("No Wheels",_wheels); [[],[]]}; + +// get all hitpoints and selections +(getAllHitPointsDamage _vehicle) params ["_hitPoints", "_hitPointSelections"]; // get all wheels and read selections from config -private ["_selections", "_bones"]; - _wheels = "true" configClasses _wheels; -_selections = []; -_bones = []; -{ - _selections pushBack getText (_x >> "center"); - - private "_bone"; - _bone = getText (_x >> "boneName"); - - _bone = toArray _bone; - _bone resize count "wheel_X_Y"; // this is a requirement for physx. Should work for all addon vehicles. - _bone = toString _bone; - - _bones pushBack _bone; -} forEach _wheels; - -// get hitpoints with their fire geometry selections -private ["_hitPointsWithSelections", "_hitPoints", "_hitPointSelections"]; - -_hitPointsWithSelections = [_vehicle] call EFUNC(common,getHitPointsWithSelections); - -_hitPoints = _hitPointsWithSelections select 0; -_hitPointSelections = _hitPointsWithSelections select 1; - -// assign hitpoints to correct wheel selection by comparing bone name and fire geometry selection -private ["_wheelHitPoints", "_wheelHitPointSelections"]; - _wheelHitPoints = []; _wheelHitPointSelections = []; + { - private "_bone"; - _bone = _x; + _wheelName = configName _x; + _wheelCenter = getText (_x >> "center"); + _wheelBone = getText (_x >> "boneName"); + _wheelBoneNameResized = _wheelBone select [0, 9]; //ount "wheel_X_Y"; // this is a requirement for physx. Should work for all addon vehicles. - private "_index"; + TRACE_4("",_wheelName,_wheelCenter,_wheelBone,_wheelBoneNameResized); - _index = -1; + _wheelHitPoint = ""; + _wheelHitPointSelection = ""; + + //Commy's orginal method { - if (_bone != "" && {_x find _bone == 0}) exitWith { // same as above. Requirement for physx. - _index = _forEachIndex; + if ((_wheelBoneNameResized != "") && {_x find _wheelBoneNameResized == 0}) exitWith { // same as above. Requirement for physx. + _wheelHitPoint = _hitPoints select _forEachIndex; + _wheelHitPointSelection = _hitPointSelections select _forEachIndex; + TRACE_2("wheel found [Orginal]", _wheelName, _wheelHitPoint); }; } forEach _hitPointSelections; - if (_index != -1) then { - _wheelHitPoints pushBack (_hitPoints select _index); - _wheelHitPointSelections pushBack (_selections select _forEachIndex); + + if (_vehicle isKindOf "Car") then { + //Backup method, search for the closest hitpoint to the wheel's center selection pos. + //Ref #2742 - RHS's HMMWV + if (_wheelHitPoint == "") then { + _wheelCenterPos = _vehicle selectionPosition _wheelCenter; + if (_wheelCenterPos isEqualTo [0,0,0]) exitWith {TRACE_1("no center?",_wheelCenter);}; + + + _bestDist = 99; + _bestIndex = -1; + { + if (_x != "") then { + _xPos = _vehicle selectionPosition _x; + if (_xPos isEqualTo [0,0,0]) exitWith {}; + _xDist = _wheelCenterPos distance _xPos; + if (_xDist < _bestDist) then { + _bestIndex = _forEachIndex; + _bestDist = _xDist; + }; + }; + } forEach _hitPointSelections; + + TRACE_2("closestPoint",_bestDist,_bestIndex); + if (_bestIndex != -1) then { + _wheelHitPoint = _hitPoints select _bestIndex; + _wheelHitPointSelection = _hitPointSelections select _bestIndex; + TRACE_2("wheel found [Backup]", _wheelName, _wheelHitPoint); + }; + }; }; -} forEach _bones; + if ((_wheelHitPoint != "") && {_wheelHitPointSelection != ""}) then { + _wheelHitPoints pushBack _wheelHitPoint; + _wheelHitPointSelections pushBack _wheelHitPointSelection; + }; +} forEach _wheels; [_wheelHitPoints, _wheelHitPointSelections] diff --git a/addons/repair/functions/fnc_hasItems.sqf b/addons/repair/functions/fnc_hasItems.sqf index 2f070c8bb6..d0030b3c07 100644 --- a/addons/repair/functions/fnc_hasItems.sqf +++ b/addons/repair/functions/fnc_hasItems.sqf @@ -23,10 +23,10 @@ private ["_return"]; _return = true; { - if (typeName _x == "ARRAY" && {({[_unit, _x] call EFUNC(common,hasItem)} count _x == 0)}) exitwith { + if (typeName _x == "ARRAY" && {({[_unit, _x] call EFUNC(common,hasItem)} count _x == 0)}) exitWith { _return = false; }; - if (typeName _x == "STRING" && {!([_unit, _x] call EFUNC(common,hasItem))}) exitwith { + if (typeName _x == "STRING" && {!([_unit, _x] call EFUNC(common,hasItem))}) exitWith { _return = false; }; } forEach _items; diff --git a/addons/repair/functions/fnc_isEngineer.sqf b/addons/repair/functions/fnc_isEngineer.sqf index 9d6af3a1ff..9a7a157783 100644 --- a/addons/repair/functions/fnc_isEngineer.sqf +++ b/addons/repair/functions/fnc_isEngineer.sqf @@ -24,6 +24,6 @@ _class = _unit getVariable ["ACE_IsEngineer", getNumber (configFile >> "CfgVehic // This if statement is here for copmatability with the common variant of isEngineer, which requires a bool. // We cannot move this function to common because we require the GVAR(engineerSetting_Repair), which only makes sense to include in the repair module. -if (typeName _class == "BOOL") then {_class = 1}; +if (typeName _class == "BOOL") then {_class = [0, 1] select _class}; _class >= (_engineerN min GVAR(engineerSetting_Repair)); diff --git a/addons/repair/functions/fnc_isInRepairFacility.sqf b/addons/repair/functions/fnc_isInRepairFacility.sqf index 0c062ff0b3..b72d8a5985 100644 --- a/addons/repair/functions/fnc_isInRepairFacility.sqf +++ b/addons/repair/functions/fnc_isInRepairFacility.sqf @@ -26,7 +26,7 @@ _repairFacility = []; _objects = (lineIntersectsWith [_object modelToWorldVisual [0, 0, (_position select 2)], _object modelToWorldVisual [0, 0, (_position select 2) +10], _object]); { - if (((typeOf _x) in _repairFacility) || (_x getVariable ["ACE_isRepairFacility",0]) > 0) exitwith { + if (((typeOf _x) in _repairFacility) || (_x getVariable ["ACE_isRepairFacility",0]) > 0) exitWith { _isInBuilding = true; }; } forEach _objects; @@ -34,7 +34,7 @@ _objects = (lineIntersectsWith [_object modelToWorldVisual [0, 0, (_position sel if (!_isInBuilding) then { _objects = position _object nearObjects 7.5; { - if (((typeOf _x) in _repairFacility) || (_x getVariable ["ACE_isRepairFacility",0]) > 0) exitwith { + if (((typeOf _x) in _repairFacility) || (_x getVariable ["ACE_isRepairFacility",0]) > 0) exitWith { _isInBuilding = true; }; } forEach _objects; diff --git a/addons/repair/functions/fnc_isNearRepairVehicle.sqf b/addons/repair/functions/fnc_isNearRepairVehicle.sqf index 677f489a88..463e281faa 100644 --- a/addons/repair/functions/fnc_isNearRepairVehicle.sqf +++ b/addons/repair/functions/fnc_isNearRepairVehicle.sqf @@ -24,7 +24,7 @@ _nearObjects = nearestObjects [_unit, ["Air","LandVehicle"], 20]; _return = false; { - if ([_x] call FUNC(isRepairVehicle)) exitwith {_return = true;}; + if ([_x] call FUNC(isRepairVehicle)) exitWith {_return = true;}; } forEach _nearObjects; _return; diff --git a/addons/repair/functions/fnc_isRepairVehicle.sqf b/addons/repair/functions/fnc_isRepairVehicle.sqf index 121bda0fe3..2c0b5a1e21 100644 --- a/addons/repair/functions/fnc_isRepairVehicle.sqf +++ b/addons/repair/functions/fnc_isRepairVehicle.sqf @@ -18,6 +18,6 @@ params ["_vehicle"]; TRACE_1("params",_vehicle); -if (_vehicle isKindOf "CAManBase") exitwith {false}; +if (_vehicle isKindOf "CAManBase") exitWith {false}; ((_vehicle getVariable ["ACE_isRepairVehicle", getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> QGVAR(canRepair))]) > 0); diff --git a/addons/repair/functions/fnc_moduleAddSpareParts.sqf b/addons/repair/functions/fnc_moduleAddSpareParts.sqf index cceb62e10c..bc2502c0f4 100644 --- a/addons/repair/functions/fnc_moduleAddSpareParts.sqf +++ b/addons/repair/functions/fnc_moduleAddSpareParts.sqf @@ -11,7 +11,7 @@ * None * * Example: - * function = "ace_repair_fnc_moduleAddSpareParts" + * [logic] call ace_repair_fnc_moduleAddSpareParts * * Public: No */ @@ -41,5 +41,6 @@ if (!isNull _logic) then { // Add spare parts { [_x, _amount, _part, true] call FUNC(addSpareParts); + false } count _list; }; diff --git a/addons/repair/functions/fnc_moduleAssignEngineer.sqf b/addons/repair/functions/fnc_moduleAssignEngineer.sqf index 240a8c3b62..d64573130c 100644 --- a/addons/repair/functions/fnc_moduleAssignEngineer.sqf +++ b/addons/repair/functions/fnc_moduleAssignEngineer.sqf @@ -11,7 +11,7 @@ * None * * Example: - * function = "ace_repair_fnc_moduleAssignEngineer" + * [logic] call ace_repair_fnc_moduleAssignEngineer * * Public: No */ diff --git a/addons/repair/functions/fnc_moduleAssignRepairFacility.sqf b/addons/repair/functions/fnc_moduleAssignRepairFacility.sqf index 7150d0226b..9f01a06afc 100644 --- a/addons/repair/functions/fnc_moduleAssignRepairFacility.sqf +++ b/addons/repair/functions/fnc_moduleAssignRepairFacility.sqf @@ -11,7 +11,7 @@ * None * * Example: - * function = "ace_repair_fnc_moduleAssignRepairFacility" + * [logic] call ace_repair_fnc_moduleAssignRepairFacility * * Public: No */ diff --git a/addons/repair/functions/fnc_moduleAssignRepairVehicle.sqf b/addons/repair/functions/fnc_moduleAssignRepairVehicle.sqf index 647b5fe52c..f5df8d58e2 100644 --- a/addons/repair/functions/fnc_moduleAssignRepairVehicle.sqf +++ b/addons/repair/functions/fnc_moduleAssignRepairVehicle.sqf @@ -11,7 +11,7 @@ * None * * Example: - * function = "ace_repair_fnc_moduleAssignRepairVehicle" + * [logic] call ace_repair_fnc_moduleAssignRepairVehicle * * Public: No */ diff --git a/addons/repair/functions/fnc_moduleRepairSettings.sqf b/addons/repair/functions/fnc_moduleRepairSettings.sqf index 98ff354662..770af07449 100644 --- a/addons/repair/functions/fnc_moduleRepairSettings.sqf +++ b/addons/repair/functions/fnc_moduleRepairSettings.sqf @@ -4,14 +4,12 @@ * * Arguments: * 0: The module logic - * 1: Synchronized units - * 2: Activated * * Return Value: * None * * Example: - * function = "ace_repair_fnc_moduleRepairSettings" + * [logic] call ace_repair_fnc_moduleRepairSettings * * Public: No */ diff --git a/addons/repair/functions/fnc_normalizeHitPoints.sqf b/addons/repair/functions/fnc_normalizeHitPoints.sqf index 88c72f4de8..a73dfcfe0d 100644 --- a/addons/repair/functions/fnc_normalizeHitPoints.sqf +++ b/addons/repair/functions/fnc_normalizeHitPoints.sqf @@ -16,33 +16,45 @@ #include "script_component.hpp" params ["_vehicle"]; -TRACE_1("params",_vehicle); +TRACE_2("params",_vehicle, typeOf _vehicle); // Can't execute all commands if the vehicle isn't local, exit if that's so -if !(local _vehicle) exitWith {}; +if !(local _vehicle) exitWith {ACE_LOGERROR_1("Vehicle Not Local %1", _vehicle);}; -private ["_hitPoints", "_config", "_dependentHitPoints", "_dependentHitPointScripts", "_damage"]; +(getAllHitPointsDamage _vehicle) params [["_allHitPoints", []]]; -_hitPoints = [_vehicle] call EFUNC(common,getHitPoints); -_config = configFile >> "CfgVehicles" >> typeOf _vehicle >> "HitPoints"; +private _config = configFile >> "CfgVehicles" >> typeOf _vehicle >> "HitPoints"; -// define global variables. Needed to parse the depends config entries. Also find dependent hitpoints. +private _realHitPoints = []; +private _dependentHitPoints = []; +private _dependentHitPointScripts = []; -_dependentHitPoints = []; -_dependentHitPointScripts = []; +// Find dependent hitpoints +{ + if ((_x != "") && {isClass (_config >> _x)} && {!(_x in _realHitPoints)}) then { + _realHitPoints pushBack _x; + if (isText (_config >> _x >> "depends")) then { + _dependentHitPoints pushBack _x; + _dependentHitPointScripts pushBack compile getText (_config >> _x >> "depends"); + }; + }; +} forEach _allHitPoints; +TRACE_2("",_realHitPoints,_dependentHitPoints); + +// Don't bother setting variables if no depends on vehicle: +if (_dependentHitPoints isEqualTo []) exitWith {}; + + +// Define global variables Total = damage _vehicle; - { missionNamespace setVariable [_x, _vehicle getHitPointDamage _x]; - if (isText (_config >> _x >> "depends")) then { - _dependentHitPoints pushBack _x; - _dependentHitPointScripts pushBack compile getText (_config >> _x >> "depends"); - }; -} forEach _hitPoints; +} forEach _realHitPoints; // apply normalized damage to all dependand hitpoints { - _damage = call (_dependentHitPointScripts select _forEachIndex); + private _damage = call (_dependentHitPointScripts select _forEachIndex); + TRACE_2("setting depend hitpoint", _x, _damage); _vehicle setHitPointDamage [_x, _damage]; } forEach _dependentHitPoints; diff --git a/addons/repair/functions/fnc_repair.sqf b/addons/repair/functions/fnc_repair.sqf index fd3b4f032b..09a5ffa27f 100644 --- a/addons/repair/functions/fnc_repair.sqf +++ b/addons/repair/functions/fnc_repair.sqf @@ -4,8 +4,8 @@ * * Arguments: * 0: Unit that does the repairing - * 1: Vehicle to repair + * 1: Vehicle to repair + * 2: Selected hitpoint or hitpointIndex or * 3: Repair Action Classname * * Return Value: @@ -21,22 +21,22 @@ params ["_caller", "_target", "_hitPoint", "_className"]; TRACE_4("params",_calller,_target,_hitPoint,_className); -private["_callbackProgress", "_callerAnim", "_calller", "_condition", "_config", "_consumeItems", "_displayText", "_engineerRequired", "_iconDisplayed", "_items", "_locations", "_repairTime", "_repairTimeConfig", "_return", "_usersOfItems", "_vehicleStateCondition", "_wpn", "_settingName", "_settingItemsArray"]; +private["_callbackProgress", "_callerAnim", "_calller", "_condition", "_config", "_consumeItems", "_displayText", "_engineerRequired", "_iconDisplayed", "_items", "_repairTime", "_repairTimeConfig", "_return", "_usersOfItems", "_vehicleStateCondition", "_wpn", "_settingName", "_settingItemsArray", "_hitPointClassname"]; _config = (ConfigFile >> "ACE_Repair" >> "Actions" >> _className); -if !(isClass _config) exitwith {false}; // or go for a default? +if !(isClass _config) exitWith {false}; // or go for a default? _engineerRequired = if (isNumber (_config >> "requiredEngineer")) then { getNumber (_config >> "requiredEngineer"); } else { // Check for required class - if (isText (_config >> "requiredEngineer")) exitwith { + if (isText (_config >> "requiredEngineer")) exitWith { missionNamespace getVariable [(getText (_config >> "requiredEngineer")), 0]; }; 0; }; -if !([_caller, _engineerRequired] call FUNC(isEngineer)) exitwith {false}; -if (isEngineOn _target) exitwith {false}; +if !([_caller, _engineerRequired] call FUNC(isEngineer)) exitWith {false}; +if (isEngineOn _target) exitWith {false}; //Items can be an array of required items or a string to a ACE_Setting array _items = if (isArray (_config >> "items")) then { @@ -49,12 +49,12 @@ _items = if (isArray (_config >> "items")) then { }; _settingItemsArray select (missionNamespace getVariable _settingName); }; -if (count _items > 0 && {!([_caller, _items] call FUNC(hasItems))}) exitwith {false}; +if (count _items > 0 && {!([_caller, _items] call FUNC(hasItems))}) exitWith {false}; _return = true; if (getText (_config >> "condition") != "") then { _condition = getText (_config >> "condition"); - if (isnil _condition) then { + if (isNil _condition) then { _condition = compile _condition; } else { _condition = missionNamespace getVariable _condition; @@ -65,48 +65,62 @@ if (getText (_config >> "condition") != "") then { _return = [_caller, _target, _hitPoint, _className] call _condition; }; }; -if (!_return) exitwith {false}; +if (!_return) exitWith {false}; -_vehicleStateCondition = if (isText(_config >> "vehicleStateCondition")) then { - missionNamespace getVariable [getText(_config >> "vehicleStateCondition"), 0] -} else { - getNumber(_config >> "vehicleStateCondition") -}; -// if (_vehicleStateCondition == 1 && {!([_target] call FUNC(isInStableCondition))}) exitwith {false}; +// _vehicleStateCondition = if (isText(_config >> "vehicleStateCondition")) then { + // missionNamespace getVariable [getText(_config >> "vehicleStateCondition"), 0] +// } else { + // getNumber(_config >> "vehicleStateCondition") +// }; +// if (_vehicleStateCondition == 1 && {!([_target] call FUNC(isInStableCondition))}) exitWith {false}; -_locations = getArray (_config >> "repairLocations"); -if ("All" in _locations) exitwith {true}; - -private ["_repairFacility", "_repairVeh"]; -_repairFacility = {([_caller] call FUNC(isInRepairFacility)) || ([_target] call FUNC(isInRepairFacility))}; -_repairVeh = {([_caller] call FUNC(isNearRepairVehicle)) || ([_target] call FUNC(isNearRepairVehicle))}; - -{ - if (_x == "field") exitwith {_return = true;}; - if (_x == "RepairFacility" && _repairFacility) exitwith {_return = true;}; - if (_x == "RepairVehicle" && _repairVeh) exitwith {_return = true;}; - if !(isnil _x) exitwith { - private "_val"; - _val = missionNamespace getVariable _x; - if (typeName _val == "SCALAR") then { - _return = switch (_val) do { - case 0: {true}; //useAnywhere - case 1: {call _repairVeh}; //repairVehicleOnly - case 2: {call _repairFacility}; //repairFacilityOnly - case 3: {(call _repairFacility) || {call _repairVeh}}; //vehicleAndFacility - default {false}; //Disabled +private _repairLocations = getArray (_config >> "repairLocations"); +if (!("All" in _repairLocations)) then { + private _repairFacility = {([_caller] call FUNC(isInRepairFacility)) || ([_target] call FUNC(isInRepairFacility))}; + private _repairVeh = {([_caller] call FUNC(isNearRepairVehicle)) || ([_target] call FUNC(isNearRepairVehicle))}; + { + if (_x == "field") exitWith {_return = true;}; + if (_x == "RepairFacility" && _repairFacility) exitWith {_return = true;}; + if (_x == "RepairVehicle" && _repairVeh) exitWith {_return = true;}; + if !(isNil _x) exitWith { + private _val = missionNamespace getVariable _x; + if (typeName _val == "SCALAR") then { + _return = switch (_val) do { + case 0: {true}; //useAnywhere + case 1: {call _repairVeh}; //repairVehicleOnly + case 2: {call _repairFacility}; //repairFacilityOnly + case 3: {(call _repairFacility) || {call _repairVeh}}; //vehicleAndFacility + default {false}; //Disabled + }; }; }; - }; -} forEach _locations; + } forEach _repairLocations; +}; -if !(_return && alive _target) exitwith {false}; +private _requiredObjects = getArray (_config >> "claimObjects"); +private _claimObjectsAvailable = []; +if (!(_requiredObjects isEqualTo [])) then { + _claimObjectsAvailable = [_caller, 5, _requiredObjects] call FUNC(getClaimObjects); + if (_claimObjectsAvailable isEqualTo []) then { + TRACE_2("Missing Required Objects",_requiredObjects,_claimObjectsAvailable); + _return = false + }; +}; + +if !(_return && alive _target) exitWith {false}; +//Last exitWith: repair_success or repair_failure will be run + +//Claim required objects +{ + TRACE_2("Claiming", _x, (typeOf _x)); + [_caller, _x, false] call EFUNC(common,claim); +} forEach _claimObjectsAvailable; _consumeItems = if (isNumber (_config >> "itemConsumed")) then { getNumber (_config >> "itemConsumed"); } else { // Check for required class - if (isText (_config >> "itemConsumed")) exitwith { + if (isText (_config >> "itemConsumed")) exitWith { missionNamespace getVariable [(getText (_config >> "itemConsumed")), 0]; }; 0; @@ -160,14 +174,14 @@ if (vehicle _caller == _caller && {_callerAnim != ""}) then { _repairTime = if (isNumber (_config >> "repairingTime")) then { getNumber (_config >> "repairingTime"); } else { - if (isText (_config >> "repairingTime")) exitwith { + if (isText (_config >> "repairingTime")) exitWith { _repairTimeConfig = getText(_config >> "repairingTime"); - if (isnil _repairTimeConfig) then { + if (isNil _repairTimeConfig) then { _repairTimeConfig = compile _repairTimeConfig; } else { _repairTimeConfig = missionNamespace getVariable _repairTimeConfig; }; - if (typeName _repairTimeConfig == "SCALAR") exitwith { + if (typeName _repairTimeConfig == "SCALAR") exitWith { _repairTimeConfig; }; [_caller, _target, _hitPoint, _className] call _repairTimeConfig; @@ -177,13 +191,21 @@ _repairTime = if (isNumber (_config >> "repairingTime")) then { private ["_processText"]; // Find localized string +_hitPointClassname = if ((typeName _hitPoint) == "STRING") then { + _hitPoint +} else { + ((getAllHitPointsDamage _target) select 0) select _hitPoint +}; _processText = getText (_config >> "displayNameProgress"); -([_hitPoint, _processText, _processText] call FUNC(getHitPointString)) params ["_text"]; +private _backupText = format [localize LSTRING(RepairingHitPoint), _hitPointClassname]; +([_hitPointClassname, _processText, _backupText] call FUNC(getHitPointString)) params ["_text"]; + +TRACE_4("display",_hitPoint,_hitPointClassname,_processText,_text); // Start repair [ _repairTime, - [_caller, _target, _hitPoint, _className, _items, _usersOfItems], + [_caller, _target, _hitPoint, _className, _items, _usersOfItems, _claimObjectsAvailable], DFUNC(repair_success), DFUNC(repair_failure), _text, diff --git a/addons/repair/functions/fnc_repair_failure.sqf b/addons/repair/functions/fnc_repair_failure.sqf index 6e27ab07a7..9e329e1041 100644 --- a/addons/repair/functions/fnc_repair_failure.sqf +++ b/addons/repair/functions/fnc_repair_failure.sqf @@ -6,23 +6,24 @@ * 0: Arguments * 0: Unit that does the repairing * 1: Vehicle to repair + * 2: Selected hitpoint or hitpointIndex or * 3: Repair Action Classname * 4: None * 5: Items available + * 6: Claimed Repair Objects * * Return Value: * None * * Example: - * [[unit, vehicle, "hitpoint", "classname", nil, [items]]] call ace_repair_fnc_repair_failure + * [[unit, vehicle, "hitpoint", "classname", nil, [items], [aWheel]]] call ace_repair_fnc_repair_failure * * Public: No */ #include "script_component.hpp" params ["_args"]; -_args params ["_caller", "_target","_selectionName","_className","","_usersOfItems"]; +_args params ["_caller", "_target","_selectionName","_className","","_usersOfItems", "_claimedObjects"]; TRACE_5("params",_caller,_target,_selectionName,_className,_usersOfItems); private ["_config","_callback", "_usersOfItems", "_weaponSelect"]; @@ -46,6 +47,13 @@ if (_weaponSelect != "") then { (_x select 0) addItem (_x select 1); } forEach _usersOfItems; +//Unclaim repair objects: +{ + TRACE_2("Releasing", _x, (typeOf _x)); + [objNull, _x, false] call EFUNC(common,claim); +} forEach _claimedObjects; + + // Record specific callback _config = (ConfigFile >> "ACE_Repair" >> "Actions" >> _className); @@ -58,4 +66,4 @@ if (isNil _callback) then { _args call _callback; -// _args call FUNC(createLitter); +//todo: repair litter? diff --git a/addons/repair/functions/fnc_repair_success.sqf b/addons/repair/functions/fnc_repair_success.sqf index ccad93663f..4c21a40ae5 100644 --- a/addons/repair/functions/fnc_repair_success.sqf +++ b/addons/repair/functions/fnc_repair_success.sqf @@ -6,21 +6,24 @@ * 0: Arguments * 0: Unit that does the repairing * 1: Vehicle to repair + * 2: Selected hitpoint or hitpointIndex or * 3: Repair Action Classname + * 4: Items + * 5: User of Items + * 6: Claimed Repair Objects * * Return Value: * None * * Example: - * [[unit, vehicle, "hitpoint", "classname"]] call ace_repair_fnc_repair_success + * [[unit, vehicle, "hitpoint", "classname", [], [], [aWheel]]] call ace_repair_fnc_repair_success * * Public: No */ #include "script_component.hpp" params ["_args"]; -_args params ["_caller", "_target","_selectionName","_className"]; +_args params ["_caller", "_target","_selectionName","_className","","","_claimedObjects"]; TRACE_4("params",_caller,_target,_selectionName,_className); private ["_config","_callback", "_weaponSelect"]; @@ -40,6 +43,12 @@ if (_weaponSelect != "") then { _caller action ["SwitchWeapon", _caller, _caller, 99]; }; +//Unclaim repair objects: +{ + TRACE_2("Releasing", _x, (typeOf _x)); + [objNull, _x, false] call EFUNC(common,claim); +} forEach _claimedObjects; + // Record specific callback _config = (ConfigFile >> "ACE_Repair" >> "Actions" >> _className); @@ -51,4 +60,4 @@ if (isNil _callback) then { }; _args call _callback; -// _args call FUNC(createLitter); +//todo: repair litter? diff --git a/addons/repair/functions/fnc_setHitPointDamage.sqf b/addons/repair/functions/fnc_setHitPointDamage.sqf index a8b4cd347b..018a03723b 100644 --- a/addons/repair/functions/fnc_setHitPointDamage.sqf +++ b/addons/repair/functions/fnc_setHitPointDamage.sqf @@ -1,86 +1,83 @@ /* * Author: commy2 * Set the hitpoint damage and change the structural damage acordingly, requires local vehicle. + * Handles the "setVehicleHitPointDamage" event * * Arguments: * 0: Local Vehicle to Damage - * 1: Selected hitpoint + * 1: Selected hitpoint INDEX * 2: Total Damage * * Return Value: * None * * Example: - * [vehicle, "hitpoint", 0.5] call ace_repair_fnc_setHitPointDamage + * [vehicle, 1, 0.5] call ace_repair_fnc_setHitPointDamage * * Public: No */ #include "script_component.hpp" -params ["_vehicle", "_hitPoint", "_hitPointDamage"]; -TRACE_3("params",_vehicle,_hitPoint,_hitPointDamage); +params ["_vehicle", "_hitPointIndex", "_hitPointDamage"]; +TRACE_4("params",_vehicle,typeOf _vehicle,_hitPointIndex,_hitPointDamage); + +private["_damageNew", "_damageOld", "_hitPointDamageRepaired", "_hitPointDamageSumOld", "_realHitpointCount", "_selectionName"]; // can't execute all commands if the vehicle isn't local. exit here. -if !(local _vehicle) exitWith {}; +if !(local _vehicle) exitWith {ACE_LOGERROR_1("Vehicle Not Local %1", _vehicle);}; -// get all valid hitpoints -private ["_hitPoints", "_hitPointsWithSelections"]; +//Check for bad typeName (changed from orignal v3.3 that took string) +if ((typeName _hitPointIndex) == "STRING") then { + ACE_DEPRECATED("repair-setHitPointDamage (hit point name ","3.5.0","hit index "); + _hitPointIndex = _allHitPoints find _hitPointIndex; +}; -_hitPoints = [_vehicle] call EFUNC(common,getHitpoints); -_hitPointsWithSelections = [_vehicle] call EFUNC(common,getHitpointsWithSelections) select 0; +// get all hitpoints and selections and damages +(getAllHitPointsDamage _vehicle) params [["_allHitPoints", []], ["_allHitPointsSelections", []], ["_allHitPointDamages", []]]; // exit if the hitpoint is not valid -if !(_hitPoint in _hitPoints) exitWith {systemChat format["NOT A VALID HITPOINT: %1",_hitpoint]}; - -// save array with damage values of all hitpoints -private "_hitPointDamages"; -_hitPointDamages = []; - -{ - _hitPointDamages set [_forEachIndex, (_vehicle getHitPointDamage _x)]; -} forEach _hitPoints; +if ((_hitPointIndex < 0) || {_hitPointIndex >= (count _allHitPoints)}) exitWith {ACE_LOGERROR_2("NOT A VALID HITPOINT: %1-%2", _hitPointIndex,_vehicle);}; // save structural damage and sum of hitpoint damages -private ["_damageOld", "_hitPointDamageSumOld"]; _damageOld = damage _vehicle; +_realHitpointCount = 0; _hitPointDamageSumOld = 0; +_hitPointDamageRepaired = 0; //positive for repairs : newSum = (oldSum - repaired) { - if (!(_x in IGNORED_HITPOINTS) && {!isText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "HitPoints" >> _x >> "depends")}) then { - _hitPointDamageSumOld = _hitPointDamageSumOld + (_hitPointDamages select (_hitPoints find _x)); + _selectionName = _allHitPointsSelections select _forEachIndex; + //Filter out all the bad hitpoints (HitPoint="" or no selection) + if ((!isNil {_vehicle getHit _selectionName}) && {_x != ""}) then { + _realHitpointCount = _realHitpointCount + 1; + + if ((((toLower _x) find "glass") == -1) && {!isText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "HitPoints" >> _x >> "depends")}) then { + _hitPointDamageSumOld = _hitPointDamageSumOld + (_allHitPointDamages select _forEachIndex); + if (_forEachIndex == _hitPointIndex) then { + _hitPointDamageRepaired = (_allHitPointDamages select _forEachIndex) - _hitPointDamage; + }; + }; }; -} forEach _hitPointsWithSelections; +} forEach _allHitPoints; -// set new damage in array -_hitPointDamages set [_hitPoints find _hitPoint, _hitPointDamage]; - -// save sum of new hitpoint damages -private "_hitPointDamageSumNew"; - -_hitPointDamageSumNew = 0; -{ - if (!(_x in IGNORED_HITPOINTS) && {!isText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "HitPoints" >> _x >> "depends")}) then { - _hitPointDamageSumNew = _hitPointDamageSumNew + (_hitPointDamages select (_hitPoints find _x)); - }; -} forEach _hitPointsWithSelections; - -// calculate new strctural damage -private "_damageNew"; -_damageNew = _hitPointDamageSumNew / count _hitPoints; +// calculate new structural damage +_damageNew = (_hitPointDamageSumOld - _hitPointDamageRepaired) / _realHitpointCount; if (_hitPointDamageSumOld > 0) then { - _damageNew = _damageOld * (_hitPointDamageSumNew / _hitPointDamageSumOld); + _damageNew = _damageOld * ((_hitPointDamageSumOld - _hitPointDamageRepaired) / _hitPointDamageSumOld); }; +TRACE_5("structuralDamage",_damageOld,_damageNew,_hitPointDamageRepaired,_hitPointDamageSumOld,_realHitpointCount); // set new structural damage value _vehicle setDamage _damageNew; -// set the new damage for that hit point +//Repair the hitpoint in the damages array: +_allHitPointDamages set [_hitPointIndex, _hitPointDamage]; +//Set the new damage for all hitpoints { - _vehicle setHitPointDamage [_x, _hitPointDamages select _forEachIndex]; -} forEach _hitPoints; + _vehicle setHitIndex [_forEachIndex, _x]; +} forEach _allHitPointDamages; // normalize hitpoints -// [_vehicle] call FUNC(normalizeHitPoints); +[_vehicle] call FUNC(normalizeHitPoints); diff --git a/addons/repair/functions/fnc_spawnObject.sqf b/addons/repair/functions/fnc_spawnObject.sqf index 1ea4b7363a..86d0b563ac 100644 --- a/addons/repair/functions/fnc_spawnObject.sqf +++ b/addons/repair/functions/fnc_spawnObject.sqf @@ -4,11 +4,11 @@ * * Arguments: * 0: Item classname - * 1: Position + * 1: Position ASL * 2: Damage * * Return Value: - * None + * The new object * * Example: * ["classname", [0, 0, 0], 1] call ace_repair_fnc_spawnObject @@ -23,10 +23,12 @@ TRACE_3("params",_item,_position,_damage); // randomized end position _position = _position vectorAdd [1 - random 2, 1 - random 2, 0]; -_item = createVehicle [_item, _position, [], 0, "NONE"]; -_item setPosASL _position; +private _newObject = createVehicle [_item, _position, [], 0, "NONE"]; +_newObject setPosASL _position; -["fixCollision", _item] call EFUNC(common,localEvent); -["fixPosition", _item] call EFUNC(common,localEvent); +_newObject setDamage _damage; -_item setDamage _damage; +["fixCollision", _newObject] call EFUNC(common,localEvent); +["fixPosition", _newObject] call EFUNC(common,localEvent); + +_newObject diff --git a/addons/repair/functions/fnc_useItem.sqf b/addons/repair/functions/fnc_useItem.sqf index 218a7a1ee4..024ee76c29 100644 --- a/addons/repair/functions/fnc_useItem.sqf +++ b/addons/repair/functions/fnc_useItem.sqf @@ -4,10 +4,10 @@ * * Arguments: * 0: Unit - * 2: Item classname + * 1: Item classname * * ReturnValue: - * None + * [Had Item to Use , Unit ] * * Example: * [unit, "classname"] call ace_repair_fnc_useItem @@ -19,8 +19,9 @@ params ["_unit", "_item"]; TRACE_2("params",_unit,_item); -if ([_unit, _item] call EFUNC(common,hasItem)) exitwith { +if ([_unit, _item] call EFUNC(common,hasItem)) exitWith { [[_unit, _item], QUOTE(EFUNC(common,useItem)), _unit] call EFUNC(common,execRemoteFnc); /* TODO Replace by event system */ [true, _unit]; }; + [false, objNull]; diff --git a/addons/repair/functions/fnc_useItems.sqf b/addons/repair/functions/fnc_useItems.sqf index f8aa176018..dd781ff371 100644 --- a/addons/repair/functions/fnc_useItems.sqf +++ b/addons/repair/functions/fnc_useItems.sqf @@ -7,7 +7,7 @@ * 1: Item classnames * * ReturnValue: - * None + * [Had Item to Use , Array of units that used the items ] * * Example: * [unit, ["classname1", "classname2"]] call ace_repair_fnc_useItems @@ -27,14 +27,14 @@ _itemsUsedBy = []; if (typeName _x == "ARRAY") then { { _itemUsedInfo = [_unit, _x] call FUNC(useItem); - if (_itemUsedInfo select 0) exitwith { _itemsUsedBy pushback [(_itemUsedInfo select 1), _x]}; + if (_itemUsedInfo select 0) exitWith { _itemsUsedBy pushback [(_itemUsedInfo select 1), _x]}; } forEach _x; }; // handle required item if (typeName _x == "STRING") then { _itemUsedInfo = [_unit, _x] call FUNC(useItem); - if (_itemUsedInfo select 0) exitwith { _itemsUsedBy pushback [(_itemUsedInfo select 1), _x]}; + if (_itemUsedInfo select 0) exitWith { _itemsUsedBy pushback [(_itemUsedInfo select 1), _x]}; }; } forEach _items; diff --git a/addons/repair/script_component.hpp b/addons/repair/script_component.hpp index a6aa1db61f..ff5d40a6ae 100644 --- a/addons/repair/script_component.hpp +++ b/addons/repair/script_component.hpp @@ -13,6 +13,4 @@ #include "\z\ace\addons\main\script_macros.hpp" - -#define IGNORED_HITPOINTS ["HitGlass1", "HitGlass2", "HitGlass3", "HitGlass4", "HitGlass5", "HitGlass6", "HitGlass7", "HitGlass8", "HitGlass9", "HitGlass10", "HitGlass11", "HitGlass12", "HitGlass13", "HitGlass14", "HitGlass15", "HitRGlass", "HitLGlass", "Glass_1_hitpoint", "Glass_2_hitpoint", "Glass_3_hitpoint", "Glass_4_hitpoint", "Glass_5_hitpoint", "Glass_6_hitpoint", "Glass_7_hitpoint", "Glass_8_hitpoint", "Glass_9_hitpoint", "Glass_10_hitpoint", "Glass_11_hitpoint", "Glass_12_hitpoint", "Glass_13_hitpoint", "Glass_14_hitpoint", "Glass_15_hitpoint", "Glass_16_hitpoint", "Glass_17_hitpoint", "Glass_18_hitpoint", "Glass_19_hitpoint", "Glass_20_hitpoint"] #define TRACK_HITPOINTS ["HitLTrack", "HitRTrack"] diff --git a/addons/respawn/functions/fnc_restoreGear.sqf b/addons/respawn/functions/fnc_restoreGear.sqf index d01e45dd50..a0ca2aa35e 100644 --- a/addons/respawn/functions/fnc_restoreGear.sqf +++ b/addons/respawn/functions/fnc_restoreGear.sqf @@ -37,7 +37,7 @@ if ( }; if (currentWeapon _unit != "") then { - local _index = 0; + private _index = 0; while { _index < 100 && {currentWeaponMode _unit != _activeWeaponMode} diff --git a/addons/sitting/CfgVehicles.hpp b/addons/sitting/CfgVehicles.hpp index 4ac0d0edb7..cb2422bd6d 100644 --- a/addons/sitting/CfgVehicles.hpp +++ b/addons/sitting/CfgVehicles.hpp @@ -7,6 +7,7 @@ class CfgVehicles { function = QFUNC(moduleInit); scope = 2; isGlobal = 1; + isSingular = 1; icon = QUOTE(PATHTOF(UI\Icon_Module_Sitting_ca.paa)); class Arguments { class enable { diff --git a/addons/spectator/UI/interface.hpp b/addons/spectator/UI/interface.hpp index e8bc6c210f..a3ad215ea2 100644 --- a/addons/spectator/UI/interface.hpp +++ b/addons/spectator/UI/interface.hpp @@ -190,8 +190,8 @@ class GVAR(interface) { 1 }; multiselectEnabled = 0; + maxHistoryDelay = 10e10; onTreeDblClick = QUOTE([ARR_2('onTreeDblClick',_this)] call FUNC(handleInterface)); - onTreeSelChanged = QUOTE([ARR_2('onTreeSelChanged',_this)] call FUNC(handleInterface)); }; class unitFrame: RscFrame { x = 0; diff --git a/addons/spectator/XEH_postInit.sqf b/addons/spectator/XEH_postInit.sqf index 35b463837f..a9737868a0 100644 --- a/addons/spectator/XEH_postInit.sqf +++ b/addons/spectator/XEH_postInit.sqf @@ -8,3 +8,6 @@ GVAR(availableModes) = [[0,1,2], [1,2], [0], [1], [2]] select GVAR(restrictModes); GVAR(availableVisions) = [[-2,-1,0,1], [-2,-1], [-2,0,1], [-2]] select GVAR(restrictVisions); }] call EFUNC(common,addEventHandler); + +// Should prevent unending spectator on mission end +addMissionEventHandler ["Ended",{ [false] call FUNC(setSpectator) }]; diff --git a/addons/spectator/XEH_preInit.sqf b/addons/spectator/XEH_preInit.sqf index e26dc27d07..13f2ba1708 100644 --- a/addons/spectator/XEH_preInit.sqf +++ b/addons/spectator/XEH_preInit.sqf @@ -35,7 +35,7 @@ GVAR(camDistance) = 10; GVAR(camMode) = 0; GVAR(camPan) = 0; GVAR(camPos) = ATLtoASL [worldSize * 0.5, worldSize * 0.5, 20]; -GVAR(camSpeed) = 2.5; +GVAR(camSpeed) = 1.5; GVAR(camTilt) = -10; GVAR(camUnit) = objNull; GVAR(camVision) = -2; diff --git a/addons/spectator/functions/fnc_handleInterface.sqf b/addons/spectator/functions/fnc_handleInterface.sqf index 7c961071c3..8f29b20296 100644 --- a/addons/spectator/functions/fnc_handleInterface.sqf +++ b/addons/spectator/functions/fnc_handleInterface.sqf @@ -45,37 +45,36 @@ switch (toLower _mode) do { }; } forEach [ [localize LSTRING(uiControls),""], - [localize LSTRING(uiToggleUnits),"1"], - [localize LSTRING(uiToggleHelp),"2"], - [localize LSTRING(uiToggleTools),"3"], - [localize LSTRING(uiToggleCompass),"4"], - [localize LSTRING(uiToggleIcons),"5"], - [localize LSTRING(uiToggleMap),"M"], - [localize LSTRING(uiToggleInterface),"Backspace"], + [localize LSTRING(uiToggleUnits),keyName 2], + [localize LSTRING(uiToggleHelp),keyName 3], + [localize LSTRING(uiToggleTools),keyName 4], + [localize LSTRING(uiToggleCompass),keyName 5], + [localize LSTRING(uiToggleIcons),keyName 6], + [localize LSTRING(uiToggleMap),keyName 50], + [localize LSTRING(uiToggleInterface),keyName 14], [localize LSTRING(freeCamControls),""], - [localize LSTRING(freeCamForward),"W"], - [localize LSTRING(freeCamBackward),"S"], - [localize LSTRING(freeCamLeft),"A"], - [localize LSTRING(freeCamRight),"D"], - [localize LSTRING(freeCamUp),"Q"], - [localize LSTRING(freeCamDown),"Z"], + [localize LSTRING(freeCamForward),keyName 17], + [localize LSTRING(freeCamBackward),keyName 31], + [localize LSTRING(freeCamLeft),keyName 30], + [localize LSTRING(freeCamRight),keyName 32], + [localize LSTRING(freeCamUp),keyName 16], + [localize LSTRING(freeCamDown),keyName 44], [localize LSTRING(freeCamPan),"RMB (Hold)"], [localize LSTRING(freeCamDolly),"LMB (Hold)"], [localize LSTRING(freeCamBoost),"Shift (Hold)"], - [localize LSTRING(freeCamFocus),"F"], [localize LSTRING(attributeControls),""], - [localize LSTRING(nextCam),"Up Arrow"], - [localize LSTRING(prevCam),"Down Arrow"], - [localize LSTRING(nextUnit),"Right Arrow"], - [localize LSTRING(prevUnit),"Left Arrow"], - [localize LSTRING(nextVis),"N"], - [localize LSTRING(prevVis),"Ctrl + N"], + [localize LSTRING(nextCam),keyName 200], + [localize LSTRING(prevCam),keyName 208], + [localize LSTRING(nextUnit),keyName 205], + [localize LSTRING(prevUnit),keyName 203], + [localize LSTRING(nextVis),keyName 49], + [localize LSTRING(prevVis),format["%1 + %2",keyName 29,keyname 49]], [localize LSTRING(adjZoom),"Scrollwheel"], - [localize LSTRING(adjSpeed),"Ctrl + Scrollwheel"], - [localize LSTRING(incZoom),"Num-/Num+"], - [localize LSTRING(incSpeed),"Ctrl + Num-/Num+"], - [localize LSTRING(reZoom),"Alt + Num-"], - [localize LSTRING(reSpeed),"Alt + Num+"] + [localize LSTRING(adjSpeed),format["%1 + Scrollwheel",keyName 29]], + [localize LSTRING(incZoom),format["%1/%2",keyName 74,keyName 78]], + [localize LSTRING(incSpeed),format["%1 + %2/%3",keyName 29,keyName 74,keyName 78]], + [localize LSTRING(reZoom),format["%1 + %2",keyName 56,keyName 74]], + [localize LSTRING(reSpeed),format["%1 + %2",keyName 56,keyName 78]] ]; // Handle support for BI's respawn counter @@ -126,7 +125,6 @@ switch (toLower _mode) do { GVAR(heldKeys) resize 255; GVAR(mouse) = [false,false]; GVAR(mousePos) = [0.5,0.5]; - GVAR(treeSel) = objNull; }; // Mouse events case "onmousebuttondown": { @@ -226,19 +224,11 @@ switch (toLower _mode) do { case 32: { // D GVAR(camDolly) set [0, GVAR(camSpeed) * ([1, 2] select _shift)]; }; - case 33: { // F - private ["_sel","_vector"]; - _sel = GVAR(treeSel); - if ((GVAR(camMode) == 0) && {!isNull _sel} && {_sel in GVAR(unitList)}) then { - _vector = (positionCameraToWorld [0,0,0]) vectorDiff (positionCameraToWorld [0,0,25]); - [nil,nil,nil,(getPosATL _sel) vectorAdd _vector] call FUNC(setCameraAttributes); - }; - }; case 44: { // Z GVAR(camBoom) = -0.5 * GVAR(camSpeed) * ([1, 2] select _shift); }; case 49: { // N - if (GVAR(camMode) == 0) then { + if (GVAR(camMode) != 1) then { if (_ctrl) then { [nil,nil,-1] call FUNC(cycleCamera); } else { @@ -250,7 +240,7 @@ switch (toLower _mode) do { [_display,nil,nil,nil,true] call FUNC(toggleInterface); }; case 57: { // Spacebar - // Freecam attachment here, if in external then set cam pos and attach + // Switch between unit and freecam here }; case 74: { // Num - if (_alt) exitWith { [nil,nil,nil,nil,nil,nil, 1.25] call FUNC(setCameraAttributes); }; @@ -261,7 +251,7 @@ switch (toLower _mode) do { }; }; case 78: { // Num + - if (_alt) exitWith { [nil,nil,nil,nil,nil,nil,nil, 2.5] call FUNC(setCameraAttributes); }; + if (_alt) exitWith { [nil,nil,nil,nil,nil,nil,nil, 1.5] call FUNC(setCameraAttributes); }; if (_ctrl) then { [nil,nil,nil,nil,nil,nil,nil, GVAR(camSpeed) + 0.05] call FUNC(setCameraAttributes); } else { @@ -335,15 +325,6 @@ switch (toLower _mode) do { [_newMode,_newUnit] call FUNC(transitionCamera); }; }; - case "ontreeselchanged": { - _args params ["_tree","_sel"]; - - if (count _sel == 3) then { - GVAR(treeSel) = objectFromNetId (_tree tvData _sel); - } else { - GVAR(treeSel) = objNull; - }; - }; case "onunitsupdate": { _args params ["_tree"]; private ["_cachedUnits","_cachedGrps","_cachedSides","_s","_g","_grp","_u","_unit","_side"]; diff --git a/addons/spectator/functions/fnc_handleMap.sqf b/addons/spectator/functions/fnc_handleMap.sqf index fd084f9967..b83ccdcd7d 100644 --- a/addons/spectator/functions/fnc_handleMap.sqf +++ b/addons/spectator/functions/fnc_handleMap.sqf @@ -18,12 +18,32 @@ #include "script_component.hpp" params ["_map"]; -private ["_cachedVehicles","_unit","_color","_icon","_txt"]; +private ["_center","_radius","_scaled","_drawVehicles","_leader","_color","_cachedVehicles","_unit","_icon","_txt"]; if (GVAR(camMode) == 0) then { _map drawIcon ["\A3\UI_F\Data\GUI\Rsc\RscDisplayMissionEditor\iconcamera_ca.paa",[0,0,0,1],GVAR(freeCamera),20,20,GVAR(camPan)]; }; +_center = _map ctrlMapScreenToWorld [0.5,0.5]; +_radius = (_map ctrlMapScreenToWorld [safeZoneX,safeZoneY]) distance2D _center; +_scaled = (ctrlMapScale _map) > 0.2; + +// Draw only group icons when scaled out +_drawVehicles = []; +{ + _leader = leader _x; + if (_scaled) then { + _color = GETVAR(_x,GVAR(gColor),[ARR_4(0,0,0,0)]); + _map drawIcon ["\A3\ui_f\data\map\markers\nato\b_inf.paa", _color, _leader, 20, 20, 0, "", 0, 0]; + } else { + if ((_leader distance2D _center) < _radius) then { + _drawVehicles append (units _x); + }; + }; + nil +} count GVAR(groupList); + +// Draw units when group leader is within screen bounds _cachedVehicles = []; { _unit = vehicle _x; @@ -41,7 +61,7 @@ _cachedVehicles = []; _icon = GETVAR(_unit,GVAR(uIcon),""); _txt = ["", GETVAR(_x,GVAR(uName),"")] select (isPlayer _x); - _map drawIcon [_icon, _color, _unit, 19, 19, getDir _unit, _txt, 1, 0.03]; + _map drawIcon [_icon, _color, _unit, 19, 19, getDir _unit, _txt, 1, 0.04]; }; - false -} count GVAR(unitList); + nil +} count (_drawVehicles arrayIntersect GVAR(unitList)); diff --git a/addons/spectator/functions/fnc_handleToolbar.sqf b/addons/spectator/functions/fnc_handleToolbar.sqf index 878f3e46de..4e79c172bd 100644 --- a/addons/spectator/functions/fnc_handleToolbar.sqf +++ b/addons/spectator/functions/fnc_handleToolbar.sqf @@ -26,8 +26,13 @@ private ["_name","_vision","_fov","_speed","_mode","_time","_toolbar"]; _toolbar = _display displayCtrl IDC_TOOL; // Find all tool values +if (GVAR(camVision) >= 0) then { + _vision = localize LSTRING(VisionThermal); +} else { + _vision = [localize LSTRING(VisionNight), localize LSTRING(VisionNormal)] select (GVAR(camVision) < -1); +}; + if (GVAR(camMode) == 0) then { - _vision = if (GVAR(camVision) >= 0) then {localize LSTRING(VisionThermal)} else { [localize LSTRING(VisionNight), localize LSTRING(VisionNormal)] select (GVAR(camVision) < -1) }; _fov = format ["%1x", floor(GVAR(camZoom) * 100) * 0.01]; _speed = format ["%1 m/s", floor(GVAR(camSpeed) * 100) * 0.01]; } else { diff --git a/addons/spectator/functions/fnc_interrupt.sqf b/addons/spectator/functions/fnc_interrupt.sqf index 48cca7d102..72bb3eaa32 100644 --- a/addons/spectator/functions/fnc_interrupt.sqf +++ b/addons/spectator/functions/fnc_interrupt.sqf @@ -4,7 +4,7 @@ * * Arguments: * 0: Reason - * 1: Interrupting + * 1: Interrupting (default: true) * * Return Value: * None diff --git a/addons/spectator/functions/fnc_respawnTemplate.sqf b/addons/spectator/functions/fnc_respawnTemplate.sqf index d903e3ecc4..4584a1fc3c 100644 --- a/addons/spectator/functions/fnc_respawnTemplate.sqf +++ b/addons/spectator/functions/fnc_respawnTemplate.sqf @@ -34,7 +34,7 @@ _pos = (getPosATL _unit) vectorAdd [0,0,5]; // Enter/exit spectator based on the respawn type and whether killed/respawned if (alive _unit) then { if (_respawn == 1) then { - [_unit,QGVAR(isSeagull)] call EFUNC(common,hideUnit); + [_unit] call FUNC(stageSpectator); [2,_killer,_vision,_pos,getDir _unit] call FUNC(setCameraAttributes); [true] call FUNC(setSpectator); } else { diff --git a/addons/spectator/functions/fnc_setCameraAttributes.sqf b/addons/spectator/functions/fnc_setCameraAttributes.sqf index dd8dd3ef6a..f908b30b76 100644 --- a/addons/spectator/functions/fnc_setCameraAttributes.sqf +++ b/addons/spectator/functions/fnc_setCameraAttributes.sqf @@ -1,23 +1,24 @@ /* * Author: SilentSpike * Sets the spectator camera attributes as desired + * All values are optional and default to whatever the current value is * * Arguments: - * 0: Camera mode + * 0: Camera mode * - 0: Free * - 1: Internal * - 2: External - * 1: Camera unit (objNull for random) - * 2: Camera vision + * 1: Camera unit (objNull for random) + * 2: Camera vision * - -2: Normal * - -1: Night vision * - 0: Thermal white hot * - 1: Thermal black hot - * 3: Camera position (ATL) - * 4: Camera pan (0 - 360) - * 5: Camera tilt (-90 - 90) - * 6: Camera zoom (0.01 - 2) - * 7: Camera speed in m/s (0.05 - 10) + * 3: Camera position (ATL) + * 4: Camera pan (0 - 360) + * 5: Camera tilt (-90 - 90) + * 6: Camera zoom (0.01 - 2) + * 7: Camera speed in m/s (0.05 - 10) * * Return Value: * None diff --git a/addons/spectator/functions/fnc_setSpectator.sqf b/addons/spectator/functions/fnc_setSpectator.sqf index efa7000b8f..065ca0079b 100644 --- a/addons/spectator/functions/fnc_setSpectator.sqf +++ b/addons/spectator/functions/fnc_setSpectator.sqf @@ -7,7 +7,8 @@ * The spectator interface will be opened/closed * * Arguments: - * 0: Spectator state of local client + * 0: Spectator state of local client (default: true) + * 1: Force interface (default: true) * * Return Value: * None @@ -20,7 +21,7 @@ #include "script_component.hpp" -params [["_set",true,[true]]]; +params [["_set",true,[true]], ["_force",true,[true]]]; // Only clients can be spectators if (!hasInterface) exitWith {}; @@ -29,7 +30,10 @@ if (!hasInterface) exitWith {}; if (_set isEqualTo GVAR(isSet)) exitwith {}; // Handle common addon audio -if (["ace_hearing"] call EFUNC(common,isModLoaded)) then {EGVAR(hearing,disableVolumeUpdate) = _set}; +if (["ace_hearing"] call EFUNC(common,isModLoaded)) then { + EGVAR(hearing,disableVolumeUpdate) = _set; + EGVAR(hearing,deafnessDV) = 0; +}; if (["acre_sys_radio"] call EFUNC(common,isModLoaded)) then {[_set] call acre_api_fnc_setSpectator}; if (["task_force_radio"] call EFUNC(common,isModLoaded)) then {[player, _set] call TFAR_fnc_forceSpectator}; @@ -45,7 +49,6 @@ if (_set) then { GVAR(heldKeys) resize 255; GVAR(mouse) = [false,false]; GVAR(mousePos) = [0.5,0.5]; - GVAR(treeSel) = objNull; // Update units before opening to support pre-set camera unit [] call FUNC(updateUnits); @@ -75,7 +78,17 @@ if (_set) then { [{ // Create the display (findDisplay 46) createDisplay QGVAR(interface); - }, []] call EFUNC(common,execNextFrame); + + // If not forced, make esc end spectator + if (_this) then { + (findDisplay 12249) displayAddEventHandler ["KeyDown", { + if (_this select 1 == 1) then { + [false] call ace_spectator_fnc_setSpectator; + true + }; + }]; + }; + }, !_force] call EFUNC(common,execNextFrame); // Cache and disable nametag settings if (["ace_nametags"] call EFUNC(common,isModLoaded)) then { @@ -119,7 +132,6 @@ if (_set) then { GVAR(heldKeys) = nil; GVAR(mouse) = nil; GVAR(mousePos) = nil; - GVAR(treeSel) = nil; // Reset nametag settings if (["ace_nametags"] call EFUNC(common,isModLoaded)) then { diff --git a/addons/spectator/functions/fnc_stageSpectator.sqf b/addons/spectator/functions/fnc_stageSpectator.sqf index 7f0d862719..61445f3dd9 100644 --- a/addons/spectator/functions/fnc_stageSpectator.sqf +++ b/addons/spectator/functions/fnc_stageSpectator.sqf @@ -7,8 +7,8 @@ * Upon unstage, units will be moved to the position they were in upon staging * * Arguments: - * 0: Unit to put into spectator stage - * 1: Spectator stage + * 0: Unit to put into spectator stage (default: player) + * 1: Unit should be staged (default: true) * * Return Value: * None diff --git a/addons/spectator/functions/fnc_transitionCamera.sqf b/addons/spectator/functions/fnc_transitionCamera.sqf index edc7fa23a2..0f6eb3ffc7 100644 --- a/addons/spectator/functions/fnc_transitionCamera.sqf +++ b/addons/spectator/functions/fnc_transitionCamera.sqf @@ -49,7 +49,6 @@ if (_newMode == 0) then { // Free // Preserve camUnit value for consistency when manually changing view _camera cameraEffect ["internal", "back"]; - showCinemaBorder false; // Apply the camera zoom _camera camSetFov -(linearConversion [0.01,2,GVAR(camZoom),-2,-0.01,true]); @@ -63,23 +62,6 @@ if (_newMode == 0) then { // Free GVAR(camAgent) switchCamera "internal"; clearRadio; - - // If new vision isn't available then keep current (unless current also isn't) - if !(_newVision in GVAR(availableVisions)) then { - _newVision = GVAR(availableVisions) select ((GVAR(availableVisions) find GVAR(camVision)) max 0); - }; - - // Vision mode only applies to free cam - if (_newVision < 0) then { - false setCamUseTi 0; - camUseNVG (_newVision >= -1); - } else { - true setCamUseTi _newVision; - }; - GVAR(camVision) = _newVision; - - // Handle camera movement - if (isNil QGVAR(camHandler)) then { GVAR(camHandler) = [FUNC(handleCamera), 0] call CBA_fnc_addPerFrameHandler; }; } else { _camera = GVAR(unitCamera); @@ -103,10 +85,6 @@ if (_newMode == 0) then { // Free } else { // Switch to the camera _camera cameraEffect ["internal", "back"]; - showCinemaBorder false; - - // Handle camera orbit movement - if (isNil QGVAR(camHandler)) then { GVAR(camHandler) = [FUNC(handleCamera), 0] call CBA_fnc_addPerFrameHandler; }; }; // Clear radio if group changed @@ -117,4 +95,27 @@ if (_newMode == 0) then { // Free GVAR(camUnit) = _newUnit; }; +if (_newMode in [0,2]) then { + // Set up camera UI + showCinemaBorder false; + cameraEffectEnableHUD true; + + // Handle camera movement + if (isNil QGVAR(camHandler)) then { GVAR(camHandler) = [FUNC(handleCamera), 0] call CBA_fnc_addPerFrameHandler; }; + + // If new vision isn't available then keep current (unless current also isn't) + if !(_newVision in GVAR(availableVisions)) then { + _newVision = GVAR(availableVisions) select ((GVAR(availableVisions) find GVAR(camVision)) max 0); + }; + + // Vision mode applies to free and external cam + if (_newVision < 0) then { + false setCamUseTi 0; + camUseNVG (_newVision >= -1); + } else { + true setCamUseTi _newVision; + }; + GVAR(camVision) = _newVision; +}; + GVAR(camMode) = _newMode; diff --git a/addons/spectator/functions/fnc_updateUnits.sqf b/addons/spectator/functions/fnc_updateUnits.sqf index 0297b31b8d..e5b15b6bc1 100644 --- a/addons/spectator/functions/fnc_updateUnits.sqf +++ b/addons/spectator/functions/fnc_updateUnits.sqf @@ -4,7 +4,7 @@ * * Arguments: * 0: Units to add to the whitelist - * 1: Use blacklist + * 1: Use blacklist (default: false) * * Return Value: * None diff --git a/addons/spectator/stringtable.xml b/addons/spectator/stringtable.xml index 00d50e4704..d8c7cd1310 100644 --- a/addons/spectator/stringtable.xml +++ b/addons/spectator/stringtable.xml @@ -344,14 +344,6 @@ Ускорение камеры Aumento de velocidad - - Focus on Unit - Skup na jednostce - Focar na unidade - Фокус на юните - Zaměřit se na Jednotku - Centrarse en la unidad - Interface Interfejs diff --git a/addons/spottingscope/CfgVehicles.hpp b/addons/spottingscope/CfgVehicles.hpp index 2c8159fbb1..434c1c96ca 100644 --- a/addons/spottingscope/CfgVehicles.hpp +++ b/addons/spottingscope/CfgVehicles.hpp @@ -56,7 +56,7 @@ class CfgVehicles { side = 1; typicalCargo[] = {"Soldier"}; displayName = CSTRING(DisplayName); - model = PATHTOF(data\spottingscope.p3d); + model = PATHTOF(data\ace_spottingscope.p3d); mapSize = 0.5; transportSoldier = 0; getInAction = "GetInLow"; @@ -89,9 +89,9 @@ class CfgVehicles { initAngleY = 0; minAngleY = -100; maxAngleY = 100; - initFov = 0.7; - minFov = 0.7; - maxFov = 0.7; + initFov = 0.75; + minFov = 0.25; + maxFov = 1.25; }; class ViewOptics { initAngleX = 0; @@ -100,9 +100,9 @@ class CfgVehicles { initAngleY = 0; minAngleY = -100; maxAngleY = 100; - initFov = 0.014812; - minFov = 0.014812; - maxFov = 0.014812; + minFov = 0.0025; + maxFov = 0.05; + initFov= 0.05; }; }; }; diff --git a/addons/spottingscope/CfgWeapons.hpp b/addons/spottingscope/CfgWeapons.hpp index 4ba078c057..9b5825572b 100644 --- a/addons/spottingscope/CfgWeapons.hpp +++ b/addons/spottingscope/CfgWeapons.hpp @@ -8,7 +8,7 @@ class CfgWeapons { displayName = CSTRING(DisplayName); descriptionShort = ""; picture = PATHTOF(UI\w_spottingscope_ca.paa); - model = PATHTOF(data\w_spottingscope.p3d); + model = PATHTOF(data\ace_spottingscope.p3d); class ItemInfo: InventoryItem_Base_F { mass = 40; diff --git a/addons/spottingscope/config.cpp b/addons/spottingscope/config.cpp index 157e430868..c3541eed39 100644 --- a/addons/spottingscope/config.cpp +++ b/addons/spottingscope/config.cpp @@ -6,7 +6,7 @@ class CfgPatches { weapons[] = {"ACE_SpottingScope"}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_apl", "ace_interaction"}; - author[] = {"Rocko", "Scubaman3D", "Ruthberg", "commy2"}; + author[] = {"Rocko", "Scubaman3D", "Ruthberg", "commy2", "p1nga"}; VERSION_CONFIG; }; }; diff --git a/addons/spottingscope/data/ace_spottingscope.p3d b/addons/spottingscope/data/ace_spottingscope.p3d new file mode 100644 index 0000000000..fc6bc45354 Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope.p3d differ diff --git a/addons/spottingscope/data/ace_spottingscope_as.paa b/addons/spottingscope/data/ace_spottingscope_as.paa new file mode 100644 index 0000000000..a7e517e4ff Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_as.paa differ diff --git a/addons/spottingscope/data/ace_spottingscope_co.paa b/addons/spottingscope/data/ace_spottingscope_co.paa new file mode 100644 index 0000000000..669d94f4ae Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_co.paa differ diff --git a/addons/spottingscope/data/ace_spottingscope_glass.rvmat b/addons/spottingscope/data/ace_spottingscope_glass.rvmat new file mode 100644 index 0000000000..bce3c40b59 --- /dev/null +++ b/addons/spottingscope/data/ace_spottingscope_glass.rvmat @@ -0,0 +1,96 @@ +class StageTI +{ + texture="a3\data_f\Default_ti_ca.paa"; +}; +ambient[]={0.301,0.63999999,0.68000001,1}; +diffuse[]={0.301,0.63999999,0.68000001,1}; +forcedDiffuse[]={0.2,0.34999999,0.2,0}; +emmisive[]={0,0,0,1}; +specular[]={0.67450982,0.64313728,0.50196081,1}; +specularPower=550; +PixelShaderID="Super"; +VertexShaderID="Super"; +class Stage1 +{ + texture="z\ace\addons\spottingscope\data\ace_spottingscope_nohq.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage2 +{ + texture="#(argb,8,8,3)color(0.5,0.5,0.5,1,DT)"; + uvSource="tex"; + class uvTransform + { + aside[]={6,0,0}; + up[]={0,6,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage3 +{ + texture="#(argb,8,8,3)color(0,0,0,0,MC)"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage4 +{ + texture="z\ace\addons\spottingscope\data\ace_spottingscope_as.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage5 +{ + texture="z\ace\addons\spottingscope\data\ace_spottingscope_smdi.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage6 +{ + texture="#(ai,32,128,1)fresnel(4.01,2.86)"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage7 +{ + texture="a3\data_f\env_land_co.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; diff --git a/addons/spottingscope/data/ace_spottingscope_item.p3d b/addons/spottingscope/data/ace_spottingscope_item.p3d new file mode 100644 index 0000000000..d2de0edf1c Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_item.p3d differ diff --git a/addons/spottingscope/data/ace_spottingscope_metal.rvmat b/addons/spottingscope/data/ace_spottingscope_metal.rvmat new file mode 100644 index 0000000000..54cfcafeb8 --- /dev/null +++ b/addons/spottingscope/data/ace_spottingscope_metal.rvmat @@ -0,0 +1,92 @@ +ambient[]={1,1,1,1}; +diffuse[]={1,1,1,1}; +forcedDiffuse[]={0,0,0,0}; +emmisive[]={0,0,0,1}; +specular[]={0.2,0.2,0.2,0}; +specularPower=100; +PixelShaderID="Super"; +VertexShaderID="Super"; +class Stage1 +{ + texture="z\ace\addons\spottingscope\data\ace_spottingscope_nohq.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage2 +{ + texture="#(argb,8,8,3)color(0.5,0.5,0.5,1,DT)"; + uvSource="tex"; + class uvTransform + { + aside[]={6,0,0}; + up[]={0,6,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage3 +{ + texture="#(argb,8,8,3)color(0,0,0,0,MC)"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage4 +{ + texture="z\ace\addons\spottingscope\data\ace_spottingscope_as.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage5 +{ + texture="z\ace\addons\spottingscope\data\ace_spottingscope_smdi.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage6 +{ + texture="#(ai,32,128,1)fresnel(4.01,2.86)"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage7 +{ + texture="a3\data_f\env_land_co.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; diff --git a/addons/spottingscope/data/ace_spottingscope_nohq.paa b/addons/spottingscope/data/ace_spottingscope_nohq.paa new file mode 100644 index 0000000000..5cc7f00dfd Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_nohq.paa differ diff --git a/addons/spottingscope/data/ace_spottingscope_rubber.rvmat b/addons/spottingscope/data/ace_spottingscope_rubber.rvmat new file mode 100644 index 0000000000..c31f850e7d --- /dev/null +++ b/addons/spottingscope/data/ace_spottingscope_rubber.rvmat @@ -0,0 +1,85 @@ +ambient[]={1,1,1,1}; +diffuse[]={1,1,1,1}; +forcedDiffuse[]={0,0,0,0}; +emmisive[]={0,0,0,1}; +specular[]={0.25,0.25,0.25,1}; +specularPower=90; +PixelShaderID="Super"; +VertexShaderID="Super"; +class Stage1 +{ + texture="z\ace\addons\spottingscope\data\ace_spottingscope_nohq.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage2 +{ + texture="#(argb,8,8,3)color(0.5,0.5,0.5,1,DT)"; + uvSource="tex"; + class uvTransform + { + aside[]={6,0,0}; + up[]={0,6,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage3 +{ + texture="#(argb,8,8,3)color(0,0,0,0,MC)"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage4 +{ + texture="z\ace\addons\spottingscope\data\ace_spottingscope_as.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage5 +{ + texture="z\ace\addons\spottingscope\data\ace_spottingscope_smdi.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage6 +{ + texture="#(ai,64,64,1)fresnel(1.5,1.22)"; + uvSource="none"; +}; +class Stage7 +{ + texture="a3\data_f\env_land_co.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; diff --git a/addons/spottingscope/data/ace_spottingscope_smdi.paa b/addons/spottingscope/data/ace_spottingscope_smdi.paa new file mode 100644 index 0000000000..844626c0af Binary files /dev/null and b/addons/spottingscope/data/ace_spottingscope_smdi.paa differ diff --git a/addons/spottingscope/data/m144_ca.paa b/addons/spottingscope/data/m144_ca.paa index 4d7a63ba0a..a2d299d937 100644 Binary files a/addons/spottingscope/data/m144_ca.paa and b/addons/spottingscope/data/m144_ca.paa differ diff --git a/addons/spottingscope/data/model.cfg b/addons/spottingscope/data/model.cfg index e7beb2f2c1..71eb918bf7 100644 --- a/addons/spottingscope/data/model.cfg +++ b/addons/spottingscope/data/model.cfg @@ -9,8 +9,11 @@ class CfgSkeletons isDiscrete = 1; skeletonInherit = "Default"; skeletonBones[] = { - "otocvez","", - "otochlaven","otocvez" + "main_turret","", + "main_gun","main_turret", + "leg_01","", + "leg_02","", + "leg_03","" }; }; }; @@ -20,15 +23,15 @@ class CfgModels { sections[] = {}; skeletonName = ""; }; - class spottingscope: Default { + class ace_spottingscope: Default { skeletonName = "ace_spottingscope_skeleton"; sectionsInherit = "Default"; class animations { class mainTurret { type = "rotationY"; source = "mainTurret"; - selection = "otocvez"; - axis = "osaveze"; + selection = "main_turret"; + axis = "main_turret_axis"; minValue = "rad -360"; maxValue = "rad +360"; angle0 = "rad -360"; @@ -37,13 +40,31 @@ class CfgModels { class mainGun { type = "rotationX"; source = "mainGun"; - selection = "otochlaven"; - axis = "osahlavne"; + selection = "main_gun"; + axis = "main_gun_axis"; minValue = "rad -360"; maxValue = "rad +360"; angle0 = "rad -360"; angle1 = "rad +360"; }; + class leg_01 { + type = "rotation"; + source = "fold_legs"; + selection = "leg_01"; + axis="leg_01_axis"; + minValue = 0; + maxValue = 1; + angle0="rad +00"; + angle1="rad +55"; + }; + class leg_02: leg_01 { + selection = "leg_02"; + axis="leg_02_axis"; + }; + class leg_03: leg_01 { + selection = "leg_03"; + axis="leg_03_axis"; + }; }; }; }; diff --git a/addons/tacticalladder/stringtable.xml b/addons/tacticalladder/stringtable.xml index 57f03f7600..3d377ed420 100644 --- a/addons/tacticalladder/stringtable.xml +++ b/addons/tacticalladder/stringtable.xml @@ -42,6 +42,7 @@ Ausfahren, +Strg kippen Rozłóż, +Ctrl nachyl Extender, +Ctrl tilt + Разложить, +Ctrl наклонить Position ladder diff --git a/addons/vehiclelock/CfgVehicles.hpp b/addons/vehiclelock/CfgVehicles.hpp index 9e6f155616..873c875f09 100644 --- a/addons/vehiclelock/CfgVehicles.hpp +++ b/addons/vehiclelock/CfgVehicles.hpp @@ -74,6 +74,7 @@ class CfgVehicles { function = QFUNC(moduleInit); scope = 2; isGlobal = 0; + isSingular = 1; icon = QUOTE(PATHTOF(UI\Icon_Module_VehicleLock_ca.paa)); functionPriority = 0; class Arguments { diff --git a/addons/vehiclelock/README.md b/addons/vehiclelock/readme.md similarity index 76% rename from addons/vehiclelock/README.md rename to addons/vehiclelock/readme.md index c31402c6e3..64ae01a99c 100644 --- a/addons/vehiclelock/README.md +++ b/addons/vehiclelock/readme.md @@ -5,10 +5,11 @@ Adds keys as an item, to lock and unlock vehicles. Primary target would be role play or TVT, but has uses in all game types, even co-ops (e.g.: DAC AI will steal unlocked vehicles) Two key modes (can be used together): -- Simple Side based keys (e.g. "ACE_key_west" works on any [WEST] vehicle like the M-ATV//hunter) -- Custom keys (one key will only open a specific vehicle and nothing else) +* Simple Side based keys (e.g. "ACE_key_west" works on any [WEST] vehicle like the M-ATV//hunter) +* Custom keys (one key will only open a specific vehicle and nothing else) #### Items Added: + `ACE_key_lockpick` `ACE_key_master` `ACE_key_west` @@ -19,21 +20,19 @@ Two key modes (can be used together): #### Magazine added: `ACE_key_customKeyMagazine` (should never be manualy added, needs to be "programed" to work on a vehicle, see `ACE_VehicleLock_fnc_addKeyForVehicle`) - ## For Mission Makers: #### Modules: -- Vehicle Lock Setup - Settings for locking inventory of locked vehicles, default lockpick time, and initial vehicle lock state. -- Vehicle Key Assign - Sync with vehicles and players. Will handout custom keys to players for every synced vehicle. Will NOT work for JIP units. +* Vehicle Lock Setup - Settings for locking inventory of locked vehicles, default lockpick time, and initial vehicle lock state. +* Vehicle Key Assign - Sync with vehicles and players. Will handout custom keys to players for every synced vehicle. Will NOT work for JIP units. #### Vehicle setVariables: -- `ACE_VehicleLock_lockSide` - SIDE: overrides a vehicle's side, allows indfor to use little-bird's with indp keys -- `ACE_vehicleLock_lockpickStrength` - NUMBER: secons, determines how long lockpicking with take, overrides ACE_VehicleLock_DefaultLockpickStrength +* `ACE_VehicleLock_lockSide` - SIDE: overrides a vehicle's side, allows indfor to use little-bird's with indp keys +* `ACE_vehicleLock_lockpickStrength` - NUMBER: secons, determines how long lockpicking with take, overrides ACE_VehicleLock_DefaultLockpickStrength #### Public Functions: `[bob, car1, true] call ACE_VehicleLock_fnc_addKeyForVehicle;` - will add a `ACE_key_customKeyMagazine` to bob and program it to work on car1 - ## Maintainers The people responsible for merging changes to this component or answering potential questions. diff --git a/addons/viewdistance/CfgVehicles.hpp b/addons/viewdistance/CfgVehicles.hpp index 8e4e30d266..86d906bfce 100644 --- a/addons/viewdistance/CfgVehicles.hpp +++ b/addons/viewdistance/CfgVehicles.hpp @@ -7,6 +7,7 @@ class CfgVehicles { displayName = CSTRING(Module_DisplayName); scope = 2; isGlobal = 1; + isSingular = 1; //icon = ""; // needs an icon class Arguments { class moduleViewDistanceEnabled { diff --git a/addons/weather/CfgVehicles.hpp b/addons/weather/CfgVehicles.hpp index ebdd65c30d..f37a62449a 100644 --- a/addons/weather/CfgVehicles.hpp +++ b/addons/weather/CfgVehicles.hpp @@ -8,6 +8,7 @@ class CfgVehicles { function = QUOTE(DFUNC(initModuleSettings)); functionPriority = 1; isGlobal = 1; + isSingular = 1; isTriggerActivated = 0; author = ECSTRING(common,ACETeam); class Arguments { diff --git a/addons/winddeflection/CfgVehicles.hpp b/addons/winddeflection/CfgVehicles.hpp index 2694bb1b34..c52949e1fc 100644 --- a/addons/winddeflection/CfgVehicles.hpp +++ b/addons/winddeflection/CfgVehicles.hpp @@ -8,6 +8,7 @@ class CfgVehicles { function = QUOTE(DFUNC(initModuleSettings)); functionPriority = 1; isGlobal = 1; + isSingular = 1; isTriggerActivated = 0; author = ECSTRING(common,ACETeam); class Arguments { diff --git a/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf b/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf index baff39516d..393a5cd757 100644 --- a/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf +++ b/addons/winddeflection/functions/fnc_updateTrajectoryPFH.sqf @@ -34,8 +34,7 @@ _bulletSpeed = vectorMagnitude _bulletVelocity; if ((!alive _bullet) || {(_bullet isKindOf "BulletBase") && {_bulletSpeed < 100}}) then { - GVAR(trackedBullets) deleteAt (_forEachIndex - _deleted); - _deleted = _deleted + 1; + GVAR(trackedBullets) deleteAt (GVAR(trackedBullets) find _x); } else { if (_isWind) then { _trueVelocity = _bulletVelocity vectorDiff ACE_wind; @@ -51,7 +50,7 @@ }; _bullet setVelocity _bulletVelocity; }; - - } forEach GVAR(trackedBullets); + nil + } count +GVAR(trackedBullets); // END_COUNTER(pfeh); }, GVAR(simulationInterval), [ACE_time]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/zeus/CfgVehicles.hpp b/addons/zeus/CfgVehicles.hpp index 35c43b0e84..f5144e60e6 100644 --- a/addons/zeus/CfgVehicles.hpp +++ b/addons/zeus/CfgVehicles.hpp @@ -23,6 +23,7 @@ class CfgVehicles { function = QFUNC(moduleZeusSettings); functionPriority = 1; isGlobal = 1; + isSingular = 1; isTriggerActivated = 0; author = "SilentSpike"; class Arguments { diff --git a/addons/zeus/stringtable.xml b/addons/zeus/stringtable.xml index fa969af422..da8e2ac3d2 100644 --- a/addons/zeus/stringtable.xml +++ b/addons/zeus/stringtable.xml @@ -216,21 +216,25 @@ Add Spare Wheel Adicionar roda sobressalente Dodaj koło zapasowe + Добавить запасное колесо Adds a Spare Wheel to the vehicle Adiciona uma roda sobressalente ao veículo Dodaje koło zapasowe do pojazdu + Добавляет запасное колесо в транспорт Add Spare Track Adicionar esteira sobressalente Dodaj zapasową gąsienicę + Дабавить запасную гусеницу Adds a Spare Track to the vehicle Adiciona uma esteira sobressalente ao veículo Dodaje zapasową gąsienicę do pojazdu + Добавляет запасную гусеницу в транспорт Unit must be alive @@ -274,11 +278,13 @@ Unit must be a vehicle with cargo space Unidade deve ser um veículo com espaço em carga Jednostka musi być pojazdem z wolną przestrzenią cargo + Юнит должен быть транспортом с грузовым отсеком Unit must have cargo space left Unidade deve conter espaço sobressalente Jednostka musi mieć wolną przestrzeń cargo + Юнит должен иметь свободное место в грузовом отсеке Unit must not be captive diff --git a/extensions/CMakeLists.txt b/extensions/CMakeLists.txt index 43bd59abaf..299a9f4a5b 100644 --- a/extensions/CMakeLists.txt +++ b/extensions/CMakeLists.txt @@ -20,7 +20,7 @@ option(USE_STATIC_LINKING "USE_STATIC_LINKING" ON) if(CMAKE_COMPILER_IS_GNUCXX) - SET(CMAKE_CXX_FLAGS "-std=c++11 -march=i686 -m32 -O2 -s -fPIC -fpermissive") + SET(CMAKE_CXX_FLAGS "-std=c++11 -pedantic -pedantic-errors -march=i686 -m32 -O2 -s -fPIC -fpermissive") set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") set(CMAKE_SHARED_LINKER_FLAGS "-static-libgcc -static-libstdc++") elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") diff --git a/extensions/advanced_ballistics/AdvancedBallistics.cpp b/extensions/advanced_ballistics/AdvancedBallistics.cpp index c5c0a6c7a3..203243cd9d 100644 --- a/extensions/advanced_ballistics/AdvancedBallistics.cpp +++ b/extensions/advanced_ballistics/AdvancedBallistics.cpp @@ -5,7 +5,6 @@ #include #include -#define M_PI 3.14159265358979323846f #define GRAVITY 9.80665f #define ABSOLUTE_ZERO_IN_CELSIUS -273.15f #define KELVIN(t) (t - ABSOLUTE_ZERO_IN_CELSIUS) diff --git a/extensions/break_line/ace_break_line.cpp b/extensions/break_line/ace_break_line.cpp index 8bb5af9572..7644748378 100644 --- a/extensions/break_line/ace_break_line.cpp +++ b/extensions/break_line/ace_break_line.cpp @@ -21,7 +21,7 @@ extern "C" { EXPORT void __stdcall RVExtension(char *output, int outputSize, const char *function); -}; +} std::vector splitString(const std::string & input) { std::istringstream ss(input); diff --git a/extensions/clipboard/ace_clipboard.cpp b/extensions/clipboard/ace_clipboard.cpp index 61960598ec..cdd5f7c423 100644 --- a/extensions/clipboard/ace_clipboard.cpp +++ b/extensions/clipboard/ace_clipboard.cpp @@ -15,7 +15,7 @@ extern "C" { EXPORT void __stdcall RVExtension(char *output, int outputSize, const char *function); -}; +} std::string gClipboardData; diff --git a/extensions/common/p3d/animation.cpp b/extensions/common/p3d/animation.cpp index f47a40fe5a..07f5922f49 100644 --- a/extensions/common/p3d/animation.cpp +++ b/extensions/common/p3d/animation.cpp @@ -67,5 +67,5 @@ namespace ace { animation::~animation() { } - }; -}; + } +} diff --git a/extensions/common/p3d/animation.hpp b/extensions/common/p3d/animation.hpp index b53bee6a68..430f3aed6d 100644 --- a/extensions/common/p3d/animation.hpp +++ b/extensions/common/p3d/animation.hpp @@ -65,5 +65,5 @@ namespace ace { //ace::vector3 axis_dir; }; typedef std::shared_ptr animation_p; - }; -}; \ No newline at end of file + } +} diff --git a/extensions/common/p3d/model.hpp b/extensions/common/p3d/model.hpp index bd3cafe60c..a26a8cfbb8 100644 --- a/extensions/common/p3d/model.hpp +++ b/extensions/common/p3d/model.hpp @@ -53,5 +53,5 @@ namespace ace { }; typedef std::shared_ptr model_p; - }; -}; \ No newline at end of file + } +} diff --git a/extensions/common/p3d/model_info.hpp b/extensions/common/p3d/model_info.hpp index 195e925a5a..f785574411 100644 --- a/extensions/common/p3d/model_info.hpp +++ b/extensions/common/p3d/model_info.hpp @@ -70,5 +70,5 @@ namespace ace { }; typedef std::shared_ptr model_info_p; - }; -}; \ No newline at end of file + } +} diff --git a/extensions/common/p3d/parser.hpp b/extensions/common/p3d/parser.hpp index b3f584a017..76a2d2f8e1 100644 --- a/extensions/common/p3d/parser.hpp +++ b/extensions/common/p3d/parser.hpp @@ -13,5 +13,5 @@ namespace ace { model_p load(const std::string &); }; - }; -}; \ No newline at end of file + } +} diff --git a/extensions/common/p3d/skeleton.hpp b/extensions/common/p3d/skeleton.hpp index 86fa71c49c..2b66c4fc6c 100644 --- a/extensions/common/p3d/skeleton.hpp +++ b/extensions/common/p3d/skeleton.hpp @@ -32,5 +32,5 @@ namespace ace { std::vector all_bones; }; typedef std::shared_ptr skeleton_p; - }; -}; \ No newline at end of file + } +} diff --git a/extensions/common/transform_matrix.hpp b/extensions/common/transform_matrix.hpp index f9c3056dc9..73dad45019 100644 --- a/extensions/common/transform_matrix.hpp +++ b/extensions/common/transform_matrix.hpp @@ -31,4 +31,4 @@ namespace ace { }; typedef transform_matrix_base transform_matrix; -}; \ No newline at end of file +} diff --git a/extensions/common/vector.hpp b/extensions/common/vector.hpp index 0eb348f312..3f786a964f 100644 --- a/extensions/common/vector.hpp +++ b/extensions/common/vector.hpp @@ -168,4 +168,4 @@ namespace ace { T _x; T _y; }; -}; +} diff --git a/extensions/fcs/ace_fcs.cpp b/extensions/fcs/ace_fcs.cpp index 178711f54c..5bc750235e 100644 --- a/extensions/fcs/ace_fcs.cpp +++ b/extensions/fcs/ace_fcs.cpp @@ -27,7 +27,7 @@ extern "C" { EXPORT void __stdcall RVExtension(char *output, int outputSize, const char *function); -}; +} std::vector splitString(std::string input) { std::istringstream ss(input); diff --git a/extensions/medical/medical.cpp b/extensions/medical/medical.cpp index 78517b99d4..5f999caaa2 100644 --- a/extensions/medical/medical.cpp +++ b/extensions/medical/medical.cpp @@ -14,7 +14,7 @@ extern "C" { EXPORT void __stdcall RVExtension(char *output, int outputSize, const char *function); -}; +} std::vector parseExtensionInput(const std::string& input) { diff --git a/extensions/parse_imagepath/ace_parse_imagepath.cpp b/extensions/parse_imagepath/ace_parse_imagepath.cpp index 051535e473..56d503cbaf 100644 --- a/extensions/parse_imagepath/ace_parse_imagepath.cpp +++ b/extensions/parse_imagepath/ace_parse_imagepath.cpp @@ -18,7 +18,7 @@ extern "C" { __declspec (dllexport) void __stdcall RVExtension(char *output, int outputSize, const char *function); -}; +} std::string getImagePathFromStructuredText(const std::string & input) { std::string returnValue = ""; diff --git a/extras/assets/icons/Icon_Module_png/Icons_Modules_Rearm.png b/extras/assets/icons/Icon_Module_png/Icons_Modules_Rearm.png new file mode 100644 index 0000000000..b564992d5f Binary files /dev/null and b/extras/assets/icons/Icon_Module_png/Icons_Modules_Rearm.png differ diff --git a/extras/assets/icons/Icon_Module_png/Icons_Modules_Refuel.png b/extras/assets/icons/Icon_Module_png/Icons_Modules_Refuel.png new file mode 100644 index 0000000000..da50b92caf Binary files /dev/null and b/extras/assets/icons/Icon_Module_png/Icons_Modules_Refuel.png differ diff --git a/mod.cpp b/mod.cpp index 2e8513a952..096e6d563d 100644 --- a/mod.cpp +++ b/mod.cpp @@ -1,8 +1,8 @@ -name = "Advanced Combat Environment 3.3.2"; +name = "Advanced Combat Environment 3.3.3"; picture = "logo_ace3_ca.paa"; actionName = "GitHub"; action = "https://github.com/acemod/ACE3"; -description = "ACE3 - Version 3.3.2"; +description = "ACE3 - Version 3.3.3"; logo = "logo_ace3_ca.paa"; logoOver = "logo_ace3_ca.paa"; tooltip = "ACE3"; diff --git a/optionals/compat_bwa3/CfgVehicles.hpp b/optionals/compat_bwa3/CfgVehicles.hpp new file mode 100644 index 0000000000..bdcebdab9d --- /dev/null +++ b/optionals/compat_bwa3/CfgVehicles.hpp @@ -0,0 +1,11 @@ +class CfgVehicles { + class Tank_F; + class BWA3_Puma_base: Tank_F { + // Assuming 1 L/km + EGVAR(refuel,fuelCapacity) = 700; + }; + + class BWA3_Leopard_base: Tank_F { + EGVAR(refuel,fuelCapacity) = 1160; + }; +}; diff --git a/optionals/compat_rhs_afrf3/CfgAmmo.hpp b/optionals/compat_rhs_afrf3/CfgAmmo.hpp index 541437458e..41c0f333ce 100644 --- a/optionals/compat_rhs_afrf3/CfgAmmo.hpp +++ b/optionals/compat_rhs_afrf3/CfgAmmo.hpp @@ -122,4 +122,8 @@ class CfgAmmo ACE_muzzleVelocities[]={298, 330, 350}; ACE_barrelLengths[]={96.52, 127.0, 228.6}; }; -}; \ No newline at end of file + class SubmunitionBase; + class rhs_ammo_127x108mm_x5: SubmunitionBase { + ACE_rearm_caliber=13; + }; +}; diff --git a/optionals/compat_rhs_afrf3/CfgVehicles.hpp b/optionals/compat_rhs_afrf3/CfgVehicles.hpp index e9c71f4da7..963913d74d 100644 --- a/optionals/compat_rhs_afrf3/CfgVehicles.hpp +++ b/optionals/compat_rhs_afrf3/CfgVehicles.hpp @@ -28,6 +28,7 @@ class cfgVehicles { class CommanderOptics; }; class rhs_bmd_base: Tank_F { + EGVAR(refuel,fuelCapacity) = 300; class Turrets: Turrets { class CommanderOptics: NewTurret { ace_fcs_Enabled = 0; @@ -41,6 +42,7 @@ class cfgVehicles { }; }; class rhs_bmp1tank_base: Tank_F { + EGVAR(refuel,fuelCapacity) = 460; class Turrets: Turrets { class MainTurret: MainTurret { ace_fcs_Enabled = 0; @@ -57,13 +59,14 @@ class cfgVehicles { class MainTurret: MainTurret { class Turrets: Turrets { class CommanderOptics : CommanderOptics { - ace_fcs_Enabled = 0; + ace_fcs_Enabled = 0; }; }; }; }; }; class rhs_bmp3tank_base: Tank_F { + EGVAR(refuel,fuelCapacity) = 460; class Turrets: Turrets { class MainTurret: MainTurret { ace_fcs_Enabled = 0; @@ -79,6 +82,7 @@ class cfgVehicles { }; }; class rhs_btr_base: Wheeled_APC_F { + EGVAR(refuel,fuelCapacity) = 300; class Turrets: Turrets { class MainTurret: MainTurret { ace_fcs_Enabled = 0; @@ -89,6 +93,7 @@ class cfgVehicles { }; }; class rhs_a3spruttank_base: Tank_F { + EGVAR(refuel,fuelCapacity) = 400; class Turrets: Turrets { class MainTurret: MainTurret { ace_fcs_Enabled = 0; @@ -105,6 +110,7 @@ class cfgVehicles { }; }; class rhs_a3t72tank_base: Tank_F { + EGVAR(refuel,fuelCapacity) = 1200; class Turrets: Turrets { class MainTurret: MainTurret { ace_fcs_Enabled = 0; @@ -133,6 +139,7 @@ class cfgVehicles { }; }; class rhs_tank_base: Tank_F { + EGVAR(refuel,fuelCapacity) = 1200; class Turrets: Turrets { class MainTurret: MainTurret { ace_fcs_Enabled = 0; @@ -153,4 +160,71 @@ class cfgVehicles { { ace_gforcecoef = 0.55; }; -}; \ No newline at end of file + + class O_Plane_CAS_02_F; + class RHS_su25_base : O_Plane_CAS_02_F { + EGVAR(refuel,fuelCapacity) = 3600; + }; + + class Heli_Light_02_base_F; + class RHS_Mi8_base : Heli_Light_02_base_F { + EGVAR(refuel,fuelCapacity) = 3700; + }; + + class Heli_Attack_02_base_F; + class RHS_Ka52_base : Heli_Attack_02_base_F { + EGVAR(refuel,fuelCapacity) = 1870; + }; + + class RHS_Mi24_base : Heli_Attack_02_base_F { + EGVAR(refuel,fuelCapacity) = 1851; + }; + + class rhs_t80b : rhs_tank_base { + EGVAR(refuel,fuelCapacity) = 1100; + }; + + class Truck_F; + class RHS_Ural_BaseTurret : Truck_F { + EGVAR(refuel,fuelCapacity) = 360; + }; + + class rhs_truck : Truck_F { + EGVAR(refuel,fuelCapacity) = 210; + }; + + class MRAP_02_base_F; + class rhs_tigr_base : MRAP_02_base_F { + EGVAR(refuel,fuelCapacity) = 138; + }; + + class Offroad_01_base_f; + class RHS_UAZ_Base : Offroad_01_base_f { + EGVAR(refuel,fuelCapacity) = 78; + }; + + class APC_Tracked_02_base_F; + class rhs_zsutank_base : APC_Tracked_02_base_F { + EGVAR(refuel,fuelCapacity) = 515; + }; + + class rhs_btr60_base : rhs_btr_base { + EGVAR(refuel,fuelCapacity) = 290; + }; + class rhs_btr70_vmf : rhs_btr_base { + EGVAR(refuel,fuelCapacity) = 350; + }; + + class rhs_btr70_msv : rhs_btr70_vmf {}; + class rhs_btr80_msv : rhs_btr70_msv { + EGVAR(refuel,fuelCapacity) = 300; + }; + + class rhs_2s3tank_base : Tank_F { + EGVAR(refuel,fuelCapacity) = 830; + }; + + class OTR21_Base : Truck_F { + EGVAR(refuel,fuelCapacity) = 500; + }; +}; diff --git a/optionals/compat_rhs_afrf3/config.cpp b/optionals/compat_rhs_afrf3/config.cpp index 123f80b566..aa9d6bed95 100644 --- a/optionals/compat_rhs_afrf3/config.cpp +++ b/optionals/compat_rhs_afrf3/config.cpp @@ -6,7 +6,7 @@ class CfgPatches { weapons[] = {}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"rhs_c_weapons", "rhs_c_troops"}; - author[]={"Ruthberg"}; + author[]={"Ruthberg", "GitHawk"}; VERSION_CONFIG; }; }; @@ -14,4 +14,4 @@ class CfgPatches { #include "CfgAmmo.hpp" #include "CfgMagazines.hpp" #include "CfgWeapons.hpp" -#include "CfgVehicles.hpp" \ No newline at end of file +#include "CfgVehicles.hpp" diff --git a/optionals/compat_rhs_usf3/CfgVehicles.hpp b/optionals/compat_rhs_usf3/CfgVehicles.hpp index 2be7a8076e..3c56b91aa9 100644 --- a/optionals/compat_rhs_usf3/CfgVehicles.hpp +++ b/optionals/compat_rhs_usf3/CfgVehicles.hpp @@ -15,6 +15,7 @@ class cfgVehicles { class MBT_01_base_F: Tank_F {}; class rhsusf_m1a1tank_base: MBT_01_base_F { + EGVAR(refuel,fuelCapacity) = 1909; class Turrets: Turrets { class MainTurret: MainTurret { ace_fcs_Enabled = 0; @@ -29,4 +30,67 @@ class cfgVehicles { }; }; }; -}; \ No newline at end of file + + class Heli_light_03_base_F; + class RHS_UH1_Base : Heli_light_03_base_F { + EGVAR(refuel,fuelCapacity) = 1447; + }; + + class Heli_Transport_01_base_F; + class RHS_UH60_Base : Heli_Transport_01_base_F { + EGVAR(refuel,fuelCapacity) = 1360; + }; + + class Heli_Transport_02_base_F; + class RHS_CH_47F_base : Heli_Transport_02_base_F { + EGVAR(refuel,fuelCapacity) = 3914; + }; + + class Heli_Attack_01_base_F; + class RHS_AH1Z_base : Heli_Attack_01_base_F { + EGVAR(refuel,fuelCapacity) = 1600; + }; + + class RHS_AH64_base : Heli_Attack_01_base_F { + EGVAR(refuel,fuelCapacity) = 1420; + }; + + class MBT_01_arty_base_F; + class rhsusf_m109tank_base : MBT_01_arty_base_F { + EGVAR(refuel,fuelCapacity) = 511; + }; + + class MRAP_01_base_F; + class rhsusf_hmmwe_base : MRAP_01_base_F { + EGVAR(refuel,fuelCapacity) = 95; + }; + + class rhsusf_rg33_base : MRAP_01_base_F { + EGVAR(refuel,fuelCapacity) = 302; + }; + + class Truck_01_base_F; + class rhsusf_fmtv_base : Truck_01_base_F { + EGVAR(refuel,fuelCapacity) = 219; + }; + + class APC_Tracked_02_base_F; + class rhsusf_m113_tank_base : APC_Tracked_02_base_F { + EGVAR(refuel,fuelCapacity) = 360; + }; + + class APC_Tracked_03_base_F; + class RHS_M2A2_Base : APC_Tracked_03_base_F { + EGVAR(refuel,fuelCapacity) = 746; + }; + + class Plane_CAS_01_base_F; + class RHS_A10 : Plane_CAS_01_base_F { + EGVAR(refuel,fuelCapacity) = 6223; + }; + + class Plane_Base_F; + class RHS_C130J_Base : Plane_Base_F { + EGVAR(refuel,fuelCapacity) = 25704; + }; +}; diff --git a/optionals/compat_rhs_usf3/config.cpp b/optionals/compat_rhs_usf3/config.cpp index 3e9aee6ec7..59517ed64f 100644 --- a/optionals/compat_rhs_usf3/config.cpp +++ b/optionals/compat_rhs_usf3/config.cpp @@ -6,7 +6,7 @@ class CfgPatches { weapons[] = {}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"rhsusf_c_weapons", "rhsusf_c_troops"}; - author[]={"Ruthberg"}; + author[]={"Ruthberg", "GitHawk"}; VERSION_CONFIG; }; }; @@ -14,4 +14,4 @@ class CfgPatches { #include "CfgAmmo.hpp" #include "CfgMagazines.hpp" #include "CfgWeapons.hpp" -#include "CfgVehicles.hpp" \ No newline at end of file +#include "CfgVehicles.hpp" diff --git a/tools/make.py b/tools/make.py index adaecf269e..e4b99116a6 100644 --- a/tools/make.py +++ b/tools/make.py @@ -489,7 +489,7 @@ def check_for_obsolete_pbos(addonspath, file): def backup_config(module): - #PABST: Convert config (run the macro'd config.cpp through CfgConvert twice to produce a de-macro'd cpp that pboProject can read without fucking up: + #backup original $PBOPREFIX$ global work_drive global prefix @@ -503,52 +503,11 @@ def backup_config(module): except: print_error("Error creating backup of $PBOPREFIX$ for module {}.".format(module)) - try: - shutil.copyfile(os.path.join(work_drive, prefix, module, "config.cpp"), os.path.join(work_drive, prefix, module, "config.backup")) - os.chdir(work_drive) - except: - print_error("Error creating backup of config.cpp for module {}.".format(module)) - return True -def convert_config(module): - try: - global work_drive - global prefix - global arma3tools_path - - cmd = [os.path.join(arma3tools_path, "CfgConvert", "CfgConvert.exe"), "-bin", "-dst", os.path.join(work_drive, prefix, module, "config.bin"), os.path.join(work_drive, prefix, module, "config.cpp")] - ret = subprocess.call(cmd) - if ret != 0: - print_error("CfgConvert -bin return code == {}. Usually means there is a syntax error within the config.cpp file.".format(str(ret))) - os.remove(os.path.join(work_drive, prefix, module, "config.cpp")) - shutil.copyfile(os.path.join(work_drive, prefix, module, "config.backup"), os.path.join(work_drive, prefix, module, "config.cpp")) - - cmd = [os.path.join(arma3tools_path, "CfgConvert", "CfgConvert.exe"), "-txt", "-dst", os.path.join(work_drive, prefix, module, "config.cpp"), os.path.join(work_drive, prefix, module, "config.bin")] - ret = subprocess.call(cmd) - if ret != 0: - print_error("CfgConvert -txt return code == {}. Usually means there is a syntax error within the config.cpp file.".format(str(ret))) - os.remove(os.path.join(work_drive, prefix, module, "config.cpp")) - shutil.copyfile(os.path.join(work_drive, prefix, module, "config.backup"), os.path.join(work_drive, prefix, module, "config.cpp")) - except Exception as e: - print_error("Exception from convert_config=>CfgConvert: {}".format(e)) - return False - - return True - - def addon_restore(modulePath): - #PABST: cleanup config BS (you could comment this out to see the "de-macroed" cpp - #print_green("\Pabst! (restoring): {}".format(os.path.join(modulePath, "config.cpp"))) + #restore original $PBOPREFIX$ try: - if os.path.isfile(os.path.join(modulePath, "config.cpp")): - os.remove(os.path.join(modulePath, "config.cpp")) - if os.path.isfile(os.path.join(modulePath, "config.backup")): - os.rename(os.path.join(modulePath, "config.backup"), os.path.join(modulePath, "config.cpp")) - if os.path.isfile(os.path.join(modulePath, "config.bin")): - os.remove(os.path.join(modulePath, "config.bin")) - if os.path.isfile(os.path.join(modulePath, "texHeaders.bin")): - os.remove(os.path.join(modulePath, "texHeaders.bin")) if os.path.isfile(os.path.join(modulePath, "$PBOPREFIX$.backup")): if os.path.isfile(os.path.join(modulePath, "$PBOPREFIX$")): os.remove(os.path.join(modulePath, "$PBOPREFIX$")) @@ -1216,9 +1175,6 @@ See the make.cfg file for additional build options. nobinFilePath = os.path.join(work_drive, prefix, module, "$NOBIN$") backup_config(module) - if (not os.path.isfile(nobinFilePath)): - convert_config(module) - version_stamp_pboprefix(module,commit_id) if os.path.isfile(nobinFilePath): diff --git a/tools/search_privates.py b/tools/search_privates.py index 207c6403e0..7c6b042c1a 100644 --- a/tools/search_privates.py +++ b/tools/search_privates.py @@ -16,7 +16,7 @@ def get_private_declare(content): priv_dec_str = ''.join(priv_srch_declared) - srch = re.compile('(?