Jump to content

Добро пожаловать на проект
Weekly Open Games

Weekly Open Games — это проект для людей, которым интересен хардкорный тип игры. Мы стараемся максимально эффективно использовать структуру, слабые и сильные стороны, а также технику и вооружение различных сторон конфликта, но не ставим перед собой цель провести 100% сбалансированного боестолкновения. Командная игра, командное взаимодействие — фундамент нашего проекта.
О проекте WOG Как начать играть Правила серверов
Sign in to follow this  
Vincen

Скрипт доступа к управлению техникой только для экипажа

Recommended Posts

ТЕХНИКУ ЭКИПАЖУ!

Описание:

Скрипт предназначен для ограничения доступа лиц, не причисленных к экипажу, от управления специализированной техникой. Принцип работы очень прост - вешаем Event Handler (Обработчик событий) на нужную технику/класс техники и каждый раз, когда в указанную вами технику кто то будет садиться, класс-нейм этого человека будет сравниваться с указанным в массиве.

Список использованных команд и выражений:

Рассмотрим пример:

В данном примере рассмотрим принцип реализации скрипта и для наземной техники и для воздушных судов (вертолетов).

В init.sqf вставляем следующий код:

Скрытый текст

  _arrayOfVeh = [worldSize/2,worldSize/2] nearEntities ["Tank", worldSize/sqrt 2];
  _arrayOfHeli = [worldSize/2,worldSize/2] nearEntities ["Helicopter", worldSize/sqrt 2];
  typesOfVehCrew = ["wog_ksor_sergeant", "wog_ksor_officer_armored", "wog_ksor_driver_armored", "wog_ksor_crew_commander", "wog_ksor_crew_gunner", "wog_ksor_crew_driver", "wog_army_ucp_crew_commander", "wog_army_ucp_crew_gunner", "wog_army_ucp_crew_driver", "wog_army_ucp_squadleader", "wog_army_ucp_officer", "wog_army_ucp_Plsg"];
  typesOfVehHeli = ["wog_ru_Helipilot"];
  EjectSeat = {if !(typeOf (_this select 1) in typesOfVehCrew) then {moveOut (_this select 1)};};

  {
    _x addEventHandler ["GetIn", {
      if (((_this select 1) == "driver") && !((typeOf (_this select 2)) in typesOfVehCrew)) then {
        moveOut (_this select 2);
      };
    }];
  } forEach _arrayOfVeh;

  {
    _x addEventHandler ["GetIn", {
      if ((((_this select 1) == "driver") || ((_this select 1) == "gunner")) && !((typeOf (_this select 2)) in typesOfVehHeli)) then {
        moveOut (_this select 2);
      };
    }];
  } forEach _arrayOfHeli;

  {
    _x addEventHandler ["GetIn", {
      if ((((_this select 1) + str(_this select 3)) == "gunner[0]") && !((typeOf (_this select 2)) in typesOfVehCrew)) then {
        moveOut (_this select 2);
      }
    }];
  } forEach _arrayOfVeh;

  {
    _x addEventHandler ["SeatSwitched", {
      _assignedVehicleRoleArray = assignedVehicleRole (_this select 1);
      switch (_assignedVehicleRoleArray select 0) do {
        case "driver":    { //driver
          call EjectSeat;
        };
        case "Turret":     { 
          switch (str (_assignedVehicleRoleArray select 1)) do {
            case "[0]":    { //gunner
              call EjectSeat;
            };
            default {};
          };
        };
        default {}; //cargo
      };
    }];
  } forEach _arrayOfVeh;

 

Разберем его по частям для того, чтобы понять, что за что отвечает:

  _arrayOfVeh = [worldSize/2,worldSize/2] nearEntities ["Tank", worldSize/sqrt 2];
  _arrayOfHeli = [worldSize/2,worldSize/2] nearEntities ["Helicopter", worldSize/sqrt 2];
  typesOfVehCrew = ["wog_ksor_sergeant", "wog_ksor_officer_armored", "wog_ksor_driver_armored", "wog_ksor_crew_commander", "wog_ksor_crew_gunner", "wog_ksor_crew_driver", "wog_army_ucp_crew_commander", "wog_army_ucp_crew_gunner", "wog_army_ucp_crew_driver", "wog_army_ucp_squadleader", "wog_army_ucp_officer", "wog_army_ucp_Plsg"];
  typesOfVehHeli = ["wog_ru_Helipilot"];
  EjectSeat = {if !(typeOf (_this select 1) in typesOfVehCrew) then {moveOut (_this select 1)};};

