Перейти к содержанию
Авторизация  
Hardtmuth

Создание инвентарного комплекса

Рекомендуемые сообщения

 

Создание инвентарного комплекса

Автор: FantomICW

Перед тем, как начать урок, я хочу сказать, что скриптовой частью я обязан товарищу Ховану и СГМ моду. Именно благодаря их скриптам я нашел способ сделать подобную вещь! Огромное им спасибо!
А теперь перейдем к уроку.

Введение
Возможно, вы когда-нибудь задумывались над вопросом создания предмета, из при использовании которого в инвентарь будут выпадать сразу несколько других, как, например, универсальный медкомплект. Долго думая, я понял, что такого эффекта можно достичь используя коллбеки на использовании предметов.
Что такое "коллбек"? Если коротко, - это что-то в роде скрипта инфопорции. Однако, коллбек может работать как единожды, так и постоянно: при подборе предметов, при их использовании, при выстреле, при попадению по нпс и так далее. Нас интересует коллбек использования предмета, который будет работать постоянно.

Спойлер
  • configs/misc/items.ltx
  • configs/text/rus/st_items_equipment.ltx
  • scripts/_g.script
  • scripts/bind_stalker.script
  • scripts/my_callbacks.script
Спойлер

Часть I - создаем предмет:

1. Откроем items.ltx и скопируем секцию какого-нибудь бустера. Вставим новую секцию где-нибудь в это-же файле.
2. Настроим его так, как нам этого захочется.


[medkit_complex]:booster
$spawn     = "food and drugs\medkit_complex"
visual    = dynamics\devices\dev_aptechka\dev_aptechka_mid.ogf
description   = st_medkit_complex_desc
inv_name   = st_medkit_complex
inv_name_short          = st_medkit_complex
inv_weight   = 1.8
inv_grid_width     = 2
inv_grid_height    = 2
inv_grid_x         = 10
inv_grid_y         = 27
cost    = 30000
attach_angle_offset  = 0.440521, 1.378287, -0.644026
attach_position_offset         = 0.104196, -0.010821, 0.076969
attach_bone_name  = bip01_r_hand
auto_attach   = false
bone_name   = bip01_r_hand
position_offset   = 0.0,0.0,0.0
angle_offset   = 1.570790,1.570790,3.92699
use_sound   = interface\inv_medkit

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

3. В st_items_equipment.ltx создаем описание и название предмета:


<string id="st_medkit_complex">
                          <text>Универсальный медкомплект</text>
                         </string>
                         <string id="st_medkit_complex_desc">
                          <text>Специальный медкомплектЮ, разработаный для спецслужб в Зоне. Включает в себя все основные медикаменты.</text>
                         </string>

На этом с конфигами все.

Часть II - создаем коллбеки:

1. Руководствуясь материалом, взятым у Хована, мы создаем файл my_callbacks.script в папке scripts.
2. Наполняем его следующим образом:


function on_use_item(sect)
--Переменные
local actor=db.actor
local item_name=sect:section()
local actor_pos=db.actor:position()
local active_slot=db.actor:active_slot()
local active_item=db.actor:active_item()
local pistol_in_slot=db.actor:item_in_slot(2)
local rifle_in_slot=db.actor:item_in_slot(3)
local outfit_in_slot=db.actor:item_in_slot(7)
local helm_in_slot=db.actor:item_in_slot(12)
--Коллбеки
if item_name=="medkit_complex" then
give_object_to_actor("drug_anabiotic")
give_object_to_actor("antirad")
give_object_to_actor("bandage")
give_object_to_actor("drug_radioprotector")
give_object_to_actor("drug_antidot")
give_object_to_actor("drug_psy_blockade")
give_object_to_actor("drug_coagulant")
give_object_to_actor("drug_booster")
end
end

give_object_to_actor - как-раз и есть скрипт выдачи ГГ предмета, опираясь на коллбек. В скобках название предмета. Вообщем, продолжаем так-же, и добавляем, что хотим. Надеюсь, принцип ясен.

2. Зарегистрируем наш файл в bind_stalker.script. Там находим функцию function actor_binder:use_inventory_item(obj) и под вторым end прописываем:


if obj~=nil then
                            my_callbacks.on_use_item(obj)
                            end

В целом выглядит так:


function actor_binder:use_inventory_item(obj)
                         if(obj) then
                          local s_obj = alife():object(obj:id())
                          if(s_obj) and (s_obj:section_name()=="drug_anabiotic") then
                           xr_effects.disable_ui_only(db.actor, nil)
                           level.add_cam_effector("camera_effects\\surge_02.anm", 10, false, "bind_stalker.anabiotic_callback")
                           level.add_pp_effector("surge_fade.ppe", 11, false)
                           give_info("anabiotic_in_process")
                           _G.mus_vol = get_console():get_float("snd_volume_music")
                           _G.amb_vol = get_console():get_float("snd_volume_eff")
                           get_console():execute("snd_volume_music 0")
                           get_console():execute("snd_volume_eff 0")
                          end
                         end
                         if obj~=nil then
                           my_callbacks.on_use_item(obj)
                            end
end

3. Осталось добавить глобальную функцию give_object_to_actor в _g.script.

Внизу пишем:


-- 'Создание предмета в рюкзаке ГГ.
function give_object_to_actor(obj,count)
                          if count==nil then count=1 end
                          for i=1, count do
                             alife():create(obj,db.actor:position(),db.actor:level_vertex_id(),db.actor:game_vertex_id(),db.actor:id())
                          end
end

На этом урок заканчивается. Осталось только прописать пак ГГ и протестировать!

Спойлер

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

