Interaction - Add interaction with terrain objects (#8103)

* Add interaction with terrain objects

* Optimize with new commands

* Handle z-position under ground

* Add warning for setting

* Add parentheses to condition

Co-authored-by: jonpas <jonpas33@gmail.com>

* Add comments

* Add parentheses to condition

Co-authored-by: jonpas <jonpas33@gmail.com>

* Add parentheses to condition

Co-authored-by: mharis001 <34453221+mharis001@users.noreply.github.com>

* Add replacement configs to dragging

This reverts commit afc5abe6cd.

* Fix validator error and optimize condition

Co-authored-by: jonpas <jonpas33@gmail.com>
Co-authored-by: mharis001 <34453221+mharis001@users.noreply.github.com>
Co-authored-by: PabstMirror <pabstmirror@gmail.com>
This commit is contained in:
Dystopian 2021-10-12 22:36:33 +03:00 committed by GitHub
parent 63d7419066
commit 0c58d8b20b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 183 additions and 0 deletions

View File

@ -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};
};

View File

@ -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];
{

View File

@ -51,4 +51,6 @@ PREP(openDoor);
PREP(canPush);
PREP(push);
// misc
PREP(canFlip);
PREP(replaceTerrainObject);

View File

@ -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"];

View File

@ -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;

View File

@ -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];

View File

@ -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;

View File

@ -0,0 +1,37 @@
#include "script_component.hpp"
/*
* Author: Dystopian
* Replaces terrain object with created one.
* Run on server only.
*
* Arguments:
* 0: Terrain object <OBJECT>
* 1: New object class <STRING>
*
* 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;

View File

@ -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;

View File

@ -1242,5 +1242,9 @@
<Key ID="STR_ACE_Interaction_enableRenameGroup_Description">
<English>Allows a group leader to rename their group if the name is not already taken.</English>
</Key>
<Key ID="STR_ACE_Interaction_interactWithTerrainObjects_Description">
<English>Warning: can cause some objects to collide with others.</English>
<Russian>Внимание: может вызвать отталкивание некоторых объектов друг от друга.</Russian>
</Key>
</Package>
</Project>