Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
  • Need help?

    Create a topic in the appropriate section
    Don't write everything in the chat!
  • Take a look at the marketplace

    There you can buy
    everything related to game servers
  • Don't want a ban?

    Please read our rules
    Don't disturb the order!
  • Sell or buy?

    Use services of the guarantor
    We will make your deal safe
  • 0
Тоха

Система торговцев (смена привязки к humanity)

Доброго времени суток, недавно возобновил работу над своим скриптом и наткнулся на очередную проблемку. Сам голову сломал, поэтому надеюсь на вашу помощь.

Суть проблемы такова. 

У нас есть Торговец, мы к нему подходим и наводим курсор ( в этот момент у нас идет проверка условий, а точнее проверка принадлежности конкретного торговца к классу (друг, нейтрал, герой, бандит) и проверка нашей humanity. После проверки получаем результат -  если хумки мало то  - "иди качайся дальше"  А если достаточно то - "добро пожаловать, вот товар"

Я задумал поменять немного условия на такие - мы подходим к торговцу и наводим курсор, в этот момент идет проверка условий: 1) определяетя количество humanity у нас. 2) в зависимости от humanity для нас доступны разные предметы (для каждого ранга свой ассортимент торговца) для торговли.

Я хочу попробовать реализовать через проверку условий в fn_selfActions.sqf

Было

if (_isMan && !_isPZombie && _traderType in serverTraders) then {


if (s_player_parts_crtl < 0) then {

_humanity = player getVariable ["humanity",0];
_traderMenu = call compile format["menu_%1;",_traderType];
_low_high = "low";
_humanity_logic = false;

if((_traderMenu select 2) == "friendly") then {
_humanity_logic = (_humanity < -5000);
};
if((_traderMenu select 2) == "hostile") then {
_low_high = "high";
_humanity_logic = (_humanity > -5000);
};
if((_traderMenu select 2) == "hero") then {
_humanity_logic = (_humanity < 5000);
};
if(_humanity_logic) then {
_cancel = player addAction [format[localize "STR_EPOCH_ACTIONS_HUMANITY",_low_high], "\z\addons\dayz_code\actions\trade_cancel.sqf",["na"], 0, true, false, "",""];
s_player_parts set [count s_player_parts,_cancel];
} else {

{
_buy = player addAction [format["Trade %1 %2 for %3 %4",(_x select 3),(_x select 5),(_x select 2),(_x select 6)], "\z\addons\dayz_code\actions\trade_items_wo_db.sqf",[(_x select 0),(_x select 1),(_x select 2),(_x select 3),(_x select 4),(_x select 5),(_x select 6)], (_x select 7), true, true, "",""];
s_player_parts set [count s_player_parts,_buy];

} count (_traderMenu select 1);
_buy = player addAction [localize "STR_EPOCH_PLAYER_289", "\z\addons\dayz_code\actions\show_dialog.sqf",(_traderMenu select 0), 999, true, false, "",""];
s_player_parts set [count s_player_parts,_buy];

};
s_player_parts_crtl = 1;
};
} else {
{player removeAction _x} count s_player_parts;s_player_parts = [];
s_player_parts_crtl = -1;

};

 

 

А вот что я пытаюсь запилить

 

 

if (_isMan && !_isPZombie && _traderType in serverTraders) then {
    if (s_player_parts_crtl < 0) then {
     _humanity = (player getVariable['humanity', 0]) -2500;
  

//Бандит

if(_humanity <= LvMinB) then {_buy = player addAction ["Торговаться", "\z\addons\dayz_code\actions\show_dialog_bandit.sqf",(_traderMenu select 0), 999, true, false, "",""];
s_player_parts set [count s_player_parts,_buy];};

//Выживший
if ((_humanity < LvMinH) && (_humanity > LvMinB)) then {_buy = player addAction ["Торговаться", "\z\addons\dayz_code\actions\show_dialog_s.sqf",(_traderMenu select 0), 999, true, false, "",""];
s_player_parts set [count s_player_parts,_buy];  };

//Герой 
if(_humanity >= LvMinH) then {_buy = player addAction ["Торговаться", "\z\addons\dayz_code\actions\show_dialog_hero.sqf",(_traderMenu select 0), 999, true, false, "",""];
s_player_parts set [count s_player_parts,_buy];};

s_player_parts_crtl = 1;
    };
} else {
        s_player_parts_crtl = -1;
        };

 

 

 

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

 

Вроде заставил скролл меню отфильтровывать по уровню humanity ссылки на ассортимент торговцев. Но не могу разобраться с этим show_dialog.sqf, я то думал тут у нас идут ссылки  на файл server_traders.sqf  (которые я тоже хотел сделать под каждый уровень хумки отдельные), но не разобрался, что у нас твориться в show_dialog... вот его внутренности

private ["_trader_data", "_dialog"];


if (DZE_ActionInProgress) exitWith {
cutText [(localize "str_epoch_player_97") , "PLAIN DOWN"];
};

_trader_data = (_this select 3);

_dialog = createdialog "TraderDialog";
lbClear TraderDialogCatList;
lbClear TraderDialogItemList;

TraderCurrentCatIndex = -1;
TraderItemList = -1;

TraderCatList = [];
{
private ["_index", "_x"];
_index = lbAdd [TraderDialogCatList, _x select 0];
TraderCatList set [count TraderCatList, _x select 1];
} count _trader_data;
waitUntil { !dialog };
TraderCurrentCatIndex = -1;
TraderCatList = -1;

 

 

Пожалуйста помогите, задумка интересная, хотелось бы реализовать. Если что, запутался внутри show_dialog из-за того, что пока скрипты понимаю и пишу на уровне примитивных условий и уже такие команды, как "_this select 3" я не понимаю...=( Как  я думаю - это  ссылка на переменную в неизвестный другой файл. поправьте если ошибаюсь. Не ругайтесь, прошу. Если все воедино соединить смогу, то со временем предоставлю вам собственную ранговую систему для dayz =). Но это только если я смогу закончить ее.

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

Edited by Тоха (see edit history)

Share this post


Link to post
Share on other sites

25 answers to this question

Recommended Posts

  • 0

Вот часть скрипта, весь не стал выкладывать, дабы не вводить в заблуждения. Может кому понадобиться. 

 

 

if (_isMan && !_isPZombie && (_traderType in serverTraders)) then {

_LevelRang = PlayerLevel;  // Это переменки для моей системы. Вместо нее можете сразу кол-во хумки присваивать.

if (_traderType == "RU_Damsel4") then {
if((_LevelRang == "Survived") || (_LevelRang == "Hero_0") || (_LevelRang == "Bandit_0")) then {
if (s_player_parts_crtl < 0) then {
s_player_parts_crtl = player addAction [("")+("Торговля")+(""), "ZSC\actions\show_dialog.sqf",(menu_Tanny_PMC select 0), 999, true, false, "",""];
};
};
};

} else {
    player removeAction s_player_parts_crtl; //Ремувер немного отличается от оригинала, переделал под себя. В оригинале было через переменку "_buy"
    s_player_parts_crtl = -1;
    };

 

 

