Перейти к содержимому


Фотография

BIS_fnc_loadInventory\BIS_fnc_saveInventory


Лучший Ответ NoNameUltima , 28 April 2016 - 22:26

Проблема исчерпана, сделал сохранение...

У меня БД своя. Но без труда можно перенести на SQL\Redis и т.п. кому, что больше нравится.

//    Массив [ [UID, [аксессуары]] ]
Ultima_Server_Array_Fix_Saved_Accessories    =    [];

//    Получение массива текущих аксессуаров игрока. Возвращает массив текущих аксессуаров.
Ultima_Server_Function_Player_Fix_Get_Exists_Accessories_Array    =
    {
        Private ["_player", "_accessories"];
        _player    =    (_this select 0);
        _accessories    =    [];
        {
            {
                if ( (typeName _x) == "STRING" ) then
                    {
                        if ( (["muzzle_", _x] call BIS_fnc_inString) || (["optic_", _x] call BIS_fnc_inString) || (["acc_", _x] call BIS_fnc_inString) || (["bipod_", _x] call BIS_fnc_inString) ) then
                            {_accessories set [(count _accessories), _x];};
                    };
            } forEach _x;
        } forEach (weaponsItems _player);
        {
            if ( (["muzzle_", _x] call BIS_fnc_inString) || (["optic_", _x] call BIS_fnc_inString) || (["acc_", _x] call BIS_fnc_inString) || (["bipod_", _x] call BIS_fnc_inString) ) then
                {_accessories set [(count _accessories), _x];};
        } forEach (items _player);
        _accessories
    };
diag_log("[#Ultima]: [Компиляция]: Ultima_Server_Function_Player_Fix_Get_Exists_Accessories_Array");    
//    Сравнение массивов - текущих аксессуаров игрока, и сохраненных. Возвращает массив недостающих аксессуаров.
Ultima_Server_Function_Player_Fix_Get_Lost_Accessories_Array    =
    {
        Private ["_player", "_saved_accessories", "_load_accessories", "_sa_counter", "_la_counter"];
        _player             =    (_this select 0);
        _saved_accessories    =    (_this select 1);
        _load_accessories    =    [_player] call Ultima_Server_Function_Player_Fix_Get_Exists_Accessories_Array;    
        for "_sa_counter" from ((count _saved_accessories) - 1) to 0 step -1 do
            {
                for "_la_counter" from ((count _load_accessories) - 1) to 0 step -1 do
                    {
                        if ( (_saved_accessories select _sa_counter) == (_load_accessories select _la_counter) ) exitWith
                            {
                                _load_accessories set [_la_counter, "DELETE"];
                                _load_accessories    =    _load_accessories - ["DELETE"];
                                _saved_accessories set [_sa_counter, "DELETE"];
                                _saved_accessories    =    _saved_accessories - ["DELETE"];
                            };
                    };
            };
        _saved_accessories
    };
diag_log("[#Ultima]: [Компиляция]: Ultima_Server_Function_Player_Fix_Get_Lost_Accessories_Array");    
//    Процедура выдачи аксессуара.
Ultima_Server_Procedure_Player_Fix_Give_Accessorie    =
    {
        Private ["_player", "_accessorie", "_holder"];
        _player        =    (_this select 0);
        _accessorie    =    (_this select 1);
        if ( _player canAddItemToUniform [_accessorie, 1] ) exitWith
            {_player addItemToUniform _accessorie;};
        if ( _player canAddItemToVest [_accessorie, 1] ) exitWith
            {_player addItemToVest _accessorie;};
        if ( _player canAddItemToBackpack [_accessorie, 1] ) exitWith
            {_player addItemToBackpack _accessorie;};
        diag_log(format["[#Ultima]: [Диагностика]: [Ultima_Server_Procedure_Player_Fix_Give_Accessorie]: Добавление в контейнеры игрока не удалось - создан GroundWeaponHolder в позиции: %1", (position _player)]);
        _holder = createVehicle ["GroundWeaponHolder", (position _player), [], 0, "CAN_COLLIDE"];
        _holder addItemCargoGlobal [_accessorie, 1];
    };
