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


Фотография

Изменение снаряжение при респавне игрока


Лучший Ответ shaman33 , 26 April 2015 - 21:51

ГОТОВЫЙ ВАРИАНТ РЕШЕНИЯ ПРОБЛЕМЫ ПО ДАННОЙ ТЕМЕ

Чтобы всем видно было))

Итак, в init.sqf следующий код кидаем (ещё раз спасибо SteelRat):

#include "bis_fnc_saveInventory_data.inc"
 
_unitsClass = ["B_recon_F", "B_Soldier_SL_F", "B_soldier_M_F","B_soldier_LAT_F","B_medic_F"]; // тут те классы, экипировку которых заменяем

_replace = [];

{

    _replace set [count _replace, toLower(_x)];

} foreach _unitsClass;

_unitsClass = _replace;
 
if(!isDedicated) then

{



waitUntil {!isNull player}; // обязательно ждем подключения игрока, иначе будет куча недоразумений при его подключении в середине матча



    if (toLower(typeOf player) in _unitsClass) then {

        player call compile format["[_this, [missionnamespace, '%1']] call BIS_fnc_loadInventory", typeOf player];



        player addEventHandler ["Respawn",{

            (_this select 1) removeAllEventHandlers "Respawn";

            (_this select 0) call compile format["[_this, [missionnamespace, '%1']] call BIS_fnc_loadInventory", typeOf (_this select 0)];

        }];

    };



0 = [] execVM "InArsenal.sqf";   //в этом файле будет проверка на тот факт, октрыт виртуальный арсенал у игрока или нет
 
};

файл bis_fnc_saveInventory_data.inc:

bis_fnc_saveInventory_data = [

"B_recon_F",

    [    

        ["U_I_G_resistanceLeader_F", ["FirstAidKit"]],

        ["V_Rangemaster_belt", ["30Rnd_65x39_caseless_mag", "30Rnd_65x39_caseless_mag"]],

        ["B_Carryall_khk", ["HandGrenade"]],

        "",

        "",

        "Binocular",

        ["arifle_MX_ACO_pointer_F", ["30Rnd_65x39_caseless_mag"]],

        ["", []],

        ["", []],

        []

    ],

"B_Soldier_SL_F",

    [    

      // сообразите что тут

    ]

];

Про вышеописанное SteelRat писал тут

 

Файл  InArsenal.sqf:

if(!isDedicated) then  // возможно, это уже не нужно, но мне лень было проверить

{



while {true} do

{

waituntil { !isNull ( uiNamespace getVariable [ "BIS_fnc_arsenal_cam", objNull ] )};

player sidechat "Я в виртуальном арсенале";

waituntil { isNull ( uiNamespace getVariable [ "BIS_fnc_arsenal_cam", objNull ] )};

player sidechat "Я закончил менять снаряжение";



[player, [player, "inv"]] call BIS_fnc_saveInventory;

player removeAllEventHandlers "Respawn";  // возможно, тут легче вставить то, что в ините было,
                                                                      // но мне проще было по моему

};

};

И ещё пара мелочей:

в description.ext

class CfgRespawnTemplates

{

    class m_Respawn

    {

                onPlayerRespawn = "AfterPlayerRespawn.sqf";

    };

};

respawnTemplates[] = {"m_Respawn"}; 

и в AfterPlayerRespawn.sqf ещё одну строчку:

loadout = [player, [player, "inv"]] call BIS_fnc_loadInventory;

Немного потестил, вроде всё работает как надо - та снаряга, которую Вы выбрали в ВА, будет с вами и после респа, ну и при первом респе с вами будет снаряга соответствующего класса из bis_fnc_saveInventory_data.inc

P.S. Конечно, все это дело можно упростить, но мне как то было так проще, да и переделывать уже лень))

Перейти к сообщению


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

#1 OFFLINE   shaman33

shaman33

    Ефрейтор

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

Отправлено 25 April 2015 - 19:18

Добрый день/ночь/вечер/утро, форумчане!