В данном коде алгоритм таков: Мы подходим к торговцу "RU_Damsel4" - идет проверка нашего ранга (зависит от количества humanity). Если ранг позволяет, то появляется ассортимент от "фантомного торговца"  (которого не будет на карте, но его ассортимент можно подвязать к другому торговцу), весь товар от торговца "Tanny_PMC". По аналогии можно добавить любой другой ассортимент. А так же теперь можно разделить товар по рангам - на одного торговца. 

Делаю это сообщение ответом на вопрос, в надежде, что расписал понятненько =).

Еще раз огромное спасибо всем кто помогал, и даже объяснили мною не освоенную тему. Особая благодарность  dimquea за моментальную наводку, которую я не сразу понял)

Edited by Тоха (see edit history)

Share this post


Link to post
Share on other sites



  • 0

 

даю подсказку:

_traderMenu select 0

Сразу не заметил, за наводку спасибо, но я выше написал, у меня проблемы с select... я все никак не разберусь как они работают. я так понимаю это ссылка на переменку в другом файле, наверное show_dialog.sqf или server_traders.sqf ? 

Edited by Тоха (see edit history)

Share this post


Link to post
Share on other sites
  • 0

Сразу не заметил, за наводку спасибо, но я выше написал, у меня проблемы с select... я все никак не разберусь как они работают. я так понимаю это ссылка на переменку в другом файле, наверное show_dialog.sqf или server_traders.sqf ? 

раз не понял, разжую.

поднимемся выше и увидим:

_traderMenu = call compile format["menu_%1;",_traderType];

а теперь опустим промежуточные переменные:

_traderMenu = call compile format["menu_%1;",_typeOfCursorTarget];

стало быть

_traderMenu select 0

то же самое что

_typeOfCursorTarget

тоесть класснейм трейдера, а это значит что при запуске show_dialog.sqf в него передаётся класснейм. далее server_traders, категории и т.д.

в твоём случае нужно описать торговца в server_traders, но не ставить его на карте, а просто передавать класснейм. вернее "menu_класснейм".

Edited by dimquea (see edit history)

Share this post


Link to post
Share on other sites
  • 0

За разжеванность спасибо, пошел переваривать) Я так понял ты предлагаешь оставить все по дефолду. Поставить 1ого торговца на карту, и к нему подцепить  его личный ассортимент(меню), а остальные меню цеплять от фантомов (торговцев, которых на карте не будет, но класснейм ихний используется) ?

P.S. Кажется понял, пошел пробовать. Огромное спасибо. Долго доходит до меня. Если что удачное выйдет - отпишусь.

Edited by Тоха (see edit history)

Share this post


Link to post
Share on other sites
  • 0

вызываешь значит файл с такими переменными ["hero",(_TraderMenu select 0)] execVM "input.sqf";

в input.sqf получаешь их следующим образом:

_class = this select 0; // hero

_menu = this select 1; // _Tradermenu select 0

далее с ними уже спокойно работаешь

P.S. Еще несколько вызовов с таким же эффектом:

["hero",(_TraderMenu select 0)] call My_Function; // вызывает функцию My_Function  и передает ей переменные

["hero",(_TraderMenu select 0)] spawn My_Function; // делает тоже самое, но как я понял с поддеркой функций sleep, while и т.д. внутри функции (My_Function).

Share this post


Link to post
Share on other sites
  • 0

вызываешь значит файл с такими переменными ["hero",(_TraderMenu select 0)] execVM "input.sqf";

в input.sqf получаешь их следующим образом:

_class = this select 0; // hero

_menu = this select 1; // _Tradermenu select 0

далее с ними уже спокойно работаешь

P.S. Еще несколько вызовов с таким же эффектом:

["hero",(_TraderMenu select 0)] call My_Function; // вызывает функцию My_Function  и передает ей переменные

["hero",(_TraderMenu select 0)] spawn My_Function; // делает тоже самое, но как я понял с поддеркой функций sleep, while и т.д. внутри функции (My_Function).

тут другой случай. _TraderMenu select 0 идёт аргументом в addaction

Share this post


Link to post
Share on other sites
  • 0

я попытался объяснить автору что за зверь такой this select, и привести простые примеры для закрепления )

Share this post


Link to post
Share on other sites
  • 0

Private ['_переменная0','_переменная1','_переменная2']

_переменная0 = this select 0
_переменная1 = this select 1
_переменная2 = this select 2

Нумерация селекции начинается с нуля и порядок идет от написанных в Private локальных переменных.

Share this post


Link to post
Share on other sites
  • 0

 

порядок идет от написанных в Private локальных переменных.

шта? откуда ты это взял?

 

и как бы _this, а не this

Edited by dimquea (see edit history)

Share this post


Link to post
Share on other sites
  • 0

шта? откуда ты это взял?

 

и как бы _this, а не this

В простых скриптах считается как порядок, если под Локальную переменную ничего иного более не задается.

server_updateNearbyObjects = {
	private["_pos"];
	_pos = _this select 0;
	{
		[_x, "gear"] call server_updateObject;
	} count nearestObjects [_pos, dayz_updateObjects, 10];
};

_this, а не this

Сорян, пропустил.

Share this post


Link to post
Share on other sites
  • 0

В простых скриптах считается как порядок, если под Локальную переменную ничего иного более не задается.

server_updateNearbyObjects = {
	private["_pos"];
	_pos = _this select 0;
	{
		[_x, "gear"] call server_updateObject;
	} count nearestObjects [_pos, dayz_updateObjects, 10];
};

_this, а не this

Сорян, пропустил.

 

 

Я про порядок переменных в private, ты сам это придумал или кто научил? И что значит "простой" скрипт?

Share this post


Link to post
Share on other sites
  • 0

Я про порядок переменных в private, ты сам это придумал или кто научил? И что значит "простой" скрипт?

Простой - Однозадачный.

Например получить координату.

 

Про порядок:

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

Share this post


Link to post
Share on other sites
  • 0

Тогда и пиши, что это культура кода, не вводи людей в заблуждение.

Share this post


Link to post
Share on other sites
  • 0

Вот смотрите. В моем случае вызывается  show_dialog.sqf, внутри этого файла идет  присвоение переменке    _trader_data = (_this select 3);  Что в данном случае там спряталось? Если вызываем "диалог" с параметром (_traderMenu select 0)  а в переменке _traderMenu = call compile format["menu_%1;",_traderType];  а _tradeType в свою очередь цель в курсоре, тобишь наш торговец. Это жесть _))