diag_log("[#Ultima]: [Компиляция]: Ultima_Server_Procedure_Player_Fix_Give_Accessorie");    
//    Процедура выдачи недостающих аксессуаров(В setup игрока)
Ultima_Server_Procedure_Player_Fix_Give_Lost_Accessories    =
    {
        Private ["_player", "_uid"];
        _player    =    (_this select 0);
        _uid    =    getPlayerUID _player;
        {
            if ( (_x select 0) == _uid ) exitWith
                {
                    {
                        [_player, _x] call Ultima_Server_Procedure_Player_Fix_Give_Accessorie;
                    } forEach ([_player, (_x select 1)] call Ultima_Server_Function_Player_Fix_Get_Lost_Accessories_Array);
                };
        } forEach Ultima_Server_Array_Fix_Saved_Accessories;
    };
diag_log("[#Ultima]: [Компиляция]: Ultima_Server_Procedure_Player_Fix_Give_Lost_Accessories");    
//    Синхронизация с БД(В синхронизацию игрока)
Ultima_Server_Procedure_Player_Fix_BD_Synchronize_Accessories    =
    {
        Private ["_player", "_uid", "_index", "_rec", "_accessories"];
        _player    =    (_this select 0);
        if !(alive _player) exitWith {};
        _uid    =    getPlayerUID _player;
        _accessories    =    [_player] call Ultima_Server_Function_Player_Fix_Get_Exists_Accessories_Array;
        {
            if ( (_x select 0) == _uid ) exitWith
                {_index    =    _forEachIndex;};
        } forEach Ultima_Server_Array_Fix_Saved_Accessories;
        _rec    =    [_uid, _accessories];
        if !(isNil "_index") then
            {Ultima_Server_Array_Fix_Saved_Accessories set [_forEachIndex, _rec];}
        else
            {Ultima_Server_Array_Fix_Saved_Accessories set [(count Ultima_Server_Array_Fix_Saved_Accessories), _rec];};
        Ultima_Server_String_BD_DLL_Name callExtension (format ["9|LOST_ACCESSORIES|%1|%2", _uid, _rec]);
    };
diag_log("[#Ultima]: [Компиляция]: Ultima_Server_Procedure_Player_Fix_BD_Synchronize_Accessories");
//    Загрузка массива сохраненных аксессуаров из БД
Private ["_uid_count", "_i", "_uid", "_tmp"];
_uid_count    =    parseNumber(Ultima_Server_String_BD_DLL_Name callExtension "2|LOST_ACCESSORIES");
for "_i" from 0 to _uid_count do
    {
        _uid    =    Ultima_Server_String_BD_DLL_Name callExtension format["4|LOST_ACCESSORIES|%1", _i];
        _tmp    =    Ultima_Server_String_BD_DLL_Name callExtension format["10|LOST_ACCESSORIES|%1", _uid];
        _tmp    =    call compile _tmp;
        Ultima_Server_Array_Fix_Saved_Accessories set [(count Ultima_Server_Array_Fix_Saved_Accessories), _tmp];
    };
diag_log(format["[#Ultima]: [БД]: Загружено записей в массив Ultima_Server_Array_Fix_Saved_Accessories: %1", (count Ultima_Server_Array_Fix_Saved_Accessories)]);
Перейти к сообщению


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 16

#1 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 сообщений
  • Откуда:SPB

Отправлено 26 April 2016 - 13:06

При использовании бисовских функций, сохранения инвентаря, не сохраняются аксессуары оружия, если оно - оружие, лежит в инвентаре(не в руках). Например -  цепляем глушитель на ствол, кладем ствол в рюкзак. Итог - в массиве возвращаемом BIS_fnc_saveInventory глушителя нет...

 

Может кто менял стандартные БИС функции сохранения\загрузки с учетом данных ньюансов?

 


  • 0

#2 OFFLINE   SteelRat

SteelRat

    Полковник

  • Пользователи
  • 3241 сообщений
  • Откуда:РФ

Отправлено 27 April 2016 - 19:00

Простого способа нет. Что бы сохранилось правильно пушку надо разобрать, а после сложить в инвентарь.

По идее, можно попробовать реализовать сохранение, но это уже будут не БЕСовские функции, точнее их придётся редактировать.

 

Вот тут

https://arma3.ru/for...obekta/?p=63778

почти про тоже самое.

Но гражданин оказался не очень собеседник), я забил).

 

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

Но! При восстановлении инвентаря вы не сможете опять это повесить на пушки, просто тупо бросить в инвентарь.

Ну, или очень уж через жопу.


  • 0

#3 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 сообщений
  • Откуда:SPB

Отправлено 27 April 2016 - 19:22


с помощью перечисленных команд получить то что висит на пушках лежащих в инвентаре

Каких команд?)

Посмотрел ветку по ссылке, - не нашел команды которая получит, то что висит на пушке и при этом сама пушка лежит в рюкзаке\разгрузке\униформе.

 

Пример(MP) -

Игрок 1, открывает рюкзак игрока 2, и кладет игроку 2, в рюкзак пистолет с глушителем.

...

Какой функцией можно получить данные об этой пушке в рюкзаке игрока 2, с учетом аксессуаров?

Может быть какое то событие добавить, которое ПЕРЕД тем как пушка упадет в рюкзак:

получит аксессуары на пушке

снимет с нее аксессуары

добавит их отдельно в контейнер

?

 

пробовал добавить put

test_Put    =    
    {
        Private ["_unit", "_container", "_item", "_tmp"];
        diag_log(format["Процедура PUT: %1", _this]);
        _unit        =    (_this select 0);
        _container    =    (_this select 1);
        _item        =    (_this select 2);
        diag_log(format["_unit: %1, _container: %2, _item: %3, _containerTypeOf: %4", _unit, _container, _item, (typeOf _container)]);
        if ([_item] call Ultima_Client_Function_Get_Object_Config == "cfgWeapons") then
            {
                _tmp    =    player weaponAccessories _item;
                diag_log(format["weaponAccessories: %1 for _item: %2", _tmp, _item]);
            };
    };
player addEventHandler ["Put", {_this call test_Put;}];

аксессуары не показывает(

и так

_tmp    =    getWeaponCargo uniformContainer player;
diag_log(format["getWeaponCargo uniformContainer: %1", _tmp]);

и так

{
   if ([_x] call Ultima_Client_Function_Get_Object_Config == "cfgWeapons") then
     {
       _tmp    =    player weaponAccessories _x;
       diag_log(format["weaponAccessories: %1 for _x: %2", _tmp, _x]);
      };
} forEach _uniformItems;

  • 0

#4 OFFLINE   SteelRat

SteelRat

    Полковник

  • Пользователи
  • 3241 сообщений
  • Откуда:РФ

Отправлено 27 April 2016 - 22:10

 

Каких команд?)

Посмотрел ветку по ссылке, - не нашел команды которая получит, то что висит на пушке и при этом сама пушка лежит в рюкзаке\разгрузке\униформе.

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

Пожалуйста Войдите или Зарегистрируйтесь чтобы увидеть скрытое содержание

 

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

Пожалуйста Войдите или Зарегистрируйтесь чтобы увидеть скрытое содержание

_items = weaponsItemsCargo (backpackContainer player);

Какой функцией можно получить данные об этой пушке в рюкзаке игрока 2, с учетом аксессуаров?

 

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


 

пробовал добавить put

Этим вы получите всего лишь имя класса предмета, а не сам предмет.


  • 0