Вопрос такой - как изменить тот набор снаряжения, с которым возрождается игрок в сетевой игре? Вопрос похож на этот, но меня интересует также, как изменить данное снаряжение после посещения виртуального арсенала (стоит ящик с VA на базе, игрок взял там крутую_пушку, побежал, умер, возродился с крутой_пушкой и пр. барахлом). Собственно, это реализовано в новой МП мисси от бисов "конечная игра", и мне бы хотелось это повторить, но не знаю как :pardon:


  • 0

#2 OFFLINE   SteelRat

SteelRat

    Полковник

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

Отправлено 25 April 2015 - 19:35

Вариант первый

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

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

 

Вариант второй, наверное более разумный

Создаёте глобальную переменную, в которую сохраняете нужные данные по игроку, когда он вылазит из ящика, есть хандлер отслеживающий этот момент

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

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

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

 

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


  • 1

#3 OFFLINE   shaman33

shaman33

    Ефрейтор

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

Отправлено 25 April 2015 - 20:20

Про InventoryClosed уже интересно, но как я понял, тут будет сохранятся инвентарь даже в том случае, если открывался... труп солдата, обычный ящик и т.п., что не так уж интересно. Можно поизвращаться, проверяя расстояние игрока до ящика с ВиртАрсеналом, но может есть более локаничный способ проверки (исходя из описания ф-и, что то типа такого

if (_this select 1 == VirtualArsenal) then ...
)??

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


  • 0

#4 OFFLINE   SteelRat

SteelRat

    Полковник

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

Отправлено 25 April 2015 - 20:33

Про InventoryClosed уже интересно, но как я понял, тут будет сохранятся инвентарь даже в том случае, если открывался... труп солдата, обычный ящик и т.п., что не так уж интересно. Можно поизвращаться, проверяя расстояние игрока до ящика с ВиртАрсеналом, но может есть более локаничный способ проверки (исходя из описания ф-и, что то типа такого

if (_this select 1 == VirtualArsenal) then ...
)??

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

 

Сударь! По поводу сохранения и загрузки инвентаря здесь на форуме уже столько раз измусолили это дело, не поленитесь полистайте.

По поводу проверок при срабатывании хандлера, естественно надо в вызываемом хандлером коде проводить проверку необходимых условий.

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

А то что в игровом процессе выглядит весьма лаконично, в коде совсем не редко измеряется десятками метров кода,


  • 0

#5 OFFLINE   SteelRat

SteelRat

    Полковник

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

Отправлено 25 April 2015 - 20:52

Вот нашёл миссию, как раз про ящик

http://arma3.ru/foru...ektami/?p=43101

 

А тут несколько способов инвентаризации

http://arma3.ru/foru...unitov/?p=32632

Вариант на который выведет ссылка, для вас я вас думаю будет самый удобоваримый)


  • 1

#6 OFFLINE   shaman33

shaman33

    Ефрейтор

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

Отправлено 26 April 2015 - 14:51

Нашел такой способ проверки на открытие/закрытие ВА:

while {true} do

{

waituntil { !isNull ( uiNamespace getVariable [ "BIS_fnc_arsenal_cam", objNull ] )};

player sidechat "Открыл арсенал";

waituntil { isNull ( uiNamespace getVariable [ "BIS_fnc_arsenal_cam", objNull ] )};

player sidechat "Закрыл арсенал";

};

На сохранение и загрузку инвентаря использовал такой код:

В код сверху:

_uniformV = uniform player;

_vestV = vest player;

_backpackV = backpack player;

_headgearV = headgear player;

_magazinesV = magazines player;

_weaponsV = weapons player;

_primaccV = primaryWeaponItems player;

_secaccV = secondaryWeaponItems player;

_sideaccV = handgunItems player;

_itemsV = items player;

_assitemsV = assignedItems player;

_gogglesV = goggles player;



_arrayEquipSave = [_uniformV,_vestV,_backpackV,_headgearV,_magazinesV,_weaponsV,_primaccV,_secaccV,_sideaccV,_itemsV,_assitemsV,_gogglesV];

player setVariable ["playerEquipment", _arrayEquipSave, false];

В файл onPlayerRespawn = "AfterrRespawn.sqf";

_array = player getVariable "playerEquipment";



_uniformV = _array select 0;

_vestV = _array select 1;

_backpackV = _array select 2;

_headgearV = _array select 3;

_magazinesV = _array select 4;

_weaponsV = _array select 5;

_primaccV = _array select 6;