P.S. Я пробовал параметр (_traderMenu select 0) заменить на "menu_Класс_торговца" (который есть в server_traders). Но получал пустой диалог без ассортимента. Сразу понял что дело в select. Выше описал свою догадку.

Edited by Тоха (see edit history)

Share this post


Link to post
Share on other sites
  • 0

Почитал свой бред. Решил конкретики добавить.

Вот что работает. (используется select)

 

//Герой 2го уровня

_traderMenu = call compile format["menu_%1;","Tanny_PMC"];
if((_humanity < LvMinH3) && (_humanity >= LvMinH2)) then {_buy = player addAction ["Торговаться", "ZSC\actions\show_dialog.sqf",(_traderMenu select 0), 999, true, false, "",""];
s_player_parts set [count s_player_parts,_buy];};

 

Вот что пытаюсь сделать 

 

_traderMenu = "menu_Tanny_PMC";
//Герой 2го уровня
if((_humanity < LvMinH3) && (_humanity >= LvMinH2)) then {_buy = player addAction ["Торговаться", "ZSC\actions\show_dialog.sqf", _traderMenu, 999, true, false, "",""];
s_player_parts set [count s_player_parts,_buy];};

 

 

Ну естественно получаю пустой диалог без товара. Так как внутри show_dialog.sqf работает переменная, которая присваивает значение неизвестное мне. _trader_data = (_this select 3)

 

 

private ["_trader_data", "_dialog"];

if (DZE_ActionInProgress) exitWith {
cutText [(localize "str_epoch_player_97") , "PLAIN DOWN"];
};

_trader_data = (_this select 3);

_dialog = createdialog "TraderDialog";
lbClear TraderDialogCatList;
lbClear TraderDialogItemList;

TraderCurrentCatIndex = -1;
TraderItemList = -1;

TraderCatList = [];
{
private ["_index", "_x"];
_index = lbAdd [TraderDialogCatList, _x select 0];
TraderCatList set [count TraderCatList, _x select 1];
} count _trader_data;
waitUntil { !dialog };
TraderCurrentCatIndex = -1;
TraderCatList = -1;

 

 

А лучше так

 

 

 
//Герой 2го уровня
if((_humanity < LvMinH3) && (_humanity >= LvMinH2)) then {_buy = player addAction ["Торговаться", "ZSC\actions\show_dialog.sqf", "menu_Tanny_PMC", 999, true, false, "",""];
s_player_parts set [count s_player_parts,_buy];};

 

Edited by Тоха (see edit history)

Share this post


Link to post
Share on other sites
  • 0

при передаче через addaction параметра, в скрипте он ловиться _this select 3. именно 3.

Share this post


Link to post
Share on other sites
  • 0

при передаче через addaction параметра, в скрипте он ловиться _this select 3. именно 3.

То есть, в данной ситуации это ни что иное как "menu_Tanny_PMC"  ?  А как тогда заставить его брать нужную переменку. Пробовал изменить на _this select 0 - но безрезультатно.

Edited by Тоха (see edit history)

Share this post


Link to post
Share on other sites
  • 0

То есть, в данной ситуации это ни что иное как "menu_Tanny_PMC"  ?  А как тогда заставить его брать нужную переменку. Пробовал изменить на _this select 0 - но безрезультатно.

https://community.bistudio.com/wiki/addAction

Share this post


Link to post
Share on other sites
  • 0

arguments: (optional): Anything - Arguments to pass to the script (will be _this select 3 inside the script). If Array is used as an argument for example, its 1st element reference would be _this select 3 select 0. Default value: nil

Как я понял _this select 3 при передачи выступает в роли _this select 0 (то есть берет самое первое значение) в данном случае id торговца?

Share this post


Link to post
Share on other sites
  • 0

 

то есть берет самое первое значение

да. и по идее

player addAction ["Торговаться", "ZSC\actions\show_dialog.sqf", "menu_Tanny_PMC", 999, true, false, "",""];

 

должно работать. юзай diag_log чтобы понять где ошибка.

Share this post


Link to post
Share on other sites
  • 0

Изучаю как использовать diag_log, а пока по поводу 

player addAction ["Торговаться", "ZSC\actions\show_dialog.sqf", "menu_Tanny_PMC", 999, true, false, "",""];

Не работает как ни странно.

Зато так работает. Это при условии что персонаж стоит "Tanny_PMC"

