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:
-
Otwieramy items.ltx i kopiujemy sekcję jakiegoś boostera. Wstawmy nową sekcję gdzieś w tym samym pliku.
-
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.
-
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:
-
Tworzymy plik my_callbacks.script w folderze scripts.
-
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.
-
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
- 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.
-
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
-
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
-
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:
ŹRÓDŁO:
https://ap-pro.ru/forums/topic/1317-sozdanie-inventarnogo-kompleksa/