Функция проверки присутствия юнита в здании.

Описание: Функция получает на вход переменную юнита и возвращает bool значение в зависимости от того, находится ли игрок в здании или же нет.

Автор: DrSova (участник нашего Discord).

Применение: [/*переменная игрока*/] call fnc_isInsideBuilding;


Пример:

Создаем проверку присутствия игрока в доме каждую секунду.
1. Помещаем код функции (находится в самом низу страницы) в init.sqf вашей миссии.
fnc_isInsideBuilding в коде - является переменной, которая хранит в себе функцию и далее будет использоваться для ее вызова. Название можно изменить на любое удобное вам.
2. Следующий код будет проверять присутствие игрока в здании и выводить на экран сообщение: В доме ли игрок или же нет. (Код также можно поместить в init.sqf)

[] spawn {
  while {true} do {
    _isInside = [player] call fnc_isInsideBuilding; //Вызов функции проверки и запись результата в локальную переменную _isInside
    if (str _isInside == "true") then { //Проверка значения переменной
      hintSilent "Игрок в доме"; //При соблюдении данного условия на экран выведется сообщение "Игрок в доме"
    } else {
      hintSilent "Игрок не в доме"; //При остальных условиях на экран выведется сообщение "Игрок не в доме"
    };
    sleep 1; //Задержка выполнения скрипта. Чем меньше задержка - тем хуже производительность
  };
};

Код функции

fnc_isInsideBuilding = {
    private["_unit1","_building","_type","_relPos","_boundingBox","_min","_max","_myX","_myY","_myZ","_inside"];
    _unit1 = _this select 0;
    _inside = false;
    _buildingsCheck = [];
    _buildingsCheck = _unit1 call {
        _end = [];
        _array = lineIntersectsSurfaces [ 
          getPosWorld _this,  
          getPosWorld _this vectorAdd [0, 0, 50],  
          _this, objNull, true, 1, "GEOM", "NONE" 
         ];
        {
            _house = _x select 3;
            if (_house isKindOf "HouseBase") then {
                _end pushback _house;
            };
        } forEach _array;
        _end
    };
    
    {
        _relPos = _x WorldToModel (getposATL _unit1);
        _boundingBox = boundingBoxReal _x;
        _min = [];
        _max = [];
        _min = (_boundingBox select 0);
        _max = (_boundingBox select 1);
                     
        _myX = _relPos select 0;
        _myY = _relPos select 1;
        _myZ = _relPos select 2;
                    
        if ((_myX > (_min select 0)) and (_myX < (_max select 0))) then {
                if ((_myY > (_min select 1)) and (_myY < (_max select 1))) then {
                        if ((_myZ > (_min select 2)) and (_myZ < (_max select 2))) then {
                                _inside = true;
                        } else { _inside = false; };
                } else { _inside = false; };
        } else { _inside = false; };
    } forEach _buildingsCheck;
    _inside
};

Обсудить это можно в нашем Discord канале