_traderMenu = call compile format["menu_%1;","Tanny_PMC"];
if((_humanity < LvMinH3) && (_humanity >= LvMinH2)) then {_buy = player addAction ["Торговаться", "ZSC\actions\show_dialog.sqf",(_traderMenu select 0), 999, true, false, "",""];

А если так (персонаж опять "Tanny_PMC"), а пытаюсь подвязать меню другого торговца, то опять не фурчит.

_traderMenu = call compile format["menu_%1;","RU_Damsel1"];
if((_humanity < LvMinH3) && (_humanity >= LvMinH2)) then {_buy = player addAction ["Торговаться", "ZSC\actions\show_dialog.sqf",(_traderMenu select 0), 999, true, false, "",""];

Если что, в server_traders все прописано и настроено

Edited by Тоха (see edit history)

Share this post


Link to post
Share on other sites
  • 0

Эм, так это ж выдача лога, диалога.

 

diag_log format['Бла-Бла: Что-то считаем: %1...',_переменная];
 

 


Что под _переменная? Что укажите.
 

 

_переменная = 'Вася пупкин';
 

 


В итоге получим 

 

Бла-Бла: Что-то считаем: Вася пупкин...
 

Share this post


Link to post
Share on other sites
  • 0

Видимо я неправильно, что то пишу. Хочу с помощью diag_log посмотреть что лежим в переменке на момент выполнения скрипта.

 

if (_isMan && !_isPZombie && (_traderType == "Tanny_PMC")) then {
if (s_player_parts_crtl < 0) then {
_traderMenuH = call compile format["menu_%1;","Tanny_PMC"];
s_player_parts_crtl = player addAction ["Торговаться", "ZSC\actions\show_dialog.sqf",(_traderMenuH select 0), 999, true, false, "",""];
diag_log format['Проверка торговца %1',_traderMenuH];
};
} else {
player removeAction s_player_parts_crtl;
s_player_parts_crtl = -1;
};

 

 

Данный скрипт урезан до простого. Для того чтобы было проще проверять работоспособность. Тоесть сейчас он работает так. Мы подходим к нпс, идет проверка на classname нпс. Если он "Tanny_PMC", то выполняем скрипт. Тобишь вызывается меню скролла "торговаться" и далее как мы разбирали выше. Так вот, как вы поняли конкретно это работает, но в логах ничего не отображается. Что то я не пойму как diag-Log правильно поместить. 

Edited by Тоха (see edit history)

Share this post


Link to post
Share on other sites
  • 0

Вообщем решил проблему, использовав cutText... Сразу нашел ошибку у себя. Давно была надобность закоментировать всех торговцев(коментировал целиком всех торгашей - 4мя символами и поэтому не замечал их все это время), кроме одного, который как раз работал... Теперь делаю задуманное. Dimquea, ты был прав. (во всем). Чуть позже тут напишу как правильно выглядит, то чего я так долго не мог добиться. Спасибо всем кто помогал!

Edited by Тоха (see edit history)

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

  • Similar Content

    • By RedLink
      Всем Привет.
      Представляю вам систему логирования действий игроков и т.д. по принципу InfiSTAR.
      Для установки вам понадобятся кастомный compiles.sqf (тем кто не знает как это сделать, -> поиск по форуму).
       
      1. Открываем в серверной части файл dayz_server\init\server_functions.sqf и в самом низу вставляем:
      "SK_log" addPublicVariableEventHandler {(_this select 1) call fnc_Log;}; 2. Теперь открываем в папке с миссией файл compiles.sqf и ищем что-то в этом плане:
       
      if (!isDedicated) then { блаблабла }; и после него вставляем
      fnc_log = { private ["_fileName","_message","_dll","_dll2","_display"]; _fileName = toLower (_this select 0); _message = _this select 1; _display = if (count _this > 2) then {_this select 2} else {false}; if (!isDedicated) then { SK_Log = [_fileName,if (typeName _message == "ARRAY") then {_message} else {toArray _message},_display]; publicVariableServer "SK_Log"; } else { _message = if (typeName _message == "ARRAY") then {toString _message} else {_message}; if (_display) then {diag_log format ["[%1] %2",toUpper (_fileName),_message];}; _dll2 = format["!InfiSTAR_Logs~%1~%2",_fileName,_message]; "LogDLL" callExtension _dll2; }; }; где "!InfiSTAR_Logs" - ваша папка, куда вы хотите складировать логи.
       
      3. Открываем файл publicVariable.txt в фильтрах Battleye и в первой строке "5 !=блаблабла" в конце добавляем "!=SK_Log" (пример ниже)
      5 !"donn_heli_monitor" !"fnc_log" !=fnc_log !"redHunter" !=redHunter !"cad_pvar_s" !"PVDZE_veh_Update" !="PVDZE_veh_Update" !="PVDZE_adminevents" !="PVDZ_plr_Death" !"PVDZ_plr_Death" !="PVDZE_atp" !"PVDZE_atp" !"PVDZ_plr_LoginRecord" !="PVDZ_plr_LoginRecord" !"PVDZE_log_lockUnlock" !=PVDZE_log_lockUnlock !"redHunter" !=redHunter !"redDiagLog" !=redDiagLog !="PVDZE_atp" !=(remExField|remExFP) !=(PVCDZ_obj_GutBody|drn_AskServerDynamicWeatherEventArgs|BIS_effects_gepv|achievement|dayzFlies) !=PVDZ_(drg_(RaDrag|RaLW|RLact)|getTickTime|hlt_Bleed|obj_(Delete|Publish|RoadFlare|Destroy|Fire)|veh_Save|veh_SF) !=PVDZ_(plr_(Death|Login[12]|LoginRecord|Save|SwitchMove)|Server(_Simulation|StoreVar)|sec_atp) !=PVDZ_(playerMedicalSync|object_replace|groupInvite) !=PVDZ_(send(|Unconscious)) !=PVDZ_Server_(buildLock|LogIt|UpdateGroup) !=PVDZ_Server_process(Code|SetAccessCode) !=PVDZ_objgather_(Delete|Knockdown) !=PVDZE_(obj_(Delete|Publish|Swap|Trade)|fullobj_Publish|maintainArea|veh_(Lock|Publish2|Upgrade)|handleSafeGear|plr_(DeathB|FriendRQ|TradeMenu)) !=PVAH_AdminReq !=PVAH_WriteLogReq !=PVAHR_0_[a-zA-Z0-9]{20,40} !"PVAHR_" !="PVAH_AdminReq" !="PVAH_WriteLogReq" !=PVAHR_0_[a-zA-Z0-9]{20,40} !="PVDZE_(query|store|spawn)Vehicle" !="PVDZE_PingSend" !="PVDZE_veh_Init" !"SK_Log" !=SK_Log  
      4. А теперь самое главное.
      Пример вывода лога в отдельный файл. Возьмем для примера файл смерти игрока от тех или иных причин.
      Открываем в серверной части файл server_playerDied.sqf и ищем там строку
       
      diag_log format["%1 (%2) %3 @%4 %5",_playerName,_playerID,_message,mapGridPosition _pos,_pos]; после нее вставляем
      ["DEATHS",format ["%1 (%2) %3 @%4 %5",_playerName,_playerID,_message,mapGridPosition _pos,_pos],true] call fnc_log; Таким образом в указанной в папке в п. 2 создатся файл deaths_блаблабла.txt, в котором будет отображен лог о смерти игрока по тем или иным причинам.
       
      Формат записи лога выглядит следующим образом:
      _message = format ["Что хочу то и пишу и хочу видеть значение %1",_значение%1]; ["ИМЯ_ФАЙЛА_ЛОГА",_message,true] call fnc_log; или напрямую
      ["Имя_файла_лога",format ["тут будет то что в значении %1",_значение%1],true] call fnc_log;  
      Представляю варианты 4-х DLL, которые работают для этой системы (качаете любую из них и переименовываете в LogDLL.dll). Эту DLL необходимо закинуть в папку с игрой (например в C:\Games\Arma 2 Operation Arrowhead).
      LogDLL.dll создает в папке с логами отдельную папку по названию лога.
      LogDLL_-_dd-MM-yyyy и иные ее интерпретации - создает в папке с логами отдельную папку с датой, в которой хранятся все логи за эту дату.
       
      Если есть вопросы, задавайте.
       
      Оригинал данного скрипта и ссылки на разработчика ниже.
      Копирайта

      Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.
    • By BorizzK
      Автор: Виталий Мизев
       
      Для начала в папке профиля сервера которая указана в параметре запуска сервера -profile=
      создаем 2 файла
      pointPlayerPVP.lst - координаты спавна нового персонажа в формате vector
      playersSetUID.ini - Steam UID игроков | номер комплекта стартового лута для выбора
       
      Пример формата файла pointPlayerPVP.lst
      6010.40 0 7742.71
      6386.92 0 7945.12
      6478.50 0 7874.77
      6044.73 0 7699.81
       
      Пример формата playersSetUID.ini - STEAMUID|номер
      76531195156927007|1
      76561838156127001|2

       
      Игроку с Steam UID 6531195156927007 будет выдат комплект 1, 76561838156127001 комплект 2, если в файле UID нет, то рандомно из остальных комплектов
       
      В файле init.c
       
      в теле класса: class CustomMission: MissionServer
       
      сначала обьявим массивы
       
      ref array<string> m_pointPlayerPVP = new array<string>;;
      ref map<string, int> m_playersSetUID = new map<string, int>;
       
      это массивы глобальны в классе и могут использоваться во всех функциях класса
       
      в теле override void OnInit() (выполняется при запуске сервера)
       
      Чтение координат спавна из файла в массив m_pointPlayerPVP
      string line_content; FileHandle file = OpenFile("$profile:pointPlayerPVP.lst", FileMode.READ); Print("::: OpenFile : pointPlayerPVP.lst : $profile"); if (file != 0) { while ( FGets( file, line_content ) > 0 ) { m_pointPlayerPVP.Insert( line_content); } CloseFile(file); } m_pointPlayerPVP.Debug();  
      Чтение Steam UID и номера из файла в массив m_playersSetUID
      array<string> strFileParam; file = OpenFile("$profile:playersSetUID.ini", FileMode.READ); Print("::: OpenFile : playersSetUID.ini : $profile"); if (file != 0) { while ( FGets( file, line_content ) > 0 ) { strFileParam = new array<string>; line_content.Split( "|", strFileParam ); m_playersSetUID.Insert(strFileParam.Get(0), strFileParam.Get(1).ToInt()); } CloseFile(file); }  
      Далее
      При создании НОВОГО обьекта игрока
       
      сначала ему задаются координаты рандомно выбираясь из массива m_pointPlayerPVP
      см как идет работа с этим массивом
      override PlayerBase CreateCharacter(PlayerIdentity identity, vector pos, ParamsReadContext ctx, string characterName) { Entity playerEnt; if (m_pointPlayerPVP.Count()>0) { Print (m_pointPlayerPVP.Count()); int maxNum = m_pointPlayerPVP.Count(); int numPoint = Math.RandomInt(0, maxNum - 1); pos = m_pointPlayerPVP.Get(numPoint).ToVector(); } playerEnt = GetGame().CreatePlayer(identity, characterName, pos, 0, "NONE");//Creates random player Class.CastTo(m_player, playerEnt); GetGame().SelectPlayer(identity, m_player); return m_player; }  
      Затем при создании стартового комплекта лута комплект выдается в зависимости от наличия в файле UID и номера после | (комплекта) (в данном случае для номера 1 набор собран (см case :1) , для остальных ничего)
      override void StartingEquipSetup(PlayerBase player, bool clothesChosen) { //По умолчанию номер комплекта выбирается рандомно int numSet = Math.RandomInt(2,6); /// 1 - Админ сет, 2-6 сеты для всех пока пусты EntityAI itemEnt; ItemBase itemBs; //Это тут на всякий случай //Получаем UID //PlayerIdentity p_identity = player.GetIdentity(); //p_identity.GetName(); // Получим имя игрока //p_identity.GetPlainId(); // UID в нашем знакомом виде 7656119********** //p_identity.GetId(); // получим UID в не знакомом виде Ue7dyagee34********* //p_identity.GetPlayerId(); // получим порядковый номер объекта типа игрок PlayerIdentity p_identity = player.GetIdentity(); string p_name = p_identity.GetName(); int p_id = p_identity.GetPlayerId(); if( p_identity ) { string uid_pl = p_identity.GetPlainId(); if (m_playersSetUID.Contains(uid_pl)) { numSet = m_playersSetUID.Get(uid_pl); } } itemEnt = player.GetInventory().CreateInInventory("Rag"); itemBs = ItemBase.Cast(itemEnt); itemBs.SetQuantity(4); SetRandomHealth(itemEnt); itemEnt = player.GetInventory().CreateInInventory("RoadFlare"); itemBs = ItemBase.Cast(itemEnt); switch( numSet ) //Раздаем лут { case 1: //ADMIN { player.RemoveAllItems(); player.GetInventory().CreateInInventory("CoyoteBag_Green"); itemBs = ItemBase.Cast(itemEnt); player.GetInventory().CreateInInventory("TTSKOPants"); itemBs = ItemBase.Cast(itemEnt); player.GetInventory().CreateInInventory("TTsKOJacket_Camo"); itemBs = ItemBase.Cast(itemEnt); player.GetInventory().CreateInInventory("CombatBoots_Black"); itemBs = ItemBase.Cast(itemEnt); player.GetInventory().CreateInInventory("CombatKnife"); itemBs = ItemBase.Cast(itemEnt); player.GetInventory().CreateInInventory("FNX45"); itemBs = ItemBase.Cast(itemEnt); player.GetInventory().CreateInInventory("Mag_FNX45_15Rnd"); itemBs = ItemBase.Cast(itemEnt); player.GetInventory().CreateInInventory("Mag_FNX45_15Rnd"); itemBs = ItemBase.Cast(itemEnt); player.GetInventory().CreateInInventory("Mag_AKM_30Rnd"); itemBs = ItemBase.Cast(itemEnt); player.GetInventory().CreateInInventory("Mag_AKM_30Rnd"); itemBs = ItemBase.Cast(itemEnt); itemEnt = player.GetInventory().CreateInInventory( "akm" ); itemEnt.GetInventory().CreateAttachment( "PSO11Optic" ); itemEnt.GetInventory().CreateAttachment( "AK_WoodBttstck" ); itemEnt.GetInventory().CreateAttachment( "AK_WoodHndgrd" ); itemEnt.GetInventory().CreateAttachment( "AK_Suppressor" ); itemEnt = player.GetInventory().CreateInInventory("Rag"); itemBs = ItemBase.Cast(itemEnt); itemBs.SetQuantity(4); itemEnt = player.GetInventory().CreateInInventory("RoadFlare"); itemBs = ItemBase.Cast(itemEnt); player.SetHealth("","",1000); //ТЕСТ //SetAllowDamage НЕ РАБОТАЕТ ДЛЯ ОНЛАЙНА - БОГЕМЦЫ ВЫКЛЮЧИЛИ //Тут обсуждение - https://forums.dayz.com/topic/240028-pve-server-disable-pvp-damage/ //Есть идея насчет доработки кода обрабатывающего нанесение урона player.SetAllowDamage(false); break; } case 2: { break; } case 3: { break; } case 4: { break; } case 5: { break; } case 6: { break; } } } Вот как-то так
       
      На основе этого можно построить свою более развитую систему, например загружая координаты для кастомного спавн лута,  расстановки зданий и тп
       
       
    • By DrTauren
      На сколько я знаю, есть другой скрипт для создания системы крафта на сервер Altis Life, но данная статья позволит сделать это в разы проще. Без необходимости изменять кучу всего.
       
      Установка:
      1) Идём в папку core и создаем в ней папку craft. Затем в ней создаём файлы fn_craft.sqf, fn_craft_update.sqf, fn_craft_updateFilter.sqf, fn_craftAction.sqf и fn_craftCfg.sqf
      2) В файл fn_craft.sqf вставляем этот код:
      private["_dialog","_inv","_itemInfo","_filter"]; //Declare all private variables if(!dialog) then { //Verify if the window is open  createDialog "Life_craft"; }; disableSerialization; //Disable Serialization if(life_is_processing) exitWith{  closeDialog 2001;  closeDialog 0; }; _dialog = findDisplay 666; //find the craft dialog/window _inv = _dialog displayCtrl 669; //find the listbox of items can be created lbClear _inv; //clear the listbox _filter = _dialog displayCtrl 673; _filter lbAdd localize "STR_CRAFT_FILTER_Weapon"; _filter lbSetData[(lbSize _filter)-1,"weapon"]; _filter lbAdd localize "STR_CRAFT_FILTER_Uniform"; _filter lbSetData[(lbSize _filter)-1,"uniform"]; _filter lbAdd localize "STR_CRAFT_FILTER_Backpack"; _filter lbSetData[(lbSize _filter)-1,"backpack"]; _filter lbAdd localize "STR_CRAFT_FILTER_Item"; _filter lbSetData[(lbSize _filter)-1,"item"]; _filter lbSetCurSel 0; 3) В файл fn_craft_update.sqf вставляем это:
      #include "..\..\script_macros.hpp" private["_dialog","_inv","_mats","_item","_struct","_str","_invSize","_matsNeed","_matsNum","_config","_itemFilter"]; //Declare all private variables disableSerialization; //Disable Serialization _dialog = findDisplay 666; //find the craft dialog/window _inv = _dialog displayCtrl 669; //find the listbox of items can be created _mats = _dialog displayCtrl 672; _struct = ""; if ((lbCurSel 669) == -1) exitWith {hint localize "STR_ISTR_SelectItemFirst";}; _item = lbData[669,(lbCurSel 669)]; _itemFilter = lbData[673,(lbCurSel 673)]; _config = [_itemFilter] call life_fnc_craftCfg; {  if (_item == _x select 0) then {  _matsNeed = _x select 1;  _invSize = count _matsNeed;  for [{_i = 0},{_i < _invSize - 1},{_i = _i + 2}] do {  _str = M_CONFIG(getText,"VirtualItems",(_matsNeed select _i),"displayName");  _matsNum = _matsNeed select _i+1;  _struct = _struct + format["%1x %2<br/>",_matsNum,(localize _str)];  };  }; } foreach (_config); if (_struct == "") then {  _struct = "Es wird nichts benötigt"; }; _mats ctrlSetStructuredText parseText format[" <t size='0.8px'> %1 </t> ",_struct]; 4) В fn_craft_updateFilter.sqf:
      #include "..\..\script_macros.hpp" disableSerialization; private["_list","_filter","_dialog","_inv","_mats","_filterBox","_item","_itemFilter"]; _dialog = findDisplay 666; //find the craft dialog/window _inv = _dialog displayCtrl 669; //find the listbox of items can be created _mats = _dialog displayCtrl 672; _filterBox = _dialog displayCtrl 673; _itemFilter = lbData[673,(lbCurSel 673)]; lbClear _inv; _struct = ""; _config = [_itemFilter] call life_fnc_craftCfg; {     if(_itemFilter == "item") then{         _str = localize M_CONFIG(getText,"VirtualItems",(_x select 0),"displayName");         _inv lbAdd format["%1",_str]; //add a gun to the listbox         _inv lbSetData[(lbSize _inv)-1,_x select 0]; //set the data of the gun         } else {             _itemInfo = [_x select 0] call life_fnc_fetchCfgDetails;             _inv lbAdd format["%1",_itemInfo select 1]; //add a gun to the listbox             _inv lbSetData[(lbSize _inv)-1,_itemInfo select 0]; //set the data of the gun             _inv lbSetPicture[(lbSize _inv)-1,_itemInfo select 2];         }; } foreach (_config); _inv lbSetCurSel 0; _item = lbData[669,(lbCurSel 669)]; _config = [_itemFilter] call life_fnc_craftCfg; {     if(_item == _x select 0)then {         _matsNeed = _x select 1;         _invSize = count _matsNeed;         for [{_i = 0},{_i < _invSize - 1},{_i = _i + 2}] do {             _str = M_CONFIG(getText,"VirtualItems",(_matsNeed select _i),"displayName");             _matsNum = _matsNeed select _i+1;             _struct = _struct + format["%1x %2<br/>",_matsNum,(localize _str)];         };     }; } foreach (_config); _mats ctrlSetStructuredText parseText format[" <t size='0.8px'> %1 </t> ",_struct]; 5) В fn_craftAction.sqf:
      #include "..\..\script_macros.hpp" private["_dialog","_item","_itemInfo","_oldItem","_newItem","_upp","_itemName","_ui","_progress","_pgText","_cP","_allMaterial","_matsNeed","_invSize","_handledItem","_itemFilter","_backpackOldItems","_weight","_weightUsedItems"]; disableSerialization; _dialog = findDisplay 666; if((lbCurSel 669) isEqualTo -1) xitWith {hint localize "STR_ISTR_SelectItemFirst";}; _item = lbData[669,(lbCurSel 669)]; _allaterial = true; _itemFilter = lbData[673,(lbCurSel 673)]; _matsNeed = 0; _config = [_itemFilter] call life_fnc_craftCfg; life_action_inUse = true;//Lock out other actions during processing. {     if (_item isEqualTo (_x select 0))then {         _matsNeed = _x select 1;         _invSize = count _matsNeed;         for [{_i=0},{_i<_invSize-1},{_i=_i+2}] do {             _matsNum = _matsNeed select _i+1;             if ((ITEM_VALUE(_matsNeed select _i)) < _matsNum) then {_allMaterial = false;};         };     }; } foreach (_config); _newItem = _item; diag_log format ["%1",allMaterial]; if (!_allMaterial) exitWith {hint localize "STR_PM_NoMaterial"; life_action_inUse = false;}; //Some checks if ((count _matsNeed) isEqualTo 0) exitWith {life_action_inUse = false;}; if (_itemFilter isEqualTo "backpack" && backpack player != "") exitWith {     //hint localize "STR_CRAFT_AR_Backpack";     hint "Remove your backpack before making a new one.";     life_action_inUse = false; }; if (_itemFilter isEqualTo "uniform" && uniform player != "") exitWith {     //hint localize "STR_CRAFT_AR_Uniform";     hint "Remove your uniform before making a new one.";     life_action_inUse = false; }; if (_itemFilter isEqualTo "weapon") then {     if (!(player canAdd _newItem) || currentWeapon player != "") exitWith {         hint localize "STR_NOTF_NoRoom";         life_action_inUse = false;     }; }; if (_itemFilter isEqualTo "item") then {     _weight = [_item] call life_fnc_itemWeight;     _weightUsedItems = 0;     for [{_i=0},{_i<(count _matsNeed)-1},{_i=_i+2}] do {         _matsNum = _matsNeed select _i+1;         _weightUsedItems = _weightUsedItems + (([(_matsNeed select _i)] call life_fnc_itemWeight) * _matsNum);         diag_log format ["%1 - %2",(_matsNeed select _i),_weightUsedItems];     }     if ((life_carryWeight - _weightUsedItems + _weight) > life_maxWeight) exitWith {         hint localize "STR_NOTF_NoRoom";         life_action_inUse = false;     }; }; _oldItem = _matsNeed; if (_itemFilter isEqualTo "item") then {     _itemName = localize M_CONFIG(getText,"VirtualItems",_newItem,"displayName"); } else {  _itemInfo = [_newItem] call life_fnc_fetchCfgDetails;  _itemName = _itemInfo select 1; }; life_is_processing = true; _upp = format["Crafting %1",_itemName]; closeDialog 0; //Setup our progress bar. disableSerialization; 5 cutRsc ["life_progress","PLAIN"]; _ui = uiNamespae getVariable "life_progress"; _progress = _ui displayCtrl 38201; _pgText = _ui displayCtrl 38202; _pgText ctrlSetText format["%2 (1%1)...","%",_upp]; _progress progressSetPosition 0.01; _cP = 0.01; _removeItemSuccess = true; _invSize = count _oldItem; for [{_i=0},{_i<_invSize-1},{_i=_i+2}] do {     _handledItem = (_oldItem select _i);     if(!([false,_handledItem,_oldItem select _i+1] call life_fnc_handleInv)) exitWith {_removeItemSuccess = false;}; }; if (!_removeItemSuccess) exitWith {5 cutText ["","PLAIN"]; life_is_processing = false; life_action_inUse = false;}; for "_i" from 0 to 1 step 0 do {  sleep 0.3;  _cP = _cP + 0.01;  _progress progressSetPosition _cP;  _pgText ctrlSetText format["%3 (%1%2)...",round(_cP * 100),"%",_upp];  if(_cP >= 1) exitWith {}; }; if (_itemFilter isEqualTo "backpack") then {  if(backpack player isEqualTo "") then {  player addBackpack _newItem;  } else {  hint localize "STR_CRAFT_AR_Backpack";  life_is_processing = false;  life_action_inUse = false;  }; }; if (_itemFilter isEqualTo "uniform") then{  if(uniform player isEqualTo "") then{  player addUniform _newItem;  } else {  hint localize "STR_CRAFT_AR_Uniform";  life_is_processing = false;  life_action_inUse = false;  }; }; if (_itemFilter isEqualTo "weapon") then{  if(player canAdd _newItem) then{  player addIem _newItem;  } else {  if(currentWeapon player isEqualTo "") then{  player addWeapon _newItem;  } else {  5 cutText ["","PLAIN"];  for [{_i=0},{_i<_invSize-1},{_i=_i+2}] do {  _handledItem = (_oldItem select _i);  [true,_handledItem,_oldItem select _i+1] call life_fnc_handleInv;  };  life_is_processing = false;  life_action_inUse = false;  };  }; }; if (_itemFilter isEqualTo "item") then{  _handledItem = _newItem;  [true,_handledItem,1] call life_fnc_handleInv; }; 5 cutText ["","PLAIN"]; titleText[format[localize "STR_CRAFT_Process",_itemName],"PLAIN"]; [0] call SOCK_fnc_updatePartial; life_is_processing = false; life_action_inUse = false; 6) В fn_craftCfg.sqf:
      #include "..\..\script_macros.hpp" private["_craft","_return"]; _craft = param [0,"",[""]]; if(_craft == "") exitWith {closeDialog 0}; //Bad shop type passed. switch(_craft) do {     case "weapon": {         _return = [             //[Object classname, [item #1,quantity item #1,item #2,quantity item #2]],]             ["hgun_Pistol_01_F", ["diamond_cut",2,"copper_refined",1]],             ["SMG_01_F", ["gunbarrel",2,"copper_refined",5,"cloth",3,"diamond_uncut",2]],             ["SMG_05_F", ["gunbarrel",1,"cloth",2,"copper_refined",4,"diamond_uncut",1]],             ["hgun_PDW2000_F", ["gunbarrel",1,"cloth",1,"copper_refined",3]],             ["optic_Aco", ["diamond_cut",2,"glass",2,"iron_refined",1]],             ["optic_ACO_grn", ["diamond_cut",2,"glass",2,"iron_refined",1]],             ["optic_Holosight", ["diamond_cut",3,"glass",3,"iron_refined",2]]         ];     };     case "uniform": {         _return = [             //[Object classname, [item #1,quantity item #1,item #2,quantity item #2]],]             ["U_BG_leader", ["diamond_cut",5,"cloth",5,"iron_refined",8]]         ];     };     case "backpack": {         _return = [             //[Object classname, [item #1,quantity item #1,item #2,quantity item #2]],]             ["B_Carryall_mcamo", ["diamond_cut",1,"cloth",4,"kevlar",2]]         ];     };     case "item": {         _return = [             //[Object classname, [item #1,quantity item #1,item #2,quantity item #2]],]             ["spikeStrip", ["copper_refined",2]],             ["lockpick", ["copper_refined",1]]         ];     }; }; _return; 7) Открываем файл functions.hpp и добавляем туда:
      class Crafting {         file = "core\craft";         class craft {};         class craftAction {};         class craftCfg {};         class craft_update {};         class craft_updateFilter {};     }; 8) Открываем stringtable.xml и добавляем это:
          <Package name="Craft">           <Key ID="STR_CRAFT_Title">               <Original>Crafting Menu</Original>           </Key>           <Key ID="STR_PM_CraftStats">               <Original>Object to craft</Original>           </Key>           <Key ID="STR_PM_CraftMaterials">               <Original>Materials needed</Original>           </Key>           <Key ID="STR_CRAFT_Button">               <Original>Craft</Original>           </Key>           <Key ID="STR_PM_NoMaterial">               <Original>You do not have all the required materials</Original>           </Key>           <Key ID="STR_CRAFT_Process">               <Original>You have crafted: %1</Original>           </Key>         <Key ID="STR_CRAFT_FILTER_Weapon">               <Original>Weapons</Original>           </Key>           <Key ID="STR_CRAFT_FILTER_PWeapon">               <Original>Prim. Weapons</Original>           </Key>           <Key ID="STR_CRAFT_FILTER_HWeapon">               <Original>Sec. Weapons</Original>           </Key>           <Key ID="STR_CRAFT_FILTER_Ammo">               <Original>Ammos</Original>           </Key>           <Key ID="STR_CRAFT_FILTER_Uniform">               <Original>Uniforms</Original>           </Key>           <Key ID="STR_CRAFT_FILTER_Vest">               <Original>Vests</Original>           </Key>           <Key ID="STR_CRAFT_FILTER_Backpack">               <Original>Backpacks</Original>           </Key>           <Key ID="STR_CRAFT_FILTER_Item">               <Original>Items</Original>           </Key>           <Key ID="STR_CRAFT_AR_Question">               <Original>Would you like to equip this item?</Original>           </Key>           <Key ID="STR_CRAFT_AR_Backpack">               <Original>If you chose yes your current backpack will be deleted and replaced by the new one else it will spawn on the ground</Original>           </Key>           <Key ID="STR_CRAFT_AR_PWeapon">               <Original>If you chose yes your prim. weapon will be deleted and replaced by the new one else it will spawn on the ground</Original>           </Key>           <Key ID="STR_CRAFT_AR_HWeapon">               <Original>If you chose yes your sec. weapon will be deleted and replaced by the new one else it will spawn on the ground</Original>           </Key>           <Key ID="STR_CRAFT_AR_Uniform">               <Original>If you chose yes your current uniform will be deleted and replaced by the new one else it will spawn on the ground</Original>           </Key>           <Key ID="STR_CRAFT_AR_Vest">               <Original>If you chose yes your current vest will be deleted and replaced by the new one else it will spawn on the ground</Original>           </Key>     </Package> 9) Переходим в папку dialog и создаём там файл craft.hpp со следующим содержимым:
      class Life_craft {     idd = 666;     name= "life_craft";     movingEnable = false;     enableSimulation = true;     onLoad = "[] spawn life_fnc_craft";     class controlsBackground {         class Life_RscTitleBackground:Life_RscText {             colorBackground[] = {"(profilenamespace getvariable ['GUI_BCG_RGB_R',0.3843])", "(profilenamespace getvariable ['GUI_BCG_RGB_G',0.7019])", "(profilenamespace getvariable ['GUI_BCG_RGB_B',0.8862])", "(profilenamespace getvariable ['GUI_BCG_RGB_A',0.7])"};             idc = -1;             x = 0.1;             y = 0.2;             w = 0.8;             h = (1 / 25);         };         class MainBackground:Life_RscText {             colorBackground[] = {0, 0, 0, 0.7};             idc = -1;             x = 0.1;             y = 0.2 + (11 / 250);             w = 0.8;             h = 0.6 - (22 / 250);         };     };     class controls {         class Title : Life_RscTitle {             colorBackground[] = {0, 0, 0, 0};             idc = 667;             text = "$STR_CRAFT_Title";             x = 0.1;             y = 0.2;             w = 0.6;             h = (1 / 25);         };         class craftListHeader : Life_RscText         {             idc = 668;             colorBackground[] = {"(profilenamespace getvariable ['GUI_BCG_RGB_R',0.3843])", "(profilenamespace getvariable ['GUI_BCG_RGB_G',0.7019])", "(profilenamespace getvariable ['GUI_BCG_RGB_B',0.8862])", 0.5};             text = "$STR_PM_CraftStats";             sizeEx = 0.04;             x = 0.105; y = 0.26;             w = 0.275; h = 0.04;         };         //Craft list         class craftList : life_RscListBox         {             idc = 669;             sizeEx = 0.030;             onLBSelChanged = "[] spawn life_fnc_craft_update";             x = 0.105;             y = 0.31;             w = 0.275; h = 0.44;         };         //Materials list header         class materialListHeader : Life_RscText         {             idc = 670;             colorBackground[] = {"(profilenamespace getvariable ['GUI_BCG_RGB_R',0.3843])", "(profilenamespace getvariable ['GUI_BCG_RGB_G',0.7019])", "(profilenamespace getvariable ['GUI_BCG_RGB_B',0.8862])", 0.5};             text = "$STR_PM_CraftMaterials";             sizeEx = 0.04;             x = 0.395; y = 0.26;             w = 0.275; h = 0.04;         };         //Materials list         class materialList : Life_RscControlsGroup         {             idc = 671;             w = 0.275;             h = 0.44;             x = 0.395;             y = 0.30;             class Controls             {                 class mats : Life_RscStructuredText                 {                     idc = 672;                     sizeEx = 0.020;                     text = "";                     x = 0;                     y = 0;                     w = 0.27; h = 0.44;                 };             };         };         //FILTER         class FilterList : Life_RscCombo         {             idc = 673;             colorBackground[] = {0,0,0,0.7};             onLBSelChanged  = "[] call life_fnc_craft_updateFilter";             x = 0.69;             y = 0.32;             w = (6.25 / 30);             h = (1 / 25);         };         //Craft button         class ButtonCraft : Life_RscButtonMenu {             idc = 674;             text = "$STR_CRAFT_Button";             colorBackground[] = {"(profilenamespace getvariable ['GUI_BCG_RGB_R',0.3843])", "(profilenamespace getvariable ['GUI_BCG_RGB_G',0.7019])", "(profilenamespace getvariable ['GUI_BCG_RGB_B',0.8862])", 0.5};             onButtonClick = "if(!life_is_processing) then {[] spawn life_fnc_craftAction};";             x = 0.69;             y = 0.26;             w = (6.25 / 40);             h = (1 / 25);         };         class CloseButtonKey : Life_RscButtonMenu {             idc = -1;             text = "$STR_Global_Close";             onButtonClick = "closeDialog 0;";             x = 0.1;             y = 0.8 - (1 / 25);             w = (6.25 / 40);             h = (1 / 25);         };     }; };  10) Открываем файл Masterhandler.hpp и добавляем туда:
      #include "craft.hpp" 11) В папке dialogs открываем player_inv.hpp и добавляем код:
              class ButtonCrafting: Life_RscButtonMenu {             idc = 2025;             text = "Crafting";             onButtonClick = "createDialog ""Life_craft"";";             x = 0.1 + (6.25 / 19.8) + (1 / 250 / (safezoneW / safezoneH));             y = 0.805;             w = (6.25 / 40);             h = (1 / 25);         };  
       
      Оригинал на английском:
      https://www.altisliferpg.com/topic/3964-tutorial-crafting-system/  
  • Our picks

×
×
  • Create New...

Important Information

By using this site, you automaticly agree to our Guidelines and Privacy Policy.
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.