#5 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 сообщений
  • Откуда:SPB

Отправлено 27 April 2016 - 22:13


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

 

Тогда с другого боку...

 

При перетаскивании объекта в инвентаре, должно быть событие для контролов инвентаря - drag&drop (т.е. тот скрипт который срабатывает на контроле инвентаря - при зажатии, перетаскивании, и отпускании кнопки мышки) - магазин же "отцепляется", от пушки, и сама пушка перекидывается в другой контейнер - где то должен быть этот скрипт) или это магия)))


  • 0

#6 OFFLINE   SteelRat

SteelRat

    Полковник

  • Пользователи
  • 3241 сообщений
  • Откуда:РФ

Отправлено 27 April 2016 - 22:23

 


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

 

Тогда с другого боку...

 

При перетаскивании объекта в инвентаре, должно быть событие для контролов инвентаря - drag&drop (т.е. тот скрипт который срабатывает на контроле инвентаря - при зажатии, перетаскивании, и отпускании кнопки мышки) - магазин же "отцепляется", от пушки, и сама пушка перекидывается в другой контейнер - где то должен быть этот скрипт) или это магия)))

 

 

 

Этим вы получите всего лишь имя класса предмета, а не сам предмет.

 

далее

 

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

 

Это внутри движка.

 

И очень похоже на

или это магия)))

 


ЗЫ

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


  • 0

#7 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 сообщений
  • Откуда:SPB

Отправлено 27 April 2016 - 22:26

 

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

 

Это внутри движка.

 

И очень похоже на

или это магия)))

 

 

Тогда видимо придется переписать инвентарь на собственный...

 

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

 

Есть примеры перекрытия диалога инвентаря ? и где если не секрет лежит оригинал в а3 аддонах?


Сообщение отредактировал NoNameUltima: 27 April 2016 - 22:27

  • 0

#8 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 сообщений
  • Откуда:SPB

Отправлено 27 April 2016 - 22:33

Нашел волшебную функцию)

weaponsItems

показывает что установлено на пушке, даже если она в рюкзаке\униформе и т.п.

 

это немного упрощает задачу)

 

P.S.

После недолгих раздумий, "родил" тупое, но простое решение -

При коннекте(релоге) игрока, подсчитать аксессуары от - BIS_fnc_loadInventory, и сравнить с отдельно сохраненным массивом weaponsItems, - тех что нехватает в BIS_fnc_loadInventory, - выдать отдельно)


Сообщение отредактировал NoNameUltima: 27 April 2016 - 22:38

  • 0

#9 OFFLINE   SteelRat

SteelRat

    Полковник

  • Пользователи
  • 3241 сообщений
  • Откуда:РФ

Отправлено 27 April 2016 - 22:41

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

 

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

А может быть и сможете, если хватит таланта сделать тоже самое что сделали БЕСы, да ещё с помощью одних лишь скриптовых команд)

 

 

Есть примеры перекрытия диалога инвентаря ? и где если не секрет лежит оригинал в а3 аддонах?

ui_f.pbo

класс RscDisplayInventory


 

Нашел волшебную функцию)

weaponsItems

показывает что установлено на пушке, даже если она в рюкзаке\униформе и т.п.

Вы считаете что БЕСы просто так сделали две команды? Для персонажа и контейнеров?


  • 0

#10 OFFLINE   SteelRat

SteelRat

    Полковник

  • Пользователи
  • 3241 сообщений
  • Откуда:РФ

Отправлено 27 April 2016 - 22:51

Хотя, похоже можно обойтись и этой командой, вроде как правильно работает.


  • 0

#11 OFFLINE   SteelRat

SteelRat

    Полковник

  • Пользователи
  • 3241 сообщений
  • Откуда:РФ

Отправлено 27 April 2016 - 22:56

 

