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 serversDon'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
-
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
Доброго времени суток, недавно возобновил работу над своим скриптом и наткнулся на очередную проблемку. Сам голову сломал, поэтому надеюсь на вашу помощь.
Суть проблемы такова.
У нас есть Торговец, мы к нему подходим и наводим курсор ( в этот момент у нас идет проверка условий, а точнее проверка принадлежности конкретного торговца к классу (друг, нейтрал, герой, бандит) и проверка нашей 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(_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];};
Если что, вместо цифр я вписал перменные, это нужно для дальнейшего простого конфига скрипта.
Вроде заставил скролл меню отфильтровывать по уровню 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