1. Зададим 4 массива:

а) _arrayOfVeh && _arrayOfHeli - с помощью nearEntities из центра карты будем искать всю технику с родительскими классами "Tank" (это танки, БМПшки и пр.) и "Helicopter" (соответственно вертолеты).

Центр карты задаем в виде:

[worldSize/2,worldSize/2]

где worldSize - это функция (или скорее переменная), которая возвращает длину/ширину карты. Ну и соответственно делим длину и ширину на 2, таким образом получая координаты x и y для центра; последний worldSize/2, который идет в массиве после классов "Tank" и "Helicopter", есть радиус описанной окружности вокруг квадрата:

radius_outscribed_square.png

б) Все, с наполнением массивов техникой мы покончили. Теперь зададим вручную два новых массива typesOfVehCrew и typesOfVehHeli. Если честно, сейчас я и не припомню, почему они не приватные. Видимо на момент написания возникали проблемы с их чтением в EH (Event Handler - будет объяснено ниже).

В первый массив мы записываем класс-неймы (не путать с названием бойца) бойцов, которые могут управлять боевой наземной техникой с классом "Tank". В данном примере, это офицеры (КО) и непосредственно экипаж.

Во второй массив вносим пилотов. 

2. Зададим функцию EjectSeat, которая понадобится нам позже.

Для тех, кто не совсем понимает, в чем разница между функцией и переменной, попытаюсь на пальцах объяснить разницу не претендуя на преподавательское искусство, ибо сам в некоторых моментах не силен -_- (в конце концов, можете сами почитать =)):

Переменная, это такая коробочка на которой написано название. Она хранит в себе какой-то объект (число, массив, символ).

Функция - фрагмент программного кода (подпрограмма), к которому можно обратиться из другого места программы.

a = 1; - переменная

_b = worldSize; - приватная переменная

c = [0,1,2,3]; - переменная

doCount = {
	count с;
}; - функция. В ней содержит код, который посчитает кол-во элементов в массиве c

 


Вторая часть:

Скрытый текст

  {
    _x addEventHandler ["GetIn", {
      if (((_this select 1) == "driver") && !((typeOf (_this select 2)) in typesOfVehCrew)) then {
        moveOut (_this select 2);
      };
    }];
  } forEach _arrayOfVeh;

  {
    _x addEventHandler ["GetIn", {
      if ((((_this select 1) == "driver") || ((_this select 1) == "gunner")) && !((typeOf (_this select 2)) in typesOfVehHeli)) then {
        moveOut (_this select 2);
      };
    }];
  } forEach _arrayOfHeli;

  {
    _x addEventHandler ["GetIn", {
      if ((((_this select 1) + str(_this select 3)) == "gunner[0]") && !((typeOf (_this select 2)) in typesOfVehCrew)) then {
        moveOut (_this select 2);
      }
    }];
  } forEach _arrayOfVeh;

 

Здесь мы создаем 3 Event Handler'a

Если мы обратимся к английскому словарю и дословно переведем Event - событие и Handler - обработчик, то получим Обработчик событий. Принцип его действия в арме довольно таки прост. Товарищи из BIS заранее подготовили для нас список действий, на которые можно повесить Event Hadler, дабы выполнять по завершению указанного действия свой код.

Вам нужно зарядить снаряд в РПГ после выстрела? Воспользуйтесь EH на действие Fired.

Хотите дать под пятую точку тому, кто не должен сидеть на месте стрелка танка? EH на GetIn в вашем распоряжении!

Обращаю ваше внимание на то, что разные EH отрабатывают на разных объектах. Так например EH на действии "GetIn" должен висеть только на технике (таково его изначальное устройство и функционал). А вот если вы будете использовать "GetInMan" , то EH отрабатывать на человеке, а не на технике.

Запутались? Это легко!

EH "GetIn" в нашем примере работает на массив из техники -> _arrayOfHeli и _arrayOfVeh. Когда любой боец будет залезать в данную технику, EH будет передавать определенный массив данных. Для нас это будет выглядеть так: [класс техники, в которую залез боец, место которое он занял в машине (стрелок, водитель, пассажир), имя бойца, позиция на турели (у каждой техники это разный массив)].

EH "GetInMan" будет работать только на указанного/-ых вами игроков. Вам нужно сделать так, чтобы VIP не мог залезть в технику и уехать? Самое время повесить на него EH!

Теперь, самое важное. Как я уже написал выше, когда вы создаете в своей миссии какой-либо EH, то после того, как будет совершено действие, на которое EH повешен, этот самый EH передаст игроку массив данных, которым вы сможете оперировать в своих целях. 

Разберемся на самом первом EH из примера:

  {
    _x addEventHandler ["GetIn", {
      if (((_this select 1) == "driver") && !((typeOf (_this select 2)) in typesOfVehCrew)) then {
        moveOut (_this select 2);
      };
    }];
  } forEach _arrayOfVeh;

Синтаксис для создания EH: 

объект addEventHandler [Тип, {команда/код на выполнения после действия определенного типа}]

_x это зарезервированная переменная для многих команд, в том числе и для команды forEach

Таким образом, команда forEach будет перебирать каждый/-е объект/-ы из массива, который будет указан после него. Для того, чтобы нам не подставлять каждый раз класс-нейм техники, мы просто берем каждый класс-нейм автоматически с помощью forEach и подставляем его на место _x. Список таких переменных как _x и соответствующие им команды вы можете глянуть в блоге KK.

Итак, создаем (addEventHandler) EH на действие "GetIn" (Войти в технику) и прикрепляем этот EH на все элементы массива _arrayOfVeh, каждый из которых подставится сам вместо _x.

Дело за малым. Теперь, когда кто то залез в технику, мы должны понять, есть ли у него разрешение на то, чтобы сесть в эту технику и, если нет, то выгоняем.

Еще раз напоминаю вам вид массива, который мы получим конкретно на EH "GetIn":

[класс техники в которую залез боец, место которое он занял в машине (стрелок, водитель, пассажир), имя бойца, позиция на турели  каждой техники это разный массив)]

или на англ.

[vehicle (object), position, unit, turret]

Записываем простенькое условие:

if (((_this select 1) == "driver") && !((typeOf (_this select 2)) in typesOfVehCrew)) then {
        moveOut (_this select 2);
      };

Если (игрок залез на водителя && игрок не находится в списке typesOfVehCrew) тогда { выкинуть этого игрока из машины};

где && - это символьная альтернатива союзу И; символ "!" является отрицанием, т.е. заменяет собою отрицание "не", _this select цифра - считываем нужный элемент массива. Нумерация элементов во всех массивах начинается с 0. В нашем массиве 4 элемента - [0,1,2,3].

Ну и далее по аналогии делаем тоже самое для вертолетов и для отслеживания на наземной технике момента, чтобы игрок не мог сесть еще и на стрелка.


Заключительная часть:

Нам осталось разобрать последнюю часть кода, которая отвечает за создание EH на действие "SeatSwitched" (пересесть):

  {
    _x addEventHandler ["SeatSwitched", {
      _assignedVehicleRoleArray = assignedVehicleRole (_this select 1);
      switch (_assignedVehicleRoleArray select 0) do {
        case "driver":    { //driver
          call EjectSeat;
        };
        case "Turret":     { 
          switch (str (_assignedVehicleRoleArray select 1)) do {
            case "[0]":    { //gunner
              call EjectSeat;
            };
            default {};
          };
        };
        default {}; //cargo
      };
    }];
  } forEach _arrayOfVeh;

Создание EH происходит по стандарту.

Массив, который выводит EH:

[техника на которую закреплен EH, место на которое пересел игрок, некорректно отрабатывающийся параметр]

или на англ.

[vehicle, unit1, unit2];

[0, 1, 2];

Создадим приватную переменную, в которую по действию "пересесть" будет записываться массив с названием места и номером туррели, на которое пересел игрок (т.к. в вертолете невозможно пересесть со стрелка на пилота и обратно, то данный EH подключаем только на наземную технику).

Затем, используем switch. Эта команда будет искать в "case'-ах совпадения и если таковые будут найдены, то будет выполнен код. В нашем случае это работает так:

//Переносы строк в представленном описании сделаны для вашего удобства при чтении

switch (условие: выбрать 0й элемент массива _assignedVehicleRoleArray, 
        в котором указано название места, на которое пересел игрок) делай {

  если условие совпадает с "driver" то тогда вызвать функцию EjectSeat, 
  которая проверит, указан ли класс-нейм бойца, 
  за которого играет игрок в качестве экипажа или нет и если нет, 
  то выкинет его из техники
	};

Тот же самый ход был проделан и со стрелком, но там брали 1й элемент массива, т.к. с 0м при пересадке на стрелка были какие-то проблемы. 

На этом все. Хотелось охватить и представить как можно больше информации и донести ее доступно, дабы ею могли действительно воспользоваться. Надеюсь, получилось достаточно информативно и в то же время не сильно скомкано.

Особую благодарность хотелось бы вынести г-у @StDIABLO, который помог во всем этом деле разобраться.

 

P.S. Не уверен в корректной работе некоторых EH, в частности "SeatSwitched", ибо их работоспособность зависит от BIS'ов. Для более прошареных игроков - используйте альтернативные функции CBA

Edited by Vincen

Share this post


Link to post
Share on other sites
3 часа назад, Vincen сказал:

Тот же самый ход был проделан и со стрелком, но там брали 1й элемент массива, т.к. с 0м при пересадке на стрелка были какие-то проблемы. 

сейчас объясню

assignedVehicleRole может возвратить только это

  1. [] - Если не в технике (один из вариантов чека человека в технике)
  2. ["Driver"] - Сидит как водитель (слот водителя у нас в технике всегда один)
  3. ["Cargo"] (or ["Cargo", [turret path]] since Arma 3 1.31.127272) - Пассажир внутри (бтр к примеру) ИЛИ снаружи (на броне/в кузове) и если он может стрелять то можно получить его место (см turret path)
  4. ["Turret", [turret path]] - Внутренние слоты (стрелок/командир/негр заряжающий и т.д. все у кого есть возможность  крутить пушками техники) 

т.к. водитель всегда один достаточно чекать 0 элемент массива (да он и единственный будет)

но  если мы будем считывать turret мы всего лишь будем знать что он сидит на одной из турелей, а на какой - нам скажет первый элемент массива 0 - на стрелке 1 на командоре (к примеру, эти цифры всегда надо проверять т.к неизвестно как пожелала левая пятка аддонмейкера)

вот и все

ps

Скрытый текст

 

описаная окружность


_arrayOfVeh = [worldSize/2,worldSize/2] nearEntities ["Tank", worldSize/sqrt 2]; 

_arrayOfHeli = [worldSize/2,worldSize/2] nearEntities ["Helicopter", worldSize/sqrt 2];

вписаная окружность

 


_arrayOfVeh = [worldSize/2,worldSize/2] nearEntities ["Tank", worldSize/2];

_arrayOfHeli = [worldSize/2,worldSize/2] nearEntities ["Helicopter", worldSize/2];

 

 

 

 

 

Edited by StDIABLO

Share this post


Link to post
Share on other sites

@StDIABLO

Пробовал использовать данный скрипт, инит у меня выглядит следующим образом:

[] execVM "briefing.sqf";
[] call WMT_fnc_BriefingMap;
wog3_no_auto_long_range_radio = true;
//бегущая строка после фризтайма
waitUntil{!(isNil "BIS_fnc_init")};
waitUntil {sleep 5; WMT_pub_frzState >= 3};
["WOG3", "Team Yanki", str(date select 2) + "." + str(date select 1) + "." + str(date select 0), "Автор: [OSA]DenusKO"] call BIS_fnc_infoText;
 _arrayOfTank = ["WOG_LAV25_d"];
 typesOfVehCrewTank = ["wog_army_ucp_crew_commander", "wog_army_ucp_crew_gunner", "wog_army_ucp_crew_driver"];
 EjectSeatTank = {if !(typeOf (_this select 1) in typesOfVehCrewTank) then {moveOut (_this select 1)};};

 

{
    _x addEventHandler ["GetIn", {
      if (((_this select 1) == "driver") && !((typeOf (_this select 2)) in typesOfVehCrewTank)) then {
        moveOut (_this select 2);
      };
    }];
} forEach _arrayOfTank;

 

{
    _x addEventHandler ["SeatSwitched", {
      _assignedVehicleRoleArray = assignedVehicleRole (_this select 1);
      switch (_assignedVehicleRoleArray select 0) do {
        case "driver":    { //driver
          call EjectSeatTank;
        };
        case "Turret":     {
          switch (str (_assignedVehicleRoleArray select 1)) do {
            case "[0]":    { //gunner
              call EjectSeatTank;
            };
            default {};
          };
        };
        default {}; //cargo
      };
    }];
} forEach _arrayOfTank;

http://pastebin.com/xfvHP8Tn

В свою очередь арма ругается и выдает ошибку в строке 13 скриншот:

https://drive.google.com/file/d/0B5QRpfufpKOkZ3FVRU5DQVdSZkU/view

Может кто помочь или сказать что не так?

Share this post


Link to post
Share on other sites

Я вижу только одну ошибку :acute_mini:

Скрытый текст

["WOG3", "Team Yanki", str(date select 2) + "." + str(date select 1) + "." + str(date select 0), "Автор: [OSA]DenusKO"] call BIS_fnc_infoText;

 

Share this post


Link to post
Share on other sites
4 часа назад, DenusKO сказал:

Может кто помочь или сказать что не так?

 

0. или дай лог rpt или запусти игру с английским языком, т.к. на скрине непонятно в чем ошибка :)

(на русcком пишет только в rpt)

1. _arrayOfTank = ["WOG_LAV25_d"]; если это класс - тогда неправильно

в твоем коде 

_arrayOfTank = ["WOG_LAV25_d"]; WOG_LAV25_d - так называется одна единица техники (причем надо кавычки убрать) на которую и будет распространяться скрипт

хочешь на 2- обзываешь 2 единицы и вписываешь в массив например:

_arrayOfTank = [WOG_LAV25_d,a1,a2,a3]; //БЕЗ КАВЫЧЕК

в оригинальном коде - технически это МАССИВ объектов,а не классов

Edited by StDIABLO

Share this post


Link to post
Share on other sites

@StDIABLO, в таком случае прописал инит следующий: http://pastebin.com/usQzvFni где а1, а2, а3 имена переменных LAV-25A1. В итоге получилось следующее:

  1. При первой попытке сесть за водителя ботом, класснейм которого не прописан в ините за водителя пускает, при дальнейших попытках на водителя сесть не удается (выкидывает с лавки)
  2. На стрелка всегда можно сесть и управлять орудием и башней
  3. Нельзя внутри лавки пересаживаться со стрелка но водителя и наоборот (выкидывает с транспорта)
  4. На фризтайме можно садиться куда угодно.

 

Share this post


Link to post
Share on other sites

1. Пробовал в мультиплеере?

2. Про****ан кусок кода который отвечает за посадку за стрелка (в оригинальном коде он есть)

 {
    _x addEventHandler ["GetIn", {
      if ((((_this select 1) + str(_this select 3)) == "gunner[0]") && !((typeOf (_this select 2)) in typesOfVehCrew)) then {
        moveOut (_this select 2);
      }
    }];
  } forEach _arrayOfVeh;

3. выкидывает всех кто не находится в списке разрешенных. это нормально

4. Пробовал в мультиплеере?

Share this post


Link to post
Share on other sites

4. Я думаю в этом причина:

waitUntil {sleep 5; WMT_pub_frzState >= 3};

Код с EH выполнится только после окончания фризтайма, соответственно waitUntil нужно перенести в конец кода.

Share this post


Link to post
Share on other sites

А нельзя ли извратиться и вместо moveOut как-то прикрутить lockDriver/lockTurret, чтобы десант аутистов не выкидывало из техники в движении?

Share this post


Link to post
Share on other sites

Точнее, SeatSwitched не отдает место откуда человек пересел ( EH returns both units switching seats) units, а не позиции с которых он пересел). Можно бы было его назад засовывать при попытке). Конечно можно чекать первое свободное место в cargo  и аутиста сажать туда, но это ж надо чекать...... а человек сам пересел.... не почитал что стоит скрипт- в могилу....

Share this post


Link to post
Share on other sites

Ну тогда, может быть, выполнять вместо moveOut сразу что-то типа moveInCargo. Или проверять скорость и высоту и закрывать во время движения lockDriver/lockTurret.

Но это так, мысли вслух, потому как попытки пересесть будут 100%

Share this post


Link to post
Share on other sites

я думал над этим и разбился на уровне - а если он не из cargo перелез а с командира,а если то место будет уже занято (невероятная ситуация: человек перелезает и в это же время на его место садится другой игрок), не закинет ли его на броню к примеру, давал бы SeatSwitched предыдущую позицию - отсылали бы назад....

lockDriver/lockTurret - клева но у них эффект глобальный, а только для того чтобы запретить перелазить во время движения - жирно мне кажется, сюда же проблему в том  что если ездят только водитель и командир они должны беспрепятственно перелазить (если это возможно).

По мне moveOut  это самый гуманный способ.

