Skocz do zawartości

Tworzenie ekwipunkowego kompleksu


Gość Diegtiariow

Rekomendowane odpowiedzi

Gość Diegtiariow

NAZWA: Tworzenie ekwipunkowego kompleksu
AUTOR: FantomICW

 

WSTĘP:

Spoiler

Być może zastanawiałeś się kiedyś nad stworzeniem przedmiotu, który po użyciu wrzuci do Twojego ekwipunku kilka innych na raz, jak np. uniwersalna zestaw medyczny. Efekt ten można osiągnąć za pomocą callbacków na użycie przedmiotów.
Co to jest „callback”? Krótko mówiąc, jest to coś w rodzaju skryptu infoportion. Jednakże callback może działać jednorazowo lub stale: podczas podnoszenia przedmiotów, podczas ich używania, podczas strzelania, po trafieniu NPC i tak dalej. Interesuje nas callback użycia przedmiotu, który będzie działał stale.

 

POTRZEBNE PLIKI:

Spoiler
  • configs/misc/items.ltx
  • configs/text/pol/st_items_equipment.ltx
  • scripts/_g.script
  • scripts/bind_stalker.script
  • scripts/my_callbacks.script

 

ZEW PRYPECI (CZYTAĆ, NAWET JEŚLI INTERESUJE WAS CZYSTE NIEBO LUB CIEŃ CZARNOBYLA):

Spoiler

Część I - tworzymy przedmiot:

1. Otwieramy items.ltx i kopiujemy sekcję jakiegoś boostera. Wstawmy nową sekcję gdzieś w tym samym pliku.

2. Skonfigurujmy to tak, jak chcemy.

[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

Nie zabawimy tu długo. Wszystko jest proste. Można tylko powiedzieć, że przy użyciu będzie odtwarzany dźwięk apteczki, a model wzięto z wojskowej apteczki.

3. W st_items_equipment.ltx tworzymy opis i nazwę przedmiotu:

<string id="st_medkit_complex">
                          <text>Uniwersalny zestaw medyczny</text>
                         </string>
                         <string id="st_medkit_complex_desc">
                          <text>Specjalny zestaw medyczny, opracowany dla służb specjalnych w Strefie. Zawiera w sobie wszystkie podstawowe medykamenty.</text>
                         </string>

To wszystko, jeśli chodzi o konfigi.

Część II - tworzymy callbacki:

1. Tworzymy plik my_callbacks.script w folderze scripts.
2. Wypełniamy go w następujący sposób:

function on_use_item(sect)
--Zmienne
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)
--Callbacki
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 - to jest dokładnie skrypt wydający przedmiot GG, polegający na callbacku. Nazwa elementu jest w nawiasach. Ogólnie rzecz biorąc, kontynuujemy w ten sam sposób i dodajemy, co chcemy. Zasada jest jasna.

2. Rejestrujemy nasz plik w bind_stalker.script. Znajdujemy tam function actor_binder:use_inventory_item(obj) i pod drugim end piszemy:

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

Ogólnie wygląda tak:

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. Pozostaje dodać funkcję globalną give_object_to_actor do _g.script.

Piszemy na dole:

-- 'Tworzenie przedmiotu w plecaku GG.
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

Pozostaje tylko dopisać pakiet GG i przetestować go!

 

CZYSTE NIEBO LUB CIEŃ CZARNOBYLA:

Spoiler

Przeanalizujemy wyłącznie skrypty. Możesz przyjrzeć się konfigom i innym rzeczom w poprzednim spoilerze. Wiele osób zadawało mi pytanie jak przenieść callback na używanie przedmiotu w CCz i CzN. Powodem braku pracy callbacka w tych grach, jest brak funkcji function actor_binder:use_inventory_item(obj) w bind_stalker.script. Dla działającego kompleksu powinno to wyglądać tak:

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) --Odsyłacz do naszego skryptu z funkcją on_use_item(obj)
                     end          
end

Tak więc, zarejestrujmy ją i dodajmy. Wszystkie funkcje typu actor_binder są zarejestrowane w innej funkcji w tym samym pliku. Nazywa się to funkcją function actor_binder:reinit(). W CzN i CCz jest tak:

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

A w ZP:

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

Można zauważyć, że w ZP pojawia się:

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

Ta sama potrzebna funkcja.

1) Dodamy ją do rejestru CCz/CzN:

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) Teraz dodajmy samą funkcję gdzieś w pliku. W takim przypadku nie warto przenosić całej funkcji z ZP. Jest tam kilka zbędnych rzeczy. W CCz/CzN funkcja actor_binder:use_inventory_item(obj) powinna wyglądać następująco:

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

3) I to wszystko, pozostaje tylko utworzyć skrypt my_callbacks.script z callbackiem umożliwiającym użycie elementu. Jak to zrobić, możesz zobaczyć wyżej. Tylko nie zapominaj, że w CCz i CzN nie ma czegoś takiego jak "anabiotyk" i "herkules".

 

PRZYKŁAD TEGO, JAK PRZEDMIOT TAKIEGO RODZAJU DZIAŁA:

Spoiler

 

 

ŹRÓDŁO:

https://ap-pro.ru/forums/topic/1317-sozdanie-inventarnogo-kompleksa/

Odnośnik do komentarza
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.
Uwaga: Twój wpis zanim będzie widoczny, będzie wymagał zatwierdzenia moderatora.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Usuń formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Korzystając z tej strony, zgadzasz się na nasze Warunki użytkowania.