diff --git a/addons/dragging/CfgVehicles.hpp b/addons/dragging/CfgVehicles.hpp index 055013f7279..076c5fb640c 100644 --- a/addons/dragging/CfgVehicles.hpp +++ b/addons/dragging/CfgVehicles.hpp @@ -186,6 +186,7 @@ class CfgVehicles { // Misc crates class Constructions_base_F; class Land_WoodenBox_F: Constructions_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canCarry) = 1; GVAR(canDrag) = 1; @@ -249,22 +250,27 @@ class CfgVehicles { // some terrain objects class Land_CampingTable_F: ThingX { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canCarry) = 1; GVAR(carryPosition)[] = {0,1,0.5}; }; class Land_CampingTable_small_F: ThingX { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canCarry) = 1; GVAR(carryPosition)[] = {0,1,0.5}; }; class Land_GarbageContainer_closed_F: ThingX { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canDrag) = 1; GVAR(dragDirection) = 180; }; class Land_GarbageContainer_open_F: ThingX { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canDrag) = 1; GVAR(dragDirection) = 180; }; class Land_Sun_chair_F: ThingX { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canCarry) = 1; GVAR(carryDirection) = 90; @@ -273,56 +279,69 @@ class CfgVehicles { GVAR(dragDirection) = 90; }; class Land_TablePlastic_01_F: ThingX { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canCarry) = 1; GVAR(carryPosition)[] = {0,1,0}; GVAR(canDrag) = 1; }; class Land_Tyre_F: ThingX { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canCarry) = 1; GVAR(carryPosition)[] = {0,0.6,1}; }; class Land_WoodenTable_large_F: ThingX { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canDrag) = 1; GVAR(dragDirection) = 90; }; class Land_BarrelSand_F: Items_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canDrag) = 1; GVAR(dragPosition)[] = {0,1,0}; }; class Land_BarrelWater_F: Items_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canDrag) = 1; GVAR(dragPosition)[] = {0,1,0}; }; class Land_Bucket_F: Items_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canCarry) = 1; GVAR(carryPosition)[] = {0,0.6,1}; }; class Land_CanisterPlastic_F: Items_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canCarry) = 1; GVAR(carryPosition)[] = {0,0.6,0}; }; class Land_GarbageBarrel_01_english_F: Items_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canDrag) = 1; }; class Land_MetalBarrel_F: Items_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canDrag) = 1; GVAR(dragPosition)[] = {0,1,0}; }; class Land_Pallet_F: Constructions_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canCarry) = 1; GVAR(canDrag) = 1; }; class Land_Pallet_vertical_F: Constructions_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canCarry) = 1; GVAR(carryPosition)[] = {0,0.6,0.6}; GVAR(carryDirection) = 180; }; class Land_WheelCart_F: Constructions_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canDrag) = 1; }; class Land_WorkStand_F: Constructions_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canCarry) = 1; GVAR(carryPosition)[] = {0,1,0}; @@ -331,10 +350,12 @@ class CfgVehicles { }; class Market_base_F; class Land_Basket_F: Market_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canCarry) = 1; GVAR(carryPosition)[] = {0,0.6,0.5}; }; class Land_WoodenCart_F: Market_base_F { + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canDrag) = 1; }; @@ -343,23 +364,27 @@ class CfgVehicles { class NonStrategic; class Land_Pallets_F: NonStrategic { XEH_INHERITED; + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canDrag) = 1; }; class Camping_base_F; class Land_CampingChair_V1_folded_F: Camping_base_F { XEH_INHERITED; + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canCarry) = 1; GVAR(carryPosition)[] = {0,0.6,1}; }; class Stall_base_F; class Land_CratesPlastic_F: Stall_base_F { XEH_INHERITED; + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canCarry) = 1; GVAR(carryPosition)[] = {0,0.6,1}; }; class House_Small_F; class Land_MetalBarrel_empty_F: House_Small_F { XEH_INHERITED; + EGVAR(interaction,replaceTerrainObject) = 1; GVAR(canDrag) = 1; GVAR(dragPosition)[] = {0,1,0}; }; diff --git a/addons/interact_menu/functions/fnc_renderActionPoints.sqf b/addons/interact_menu/functions/fnc_renderActionPoints.sqf index fcc467ca3cc..987ad3f99ce 100644 --- a/addons/interact_menu/functions/fnc_renderActionPoints.sqf +++ b/addons/interact_menu/functions/fnc_renderActionPoints.sqf @@ -29,6 +29,8 @@ private _fnc_renderNearbyActions = { GVAR(foundActions) = []; GVAR(lastTimeSearchedActions) = diag_tickTime; + QGVAR(renderNearbyActions) call CBA_fnc_localEvent; + private _numInteractObjects = 0; private _nearestObjects = nearestObjects [ACE_player, ["All"], 13]; { diff --git a/addons/interaction/XEH_PREP.hpp b/addons/interaction/XEH_PREP.hpp index 2d32f3115e0..8f68aa79cf8 100644 --- a/addons/interaction/XEH_PREP.hpp +++ b/addons/interaction/XEH_PREP.hpp @@ -51,4 +51,6 @@ PREP(openDoor); PREP(canPush); PREP(push); +// misc PREP(canFlip); +PREP(replaceTerrainObject); diff --git a/addons/interaction/XEH_postInit.sqf b/addons/interaction/XEH_postInit.sqf index 387f06874e7..1639d79bbf7 100644 --- a/addons/interaction/XEH_postInit.sqf +++ b/addons/interaction/XEH_postInit.sqf @@ -77,10 +77,30 @@ ACE_Modifier = 0; }; }] call CBA_fnc_addEventHandler; +if (isServer) then { + [QGVAR(replaceTerrainObject), FUNC(replaceTerrainObject)] call CBA_fnc_addEventHandler; +}; + if (!hasInterface) exitWith {}; GVAR(isOpeningDoor) = false; +[QEGVAR(interact_menu,renderNearbyActions), { + if (!GVAR(interactWithTerrainObjects)) exitWith {}; + { + if ( + isObjectHidden _x // after hiding on server + || {_x getVariable [QGVAR(terrainObjectReplaced), false]} // after checking but before hiding + || {typeOf _x isNotEqualTo ""} + ) then {continue}; + private _model = getModelInfo _x select 1; + private _class = GVAR(replaceTerrainModels) get _model; + if (isNil "_class") then {continue}; + _x setVariable [QGVAR(terrainObjectReplaced), true]; + [QGVAR(replaceTerrainObject), [_x, _class]] call CBA_fnc_serverEvent; + } forEach nearestTerrainObjects [ACE_player, [], 5, false]; +}] call CBA_fnc_addEventHandler; + [QGVAR(tapShoulder), { params ["_unit", "_shoulderNum"]; diff --git a/addons/interaction/XEH_preInit.sqf b/addons/interaction/XEH_preInit.sqf index 855d651d556..4dd0bb13e63 100644 --- a/addons/interaction/XEH_preInit.sqf +++ b/addons/interaction/XEH_preInit.sqf @@ -15,4 +15,8 @@ DFUNC(repair_Statement) = { // moved from config because of build problems } forEach (curatorSelected select 0) }; +if (hasInterface) then { + GVAR(replaceTerrainModels) = createHashMapFromArray call (uiNamespace getVariable QGVAR(cacheReplaceTerrainModels)); +}; + ADDON = true; diff --git a/addons/interaction/XEH_preStart.sqf b/addons/interaction/XEH_preStart.sqf index 022888575ed..799e9e5986e 100644 --- a/addons/interaction/XEH_preStart.sqf +++ b/addons/interaction/XEH_preStart.sqf @@ -1,3 +1,25 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +if (!hasInterface) exitWith {}; + +private _replaceTerrainClasses = QUOTE( + getNumber (_x >> QQGVAR(replaceTerrainObject)) > 0 + && {getNumber (_x >> 'scope') == 2} +) configClasses (configFile >> "CfgVehicles"); + +private _cacheReplaceTerrainModels = createHashMap; +{ + private _model = toLower getText (_x >> "model"); + if (_model select [0, 1] == "\") then { + _model = _model select [1]; + }; + if ((_model select [count _model - 4]) != ".p3d") then { + _model = _model + ".p3d" + }; + if (_model in _cacheReplaceTerrainModels) then {continue}; + _cacheReplaceTerrainModels set [_model, configName _x]; +} forEach _replaceTerrainClasses; + +uiNamespace setVariable [QGVAR(cacheReplaceTerrainModels), compileFinal str _cacheReplaceTerrainModels]; diff --git a/addons/interaction/dev/initReplaceTerrainCursorObject.sqf b/addons/interaction/dev/initReplaceTerrainCursorObject.sqf new file mode 100644 index 00000000000..c0221b2d38e --- /dev/null +++ b/addons/interaction/dev/initReplaceTerrainCursorObject.sqf @@ -0,0 +1,59 @@ +// execVM "z\ace\addons\interaction\dev\initReplaceTerrainCursorObject.sqf"; +// use "J" key to replace terrain cursorObject and add dragging actions to it + +#include "\z\ace\addons\interaction\script_component.hpp" + +DFUNC(replaceTerrainModelsAdd) = { + params ["_model", ["_class", ""]]; + if (_model isEqualType objNull) then { + _model = getModelInfo _model select 1; + }; + if (_model isEqualTo "") exitWith {systemChat "fail model"; false}; + + private _savedClass = GVAR(replaceTerrainModels) get _model; + if (!isNil "_savedClass") exitWith {systemChat ("was " + _savedClass); true}; + + private _parent = ""; + if (_class isEqualTo "") then { + private _configClasses = QUOTE(getNumber (_x >> 'scope') == 2 && {!(configName _x isKindOf 'AllVehicles')}) configClasses (configFile >> "CfgVehicles"); + { + private _xmodel = toLower getText (_x >> "model"); + if (_xmodel select [0, 1] == "\") then { + _xmodel = _xmodel select [1]; + }; + if ((_xmodel select [count _xmodel - 4]) != ".p3d") then { + _xmodel = _xmodel + ".p3d" + }; + if (_model == _xmodel) then { + _class = configName _x; + _parent = configName inheritsFrom _x; + break; + }; + } forEach _configClasses; + }; + if (_class isEqualTo "") exitWith {systemChat "fail class"; false}; + GVAR(replaceTerrainModels) set [_model, _class]; + QEGVAR(interact_menu,renderNearbyActions) call CBA_fnc_localEvent; + systemChat ("found " + _class); + diag_log format ["replaceTerrain: class %1: %2", _class, _parent]; + true +}; + +// DIK_J +[0x24, [false, false, false], { + if ( + cursorObject call FUNC(replaceTerrainModelsAdd) + && {["ace_dragging"] call EFUNC(common,isModLoaded)} + ) then { + // wait while server replaces object, then init dragging on all clients + [{ + if (typeOf cursorObject == "") exitwith {}; + [cursorObject, { + if !hasInterface exitWith {}; + [_this, true] call EFUNC(dragging,setDraggable); + [_this, true] call EFUNC(dragging,setCarryable); + }] remoteExec ["call", 0]; + }, [], 1] call CBA_fnc_waitAndExecute; + }; + true +}, nil, nil, false] call CBA_fnc_addKeyHandler; diff --git a/addons/interaction/functions/fnc_replaceTerrainObject.sqf b/addons/interaction/functions/fnc_replaceTerrainObject.sqf new file mode 100644 index 00000000000..7a164e42125 --- /dev/null +++ b/addons/interaction/functions/fnc_replaceTerrainObject.sqf @@ -0,0 +1,37 @@ +#include "script_component.hpp" +/* + * Author: Dystopian + * Replaces terrain object with created one. + * Run on server only. + * + * Arguments: + * 0: Terrain object + * 1: New object class + * + * Return Value: + * None + * + * Example: + * [cursorObject, "Land_Bucket_F"] call ace_interaction_fnc_replaceTerrainObject + * + * Public: No + */ + +params ["_terrainObject", "_class"]; +TRACE_2("",_terrainObject,_class); + +if (isObjectHidden _terrainObject) exitWith {}; + +private _position = getPosATL _terrainObject; +if (_position select 2 < 0) then { + _position set [2, 0]; +}; +private _vectorDirAndUp = [vectorDir _terrainObject, vectorUp _terrainObject]; + +hideObjectGlobal _terrainObject; +// prevent new object clipping with old one +_terrainObject setDamage [1, false]; + +private _newObject = createVehicle [_class, [0,0,0]]; +_newObject setVectorDirAndUp _vectorDirAndUp; +_newObject setPosATL _position; diff --git a/addons/interaction/initSettings.sqf b/addons/interaction/initSettings.sqf index 684207d2527..b502ed36b00 100644 --- a/addons/interaction/initSettings.sqf +++ b/addons/interaction/initSettings.sqf @@ -37,3 +37,11 @@ true, true ] call CBA_fnc_addSetting; + +[ + QGVAR(interactWithTerrainObjects), "CHECKBOX", + ["str_a3_modules_moduleomquest_defend_f_attributes_useterrainobject0", LSTRING(interactWithTerrainObjects_Description)], + format ["ACE %1", LLSTRING(DisplayName)], + false, + true +] call CBA_fnc_addSetting; diff --git a/addons/interaction/stringtable.xml b/addons/interaction/stringtable.xml index 24fd5a694d7..6fbfb1cbb23 100644 --- a/addons/interaction/stringtable.xml +++ b/addons/interaction/stringtable.xml @@ -1242,5 +1242,9 @@ Allows a group leader to rename their group if the name is not already taken. + + Warning: can cause some objects to collide with others. + Внимание: может вызвать отталкивание некоторых объектов друг от друга. +