Можно чекать менюшку игрока в машине и смотреть что он нажал (https://community.bistudio.com/wiki/Arma_3:_Event_Handlers/inGameUISetEventHandler#Action) сохранять его положение в стек и в EH Seat switch его извлекать и тогда у нас будет и новое место и старое (если надо игрока вернуть).

Но емае, мы тут ради того чтобы человек не сел в ненужный слот СТОЛЬКО гомнокода наплодим, что овчинка выделки не стоит. Поэтому все гуманно, сел не туда - выход, сел не туда во время движения - в могилу.

Edited by StDIABLO

Share this post


Link to post
Share on other sites

Есть еще способ реализации данного скрипта с использованием команды inGameUISetEventHandler. Вешаем EH на нажатие команды в меню взаимодействия. При срабатывании обработчика проверяем имя экшена ("GetInDriver","GetInTurret"...) и объект, к которому относится экшен, а также класс-нейм нашего игрока.

Код в init.sqf:

if (hasInterface) then {
	
	lockActionFunc = {
		//класс-неймы экипажа
		_typesOfVehCrew = ["wog_ksor_sergeant", "wog_ksor_officer_armored", "wog_ksor_driver_armored", "wog_ksor_crew_commander", "wog_ksor_crew_gunner", "wog_ksor_crew_driver", "wog_army_ucp_crew_commander", "wog_army_ucp_crew_gunner", "wog_army_ucp_crew_driver", "wog_army_ucp_squadleader", "wog_army_ucp_officer", "wog_army_ucp_Plsg", "rhsusf_usmc_marpat_d_crewman"];
		_arrayOfVeh = [LAV1];  //массив техники для блокировки
		
		if (((_this select 3)=='GetInDriver' || (_this select 3)=='GetInTurret' || (_this select 3)=='MoveToDriver' || (_this select 3)=='MoveToTurret') && ((_this select 0) in _arrayOfVeh) && !(typeOf player in _typesOfVehCrew)) then
		{
			hint 'У Вас нет доступа к управлению техникой!';
			true
		} else 
		{
			false
		};
	};

	inGameUISetEventHandler ["Action","_this call lockActionFunc;"];
};

Но есть одна загвоздка, как обсуждалось в этой теме: ACE функции ace_interaction_fnc_showMouseHint и ace_interaction_fnc_hideMouseHint перезаписывают параметры команды inGameUISetEventHandler при отрисовки и скрытии вспомогательного хинта. Другими словам, например, если мы возьмем ящик через меню взаимодействия ACE или воспользуемся продвинутой системой бросков гранат, выше упомянутые функции перезапишут EH, и тогда мы сможем сесть в технику, даже если не являемся экипажем.

...
// Disable action menu, showHud also disables all scripted UI (such as drawIcon3D)
inGameUISetEventHandler ["PrevAction", "false"];
inGameUISetEventHandler ["NextAction", "false"];
inGameUISetEventHandler ["Action", "false"];

Чтобы избежать этого, как вариант, можно изменить последние строчки кода в файле ace_interaction\functions\fnc_hideMouseHint.sqf  на эти:

...
// Disable action menu, showHud also disables all scripted UI (such as drawIcon3D)
inGameUISetEventHandler ["PrevAction", "false"];
inGameUISetEventHandler ["NextAction", "false"];

if (!isNil "lockActionFunc") then {
	inGameUISetEventHandler ["Action","_this call lockActionFunc;"];
} else {
	inGameUISetEventHandler ["Action", "false"];
};

Здесь мы проверяем, объявлена ли переменная lockActionFunc, которую задаем в init.sqf. Если объявлена, то ее содержимый код прописываем на исполнение в параметры inGameUISetEH. Если нет, то значит миссия не использует скрипт блокировки на технику, и меню через колесико будет работать в обычном режиме.

ace_interaction.pbo

Share this post


Link to post
Share on other sites
27 минут назад, Lex сказал:

Чтобы избежать этого, как вариант, можно изменить последние строчки кода в файле ace_interaction\functions\fnc_hideMouseHint.sqf  на эти:


...
// Disable action menu, showHud also disables all scripted UI (such as drawIcon3D)
inGameUISetEventHandler ["PrevAction", "false"];
inGameUISetEventHandler ["NextAction", "false"];

if (!isNil "lockActionFunc") then {
	inGameUISetEventHandler ["Action","_this call lockActionFunc;"];
} else {
	inGameUISetEventHandler ["Action", "false"];
};

 

Выглядит всё очень даже элегантно. Осталось протестировать и просить добавить это в сборку.

Единственное, что поскольку такие правки касаются всей сборки, хотелось бы убедиться в универсальности такого решения. Ну то есть возможно ли в одну функцию (в файле init.sqf) запихнуть, скажем, и ограничение доступа к технике, и, допустим, запрет на разборку статичного вооружения и еще какие-то EH и всё это в одной миссии в одной функции?  Не будет ли конфликтов?

Edited by Sandy

Share this post


Link to post
Share on other sites

Разумеется можно сделать ограничение доступа и запрет на разборку в одной функции, только нужно поиграться с условностями. А какие имеешь ввиду EH вставлять?

Share this post


Link to post
Share on other sites

Да я пока чисто теоретически, учитывая что сборку мы не каждый день меняем, а решение должно быть достаточно универсальным.

Share this post


Link to post
Share on other sites

@Lex, @Sandy Спасибо за идеи, только код надо тогда будет оформить в  функцию. Типа

[[arrayVehs],[arrayCrewClass],[arrayOfLockedPlaces]] call WOG_lockVehsCrew;

ну для пользователей будет явно проще. Вопрос в том что: Если я захочу к примеру 1 закрыть технику, и например запретить разбор стационарного вооружения, функции в нашем виде будут конфликтовать.

Получается нужен еще какой то обработчик. 

 

 

Edited by StDIABLO

Share this post


Link to post
Share on other sites

Если заняться серьезно, то тогда написать универсальную функцию для картоделов и добавить на инициализацию в аддон (можно даже в WMT).

Ее синтаксис я представляю такой:

[
	[<объект1>,["команда1","команда2","команда3"],["стрелок","сапер"],"Not allowed!"],  //Класс-неймам "стрелок" и "сапер" разрешить использование команд "команда1" "команда2" "команда3" на объекте "объект1". При запрете вывести сообщение "Not allowed"
	[<объект2>,["команда4","команда5"],[""],""],  //Всем запрещено использовать команды "команда4" "команда5" на "объект2". Без сообщения
	...
] call WOG_lockActions;

UI EH будет срабатывать на нажатие экшена и вызывать функцию с алгоритмом, который сначала проверит объект, находится ли он в списке проверяемых, если да, то проверяем название экшена, если он присутствует, то тогда проверяем класс-нейм. В конечном итоге если все условия удовлетворены, то возвращаем true (запрет) в inGameUISetEH, иначе false.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.