_secaccV = _array select 7;

_sideaccV = _array select 8;

_itemsV = _array select 9;

_assitemsV = _array select 10;

_gogglesV = _array select 11;



_p = player;



removeAllAssignedItems _p;

removeAllItems _p;

removeAllWeapons _p;

removeVest _p;

removeUniform _p;

removeHeadgear _p;

removeBackpack _p;

removeGoggles _p;



if (_uniformV != "" ) then {removeUniform _p; _p addUniform _uniformV};

if (_vestV  != ""   ) then {removeVest _p; _p addVest _vestV};

if (_backpackV != "") then {removeBackpack _p; _p addBackpack _backpackV};

if (_headgearV != "") then {removeHeadgear _p; _p addHeadgear _headgearV};

if (_gogglesV != "" ) then {removeGoggles _p; _p addgoggles _gogglesV};

{_p addMagazine _x} forEach _magazinesV;

{_p addWeapon _x} forEach _weaponsV;

{_p addPrimaryWeaponItem _x} forEach _primaccV;

{_p addSecondaryWeaponItem _x} forEach _secaccV;

{_p addHandgunItem _x} forEach _sideaccV;

{_p addItem _x} forEach _itemsV;

{_p addItem _x} forEach _assitemsV;

{_p assignItem _x} forEach _assitemsV;

Все работает нормально, если потанцевать с бубном по поводу первого респа, но ... синие респятся абсолютно нормально, весь инвентарь точно такой как на момент выхода из ВА, а вот красные респятся с винтовками-рюкзаками-магазинами, но без униформы, т.е. в труселях. Сколько не просматривал  код, так и не смог найти причину таких фокусов.

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

 


  • 0

#7 OFFLINE   SteelRat

SteelRat

    Полковник

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

Отправлено 26 April 2015 - 20:02

 

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

 

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

В rpt файл заглядывали?


  • 0

#8 OFFLINE   SteelRat

SteelRat

    Полковник

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

Отправлено 26 April 2015 - 20:09

 

В файл onPlayerRespawn = "AfterrRespawn.sqf";

_array = player getVariable "playerEquipment";

Имейте в виду что в данной строке, вы пытаетесь получить значение не существующей переменной, у только что отспавненого нового юнита.

А тот юнит которому вы присвоили данную переменную, уже совсем не player.

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

 

Из чего следует

_newUnit = _this select 0;
_deadUnit = _this select 1;

  • 0

#9 OFFLINE   SteelRat

SteelRat

    Полковник

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

Отправлено 26 April 2015 - 20:16

PS

Просто создайте глобальную переменную, например с именем

UnitEquip

И обращайтесь уже к этой переменное без всяких заморочек с присвоением переменных объекту.


  • 0

#10 OFFLINE   shaman33

shaman33

    Ефрейтор

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

Отправлено 26 April 2015 - 21:23

 

 

В файл onPlayerRespawn = "AfterrRespawn.sqf";

_array = player getVariable "playerEquipment";

Имейте в виду что в данной строке, вы пытаетесь получить значение не существующей переменной, у только что отспавненого нового юнита.

А тот юнит которому вы присвоили данную переменную, уже совсем не player.

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

 

Из чего следует

_newUnit = _this select 0;
_deadUnit = _this select 1;

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


  • 0

#11 OFFLINE   SteelRat

SteelRat

    Полковник

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

Отправлено 26 April 2015 - 21:32

 

 

 

В файл onPlayerRespawn = "AfterrRespawn.sqf";

_array = player getVariable "playerEquipment";

Имейте в виду что в данной строке, вы пытаетесь получить значение не существующей переменной, у только что отспавненого нового юнита.

А тот юнит которому вы присвоили данную переменную, уже совсем не player.

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

 

Из чего следует

_newUnit = _this select 0;
_deadUnit = _this select 1;

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

 

Это меня и удивляет!)

 

ЗЫ

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

 

ЗЫ_2

Скриптовый язык SQF очень таки быстр на исполнение, стоит поблагодарить БИСов за такой подарок, и исходя из этого так же можно вполне словить глюков, от черезмерной быстроты), я бы по рекомендовал всё таки оформить по понятиям).


Сообщение отредактировал SteelRat: 26 April 2015 - 21:41

  • 0

#12 OFFLINE   shaman33

shaman33

    Ефрейтор

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

Отправлено 26 April 2015 - 21:51   Лучший Ответ

ГОТОВЫЙ ВАРИАНТ РЕШЕНИЯ ПРОБЛЕМЫ ПО ДАННОЙ ТЕМЕ

Чтобы всем видно было))

Итак, в init.sqf следующий код кидаем (ещё раз спасибо SteelRat):

#include "bis_fnc_saveInventory_data.inc"
 
_unitsClass = ["B_recon_F", "B_Soldier_SL_F", "B_soldier_M_F","B_soldier_LAT_F","B_medic_F"]; // тут те классы, экипировку которых заменяем

_replace = [];

{

    _replace set [count _replace, toLower(_x)];

} foreach _unitsClass;

_unitsClass = _replace;
 
if(!isDedicated) then

{



waitUntil {!isNull player}; // обязательно ждем подключения игрока, иначе будет куча недоразумений при его подключении в середине матча



    if (toLower(typeOf player) in _unitsClass) then {

        player call compile format["[_this, [missionnamespace, '%1']] call BIS_fnc_loadInventory", typeOf player];



        player addEventHandler ["Respawn",{

            (_this select 1) removeAllEventHandlers "Respawn";

            (_this select 0) call compile format["[_this, [missionnamespace, '%1']] call BIS_fnc_loadInventory", typeOf (_this select 0)];

        }];

    };



0 = [] execVM "InArsenal.sqf";   //в этом файле будет проверка на тот факт, октрыт виртуальный арсенал у игрока или нет
 
};

файл bis_fnc_saveInventory_data.inc:

bis_fnc_saveInventory_data = [

"B_recon_F",

    [    

        ["U_I_G_resistanceLeader_F", ["FirstAidKit"]],

        ["V_Rangemaster_belt", ["30Rnd_65x39_caseless_mag", "30Rnd_65x39_caseless_mag"]],

        ["B_Carryall_khk", ["HandGrenade"]],

        "",

        "",

        "Binocular",

        ["arifle_MX_ACO_pointer_F", ["30Rnd_65x39_caseless_mag"]],

        ["", []],

        ["", []],

        []

    ],

"B_Soldier_SL_F",

    [    

      // сообразите что тут

    ]

];

Про вышеописанное SteelRat писал тут

 

Файл  InArsenal.sqf:

if(!isDedicated) then  // возможно, это уже не нужно, но мне лень было проверить

{



while {true} do

{

waituntil { !isNull ( uiNamespace getVariable [ "BIS_fnc_arsenal_cam", objNull ] )};

player sidechat "Я в виртуальном арсенале";

waituntil { isNull ( uiNamespace getVariable [ "BIS_fnc_arsenal_cam", objNull ] )};

player sidechat "Я закончил менять снаряжение";



[player, [player, "inv"]] call BIS_fnc_saveInventory;

player removeAllEventHandlers "Respawn";  // возможно, тут легче вставить то, что в ините было,
                                                                      // но мне проще было по моему

};

};

И ещё пара мелочей:

в description.ext

class CfgRespawnTemplates

{

    class m_Respawn

    {

                onPlayerRespawn = "AfterPlayerRespawn.sqf";

    };

};

respawnTemplates[] = {"m_Respawn"}; 

и в AfterPlayerRespawn.sqf ещё одну строчку:

loadout = [player, [player, "inv"]] call BIS_fnc_loadInventory;

Немного потестил, вроде всё работает как надо - та снаряга, которую Вы выбрали в ВА, будет с вами и после респа, ну и при первом респе с вами будет снаряга соответствующего класса из bis_fnc_saveInventory_data.inc

P.S. Конечно, все это дело можно упростить, но мне как то было так проще, да и переделывать уже лень))


Сообщение отредактировал shaman33: 28 April 2015 - 14:08

  • 0

#13 OFFLINE   SteelRat

SteelRat

    Полковник

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

Отправлено 27 April 2015 - 01:12

 

P.S. Конечно, все это дело можно упростить, но мне как то было так проще, да и переделывать уже лень))

Нет предела совершенству). Будет чем на досуге заняться)


  • 1




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