При коннекте(релоге) игрока, подсчитать аксессуары от - BIS_fnc_loadInventory, и сравнить с отдельно сохраненным массивом weaponsItems, - тех что нехватает в BIS_fnc_loadInventory, - выдать отдельно)

Тут есть один нюанс, насколько он важен в вашем случае мне не ведомо.

Так вот, если при сохранении перса, в инвентаре будут в наличии не полные магазины, то после восстановления состояния персонажа эти магазины станут полными. БЕСовские функции не учитывают кол-по патронов в магазинах, по сути это не косяк, по ванили этого и не нужно.


  • 0

#12 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 сообщений
  • Откуда:SPB

Отправлено 27 April 2016 - 23:08

 

 

При коннекте(релоге) игрока, подсчитать аксессуары от - BIS_fnc_loadInventory, и сравнить с отдельно сохраненным массивом weaponsItems, - тех что нехватает в BIS_fnc_loadInventory, - выдать отдельно)

Тут есть один нюанс, насколько он важен в вашем случае мне не ведомо.

Так вот, если при сохранении перса, в инвентаре будут в наличии не полные магазины, то после восстановления состояния персонажа эти магазины станут полными. БЕСовские функции не учитывают кол-по патронов в магазинах, по сути это не косяк, по ванили этого и не нужно.

 

Это уже мелочи.

Пока подумаю, как лучше сделать...


Вы видимо так и не уловили того что я пылался донести, вы не сможете сделать подобные пируеты через GUI инвентаря. А может быть и сможете, если хватит таланта сделать тоже самое что сделали БЕСы, да ещё с помощью одних лишь скриптовых команд)

Все таки перекрыть инвентарь более красиво, и по сути там надо добавить несколько событий , особых сложностей не вижу пока -

 

*такое же создать для вторичного оружия, и для слота под РПГ(ну или добавить переменную, для определения)

FixUniformAdd    =
    {
        if (isNil "TMP_Weapon") exitWith {};
        if (isNull TMP_Weapon) exitWith {};
        player removeWeapon TMP_Weapon;
        addItemToUniform TMP_Weapon;
        {
            addItemToUniform _x;
        } forEach TMP_Accessories;
        TMP_Accessories    =    nil;
        TMP_Weapon        =    nil;
    };
    
...
повесить на контролы слотов оружия события зажимания кнопки мышки, и запоминать - что за оружие в слоте и что на нем висит

_ctrlPrimaryWeapon ctrlAddEventHandler ["MouseButtonDown", {TMP_Weapon    =    (primaryWeapon player); TMP_Accessories    =    (primaryWeaponItems player);}];

...

 

повесить на контролы униформы, разгрузки, рюкзака события отпускания кнопки мышки, с вызовом добавления оружия при перетаскивании(если его перетащили)
_ctrlUniform ctrlAddEventHandler ["MouseButtonUp", {[] call FixUniformAdd;}];

...
на все остальные контролы повесить событие уничтожения переменных
_ctrlX ctrlAddEventHandler ["MouseButtonDown", {TMP_Weapon    =    nil; TMP_Accessories    =    nil;}];

 

Ну как то так...


  • 0

#13 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 сообщений
  • Откуда:SPB

Отправлено 28 April 2016 - 14:39

я в раздумьях...

 

1. SlotAbstract -

Пришлось сделать базовый класс, для слотов, т.к. чудо - если в базовом классе создать событие onMouseButtonDown, и в наследнике перекрыть данное событие т.е. так же создать onMouseButtonDown, то сработает сначала событие onMouseButtonDown - наследника, а потом onMouseButtonDown базового класса))))))) - т.е. события просто встанут в стек) хотя явно перекрыты) Это конечно "очень круто" иметь два события)) так можно и 10 событий от баз прицепом тащить)))))

 

2.

class UniformSlot : SlotAbstract
    {
        idc          =    6331;
        x            =    "15.35 * ( ((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)";
        y            =    "2.5 *     ( (((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
        w            =    "3 * ( ((safezoneW / safezoneH) min 1.2) / 40)";
        h            =    "3 * ( (((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
        colorText[]  =    {0, 0, 0, 0.5};
        //    Работает
        //onMouseButtonDown    =    "TMP_Weapon    =    nil; TMP_Accessories    = nil;";
        //    Не работает, если onMouseButtonDown был над другим контролом
        onMouseButtonUp        =    "diag_log('UniformSlot onMouseButtonUp');";
        //    Не работает, если onMouseButtonDown был над другим контролом
        onButtonUp             =    "diag_log('UniformSlot onButtonUp');";
        //    Работает - выдает контрол 6331
        //onMouseHolding      =    "diag_log(format['onMouseHolding ctrl: %1', _this)";
    };

в комментарии подписал, что и как...

Не понятно, почему onMouseButtonUp не срабатывает при перетаскивании элемента мышкой. Я поначалу подумал было, что под мышкой создается некий контрол, который перекрывает контрол слота униформы, и onMouseButtonUp срабатывает на нем, но - включаем onMouseHolding - выдает 6331, т.е. тот самый необходимый контрол униформы(в данном случае).

 

При этом, если просто кликнуть по слоту униформы, то события onMouseButtonUp срабатывают на отлично.

 

Или я тормаз, или это в богемии кто то "шибко умный"....


Сообщение отредактировал NoNameUltima: 28 April 2016 - 14:41

  • 0

#14 OFFLINE   vlad333000

vlad333000

    Полковник

  • Пользователи
  • 3224 сообщений
  • Откуда:Кострома

Отправлено 28 April 2016 - 15:12

NoNameUltima, что бы сработал UP, сначала должен сработать DOWN на том же контроле. Решить эту х*йню можно созданием гигантского невидимого контрола поверх всего и вся, который уже будет чёкать координаты мышки и контролов (Благо их узнать не трудно)
  • 0

#15 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 сообщений
  • Откуда:SPB

Отправлено 28 April 2016 - 16:41

Оставляю кому интересно, что получилось...

RscDisplayInventory

 

Сама процедура

FixUniformAdd

 

При перетаскивании из оружейных слотов пушек с аксессуарами, в слоты - униформа\разгрузка\рюкзак - оружие удаляется, и добавляется разобранным. Если нет место под аксессуар - аксессуар падает под ноги.

 

Не решает проблему с перетаскиванием оружия с аксессуарами из техники, и т.п.

Дальше копатся лень.

 

Сделаю проще - буду сохранять массив с аксессуарами отдельно.


NoNameUltima, что бы сработал UP, сначала должен сработать DOWN на том же контроле. Решить эту х*йню можно созданием гигантского невидимого контрола поверх всего и вся, который уже будет чёкать координаты мышки и контролов (Благо их узнать не трудно)

Не знаю, как там у богемии, - в нормальных языках идет иерархия exit\leave - up\down - drag&drop

Видимо у них собственное видение всего это, т.к. событие АП не срабатывает вообще(от слова - СОВСЕМ), если есть событие DROP(вернее не событие даже, т.к. его то не было изначально! а банальный drag - перетаскивание - проще говоря, если потянули зажатую кнопку мышки над контролом, то онМаусАп можно не ждать, когда отпустим кнопку.).

Выше скинул то что получилось... Дальше мучатся не охота.


Сообщение отредактировал NoNameUltima: 28 April 2016 - 16:48

  • 0

#16 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 сообщений
  • Откуда:SPB

Отправлено 28 April 2016 - 22:26   Лучший Ответ

Проблема исчерпана, сделал сохранение...

У меня БД своя. Но без труда можно перенести на SQL\Redis и т.п. кому, что больше нравится.

//    Массив [ [UID, [аксессуары]] ]
Ultima_Server_Array_Fix_Saved_Accessories    =    [];

//    Получение массива текущих аксессуаров игрока. Возвращает массив текущих аксессуаров.
Ultima_Server_Function_Player_Fix_Get_Exists_Accessories_Array    =
    {
        Private ["_player", "_accessories"];
        _player    =    (_this select 0);
        _accessories    =    [];
        {
            {
                if ( (typeName _x) == "STRING" ) then
                    {
                        if ( (["muzzle_", _x] call BIS_fnc_inString) || (["optic_", _x] call BIS_fnc_inString) || (["acc_", _x] call BIS_fnc_inString) || (["bipod_", _x] call BIS_fnc_inString) ) then
                            {_accessories set [(count _accessories), _x];};
                    };
            } forEach _x;
        } forEach (weaponsItems _player);
        {
            if ( (["muzzle_", _x] call BIS_fnc_inString) || (["optic_", _x] call BIS_fnc_inString) || (["acc_", _x] call BIS_fnc_inString) || (["bipod_", _x] call BIS_fnc_inString) ) then
                {_accessories set [(count _accessories), _x];};
        } forEach (items _player);
        _accessories
    };
diag_log("[#Ultima]: [Компиляция]: Ultima_Server_Function_Player_Fix_Get_Exists_Accessories_Array");    
//    Сравнение массивов - текущих аксессуаров игрока, и сохраненных. Возвращает массив недостающих аксессуаров.
Ultima_Server_Function_Player_Fix_Get_Lost_Accessories_Array    =
    {
        Private ["_player", "_saved_accessories", "_load_accessories", "_sa_counter", "_la_counter"];
        _player             =    (_this select 0);
        _saved_accessories    =    (_this select 1);
        _load_accessories    =    [_player] call Ultima_Server_Function_Player_Fix_Get_Exists_Accessories_Array;    
        for "_sa_counter" from ((count _saved_accessories) - 1) to 0 step -1 do
            {
                for "_la_counter" from ((count _load_accessories) - 1) to 0 step -1 do
                    {
                        if ( (_saved_accessories select _sa_counter) == (_load_accessories select _la_counter) ) exitWith
                            {
                                _load_accessories set [_la_counter, "DELETE"];
                                _load_accessories    =    _load_accessories - ["DELETE"];
                                _saved_accessories set [_sa_counter, "DELETE"];
                                _saved_accessories    =    _saved_accessories - ["DELETE"];
                            };
                    };
            };
        _saved_accessories
    };
diag_log("[#Ultima]: [Компиляция]: Ultima_Server_Function_Player_Fix_Get_Lost_Accessories_Array");    
//    Процедура выдачи аксессуара.
Ultima_Server_Procedure_Player_Fix_Give_Accessorie    =
    {
        Private ["_player", "_accessorie", "_holder"];
        _player        =    (_this select 0);
        _accessorie    =    (_this select 1);
        if ( _player canAddItemToUniform [_accessorie, 1] ) exitWith
            {_player addItemToUniform _accessorie;};
        if ( _player canAddItemToVest [_accessorie, 1] ) exitWith
            {_player addItemToVest _accessorie;};
        if ( _player canAddItemToBackpack [_accessorie, 1] ) exitWith
            {_player addItemToBackpack _accessorie;};
        diag_log(format["[#Ultima]: [Диагностика]: [Ultima_Server_Procedure_Player_Fix_Give_Accessorie]: Добавление в контейнеры игрока не удалось - создан GroundWeaponHolder в позиции: %1", (position _player)]);
        _holder = createVehicle ["GroundWeaponHolder", (position _player), [], 0, "CAN_COLLIDE"];
        _holder addItemCargoGlobal [_accessorie, 1];
    };
diag_log("[#Ultima]: [Компиляция]: Ultima_Server_Procedure_Player_Fix_Give_Accessorie");    
//    Процедура выдачи недостающих аксессуаров(В setup игрока)
Ultima_Server_Procedure_Player_Fix_Give_Lost_Accessories    =
    {
        Private ["_player", "_uid"];
        _player    =    (_this select 0);
        _uid    =    getPlayerUID _player;
        {
            if ( (_x select 0) == _uid ) exitWith
                {
                    {
                        [_player, _x] call Ultima_Server_Procedure_Player_Fix_Give_Accessorie;
                    } forEach ([_player, (_x select 1)] call Ultima_Server_Function_Player_Fix_Get_Lost_Accessories_Array);
                };
        } forEach Ultima_Server_Array_Fix_Saved_Accessories;
    };
diag_log("[#Ultima]: [Компиляция]: Ultima_Server_Procedure_Player_Fix_Give_Lost_Accessories");    
//    Синхронизация с БД(В синхронизацию игрока)
Ultima_Server_Procedure_Player_Fix_BD_Synchronize_Accessories    =
    {
        Private ["_player", "_uid", "_index", "_rec", "_accessories"];
        _player    =    (_this select 0);
        if !(alive _player) exitWith {};
        _uid    =    getPlayerUID _player;
        _accessories    =    [_player] call Ultima_Server_Function_Player_Fix_Get_Exists_Accessories_Array;
        {
            if ( (_x select 0) == _uid ) exitWith
                {_index    =    _forEachIndex;};
        } forEach Ultima_Server_Array_Fix_Saved_Accessories;
        _rec    =    [_uid, _accessories];
        if !(isNil "_index") then
            {Ultima_Server_Array_Fix_Saved_Accessories set [_forEachIndex, _rec];}
        else
            {Ultima_Server_Array_Fix_Saved_Accessories set [(count Ultima_Server_Array_Fix_Saved_Accessories), _rec];};
        Ultima_Server_String_BD_DLL_Name callExtension (format ["9|LOST_ACCESSORIES|%1|%2", _uid, _rec]);
    };
diag_log("[#Ultima]: [Компиляция]: Ultima_Server_Procedure_Player_Fix_BD_Synchronize_Accessories");
//    Загрузка массива сохраненных аксессуаров из БД
Private ["_uid_count", "_i", "_uid", "_tmp"];
_uid_count    =    parseNumber(Ultima_Server_String_BD_DLL_Name callExtension "2|LOST_ACCESSORIES");
for "_i" from 0 to _uid_count do
    {
        _uid    =    Ultima_Server_String_BD_DLL_Name callExtension format["4|LOST_ACCESSORIES|%1", _i];
        _tmp    =    Ultima_Server_String_BD_DLL_Name callExtension format["10|LOST_ACCESSORIES|%1", _uid];
        _tmp    =    call compile _tmp;
        Ultima_Server_Array_Fix_Saved_Accessories set [(count Ultima_Server_Array_Fix_Saved_Accessories), _tmp];
    };
diag_log(format["[#Ultima]: [БД]: Загружено записей в массив Ultima_Server_Array_Fix_Saved_Accessories: %1", (count Ultima_Server_Array_Fix_Saved_Accessories)]);

Сообщение отредактировал NoNameUltima: 28 April 2016 - 22:32

  • 0

#17 OFFLINE   NoNameUltima

NoNameUltima

    Сержант

  • Пользователи
  • 189 сообщений
  • Откуда:SPB

Отправлено 02 May 2016 - 14:25

Дополню немного:

Мб у кого то есть доступ к баг трекеру A3 -

В BIS_fnc_loadInventory, а конкретно в файле функции:

fn_loadinventory.sqf

переменная _object не является локальной.

 

Пример бага:

Private ["_object", "_inv"];
_object = "test";
_inv    = [player, [ObjNull, "backup"]] call BIS_fnc_saveInventory;
[player, [_inv]] call BIS_fnc_loadInventory;
diag_log(format["_OBJECT: %1", _object]);

в _object будет указатель на игрока - player


  • 0




Яндекс.Метрика