А теперь к делу. Сегодня мы будем разбирать исключительно скрипты. Конфиги и прочее можете глянуть в прошлом уроке. Мне многие задавали вопрос, как перенести коллбек на использование предмета в ТЧ и ЧН. Причиной невозможности работы коллбека в этих частях является отсутствие в bind_stalker.script функции function actor_binder:use_inventory_item(obj). Напоминаю, для рабочего комплекса она должна выглядеть так:


function actor_binder:use_inventory_item(obj)        
                            if(obj) then        
                             local s_obj = alife():object(obj:id())        
                             if(s_obj) and (s_obj:section_name()=="drug_anabiotic") then        
                    xr_effects.disable_ui_only(db.actor, nil)        
                    level.add_cam_effector("camera_effects\\surge_02.anm", 10, false, "bind_stalker.anabiotic_callback")        
                    level.add_pp_effector("surge_fade.ppe", 11, false)        
                    give_info("anabiotic_in_process")        
                    _G.mus_vol = get_console():get_float("snd_volume_music")        
                    _G.amb_vol = get_console():get_float("snd_volume_eff")        
                    get_console():execute("snd_volume_music 0")        
                    get_console():execute("snd_volume_eff 0")        
                             end        
                            end        
                            if obj~=nil then        
                    my_callbacks.on_use_item(obj) --Отсылка к нашему скрипту с функцией on_use_item(obj)
                     end          
end

Тогда давайте мы ее зарегистрируем и добавим. Все функции типа actor_binder зарегистрированы в другой функции в этом же файле. Называется function actor_binder:reinit(). В ЧН и ТЧ она такая:


function actor_binder:reinit()
               object_binder.reinit(self)

               local npc_id = self.object:id()

               db.storage[npc_id] = { }

               self.st = db.storage[npc_id]
               self.st.pstor = nil

               self.next_restrictors_update_time = -10000

               self.object:set_callback(callback.inventory_info, self.info_callback, self)
               self.object:set_callback(callback.article_info, self.article_callback, self)
               self.object:set_callback(callback.on_item_take, self.on_item_take, self)
               self.object:set_callback(callback.on_item_drop, self.on_item_drop, self)
               self.object:set_callback(callback.trade_sell_buy_item, self.on_trade, self) -- for game stats
               --self.object:set_callback(callback.actor_sleep, self.sleep_callback, self)
               self.object:set_callback(callback.task_state, self.task_callback, self)
               --self.object:set_callback(callback.map_location_added, self.map_location_added_callback, self)
               self.object:set_callback(callback.level_border_enter, self.level_border_enter, self)
               self.object:set_callback(callback.level_border_exit, self.level_border_exit, self)
               self.object:set_callback(callback.take_item_from_box, self.take_item_from_box, self)
end

А вот в ЗП:


function actor_binder:reinit()
        object_binder.reinit(self)
        local npc_id = self.object:id()
        db.storage[npc_id] = { }
        self.st = db.storage[npc_id]
        self.st.pstor = nil
        self.next_restrictors_update_time = -10000
        self.object:set_callback(callback.inventory_info, self.info_callback, self)
        self.object:set_callback(callback.article_info, self.article_callback, self)
        self.object:set_callback(callback.on_item_take, self.on_item_take, self)
        self.object:set_callback(callback.on_item_drop, self.on_item_drop, self)
        self.object:set_callback(callback.trade_sell_buy_item, self.on_trade, self)
        self.object:set_callback(callback.task_state, self.task_callback, self)
        self.object:set_callback(callback.level_border_enter, self.level_border_enter, self)
        self.object:set_callback(callback.level_border_exit, self.level_border_exit, self)
        self.object:set_callback(callback.take_item_from_box, self.take_item_from_box, self)
        self.object:set_callback(callback.use_object, self.use_object_callback, self)
end

Можно заметить, что именно в ЗП появляется:


self.object:set_callback(callback.use_object, self.use_object_callback, self)

Та самая нужная функция.

1) Добавим ее в регистр ТЧ/ЧН:


function actor_binder:reinit()
               object_binder.reinit(self)

               local npc_id = self.object:id()

               db.storage[npc_id] = { }

               self.st = db.storage[npc_id]
               self.st.pstor = nil

               self.next_restrictors_update_time = -10000

               self.object:set_callback(callback.inventory_info, self.info_callback, self)
               self.object:set_callback(callback.article_info, self.article_callback, self)
               self.object:set_callback(callback.on_item_take, self.on_item_take, self)
               self.object:set_callback(callback.on_item_drop, self.on_item_drop, self)
               self.object:set_callback(callback.trade_sell_buy_item, self.on_trade, self) -- for game stats
               --self.object:set_callback(callback.actor_sleep, self.sleep_callback, self)
               self.object:set_callback(callback.task_state, self.task_callback, self)
               --self.object:set_callback(callback.map_location_added, self.map_location_added_callback, self)
               self.object:set_callback(callback.level_border_enter, self.level_border_enter, self)
               self.object:set_callback(callback.level_border_exit, self.level_border_exit, self)
               self.object:set_callback(callback.take_item_from_box, self.take_item_from_box, self)
               self.object:set_callback(callback.use_object, self.use_object_callback, self)
end

2) Теперь где-нибудь пристроим саму функцию в файле. В этом случае переносить полностью функцию из ЗП не стоит. Там есть несколько лишних вещей. В ТЧ/ЧН функция actor_binder:use_inventory_item(obj) должна выглядеть следующим образом:


function actor_binder:use_inventory_item(obj)
               if obj~=nil then
               my_callbacks.on_use_item(obj)
               end
end

3) Все, осталось создать скрипт my_callbacks.script с коллбеком на использование предмета. Как это сделать опять же можно глянуть в прошлом уроке. Только не забываем, что в ТЧ и ЧН такие понятия, как "анабиотик" и "геркулес" отсутствуют.

Спойлер

 

  • Лайк 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

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

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация  

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу