Gość Diegtiariow Opublikowano 23 Grudnia 2023 Zgłoś Udostępnij Opublikowano 23 Grudnia 2023 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/ Cytuj Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Rekomendowane odpowiedzi
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.