The Emperor Opublikowano 1 Lipca 2013 Zgłoś Udostępnij Opublikowano 1 Lipca 2013 Tytułem wstępu:Poradnik stworzony głównie pod SoC (wszystkie działy tego poradnika tj: ACDC/xr_Spawner/skrypty) oraz Solijankę (cześć dot. spawnu poprzez skrypt). Chcąc kompleksowo ująć temat spawnowania, dodałem również informacje potrzebne przy dekompilacji/kompilacji all.spawn - zarówno pod SoC jak i pod CSky a także CoP. Tutorial przedstawia wykaz oraz omówienie metod spawnowania, jednakże nie ujmuje całościowo tematyki - ze względu na jej złożoność. Jeśli chodzi o kwestię działu w jakim powinien przebywać - postanowiłem umieścić go tutaj, gdyż w większości oparty został o pliki Solijanki i poprzez skrypty - umożliwia spawn również w rzeczonym modzie oraz "czystej wersji" ShoC.Narzędzie, od którego zaczynamy pracę:http://sdk.stalker-game.com/en/images/d/d7/Smartterrain_and_Waypoint_Tools_by_dez0wave.zipUmożliwia określenie współrzędnych: X, Y, Z oraz game_vertex i level_vertex. (opis: link )Uwagi dot. tekstu ujętego w codeGdyby doszło do sytuacji, iż kod potrzebny do skopiowania zostanie rozwarstwiony - przykład, np. podczas przenoszenia, edycji posta lub instalacji dodatków do edycji tekstu, wówczas należy kopiować fragmenty bez podanych w przykładzie odstępów w wierszach lub pobrać kod zawarty w załączniku: kod do skopiowania.7zPodane w załączniku fragmenty nie stanowią całości poradnika! I. ACDC• SoC 1.0004/1.0005.Pobieramy (Link) i instalujemy (pod swoją wersję systemu) ActivePerl - jest to język programowania niezbędny do pracy z ACDC. Pobieramy ACDC (all.spawn compiler/decompiler) dostosowany do naszej wersji gry. Jest to istotne, o tyle iż w przypadku niezgodności wersji podczas pracy może pojawić się błąd o następującej treści: Died at acdc.pl line 795 (lub inna), dlatego ważne jest dostosowanie pod właściwą wersję spawna. Wykorzystana dla potrzeb napisania niniejszego tutoriala edycja: ACDC 2.1 - z dn. 17 maja 2009 r.link: http://stalkerin.gameru.net/modules.php?name=Downloads&d_op=viewtheoned&lid=327 wersja przeznaczona do pracy z SHOC 1.0004/1.0005. Po wypakowaniu zawartości ACDC, musimy utworzyć 2 pliki tekstowe, w których umieszczamy wpisy odpowiedzialne za kompilację oraz dekompilację. W pierwszym pliku .txt - zmieniamy nazwę na complie oraz dodajemy poniższą zawartość i zapisujemy zmiany :perl acdc.pl -c all.ltx -o new.spawn Po dodaniu powyższego wpisu - zmieniamy rozszerzenie pliku z .txt na .bat (plik kompilatora do pracy z ACDC powinien posiadać nazwę compile.bat) Dla drugiego pliku .txt dodajemy wpis:perl acdc.pl -d all.spawn Zmieniamy nazwę pliku na decompile oraz rozszerzenie na .bat (plik dekompilatora do pracy z ACDC powinien posiadać nazwę decompile.bat). Jeśli są osoby, które nie wiedzą jak ustawić wyświetlanie rozszerzeń plików, warto zapoznać się z tym art. link Do folderu z wypakowanym ACDC - kopiujemy plik all.spawn Lista kontrolna zawartości folderu przeznaczonego do kompilacji/dekompilacji spawna (dla pobranego narzędzia z pkt.2):☒ acdc.pl (niektóre wersje ACDC mają zmienioną nazwę wynikającą z wersji wydania np. acdc11oct.pl, acdc11aug.pl - jeśli spotkamy się z podobną sytuacją - zmieniamy nazwę na acdc.pl)☒ stkutils (zawiera pliki: chunked_file.pm, data_packet.pm, ini_file.pm)☒ acdc_.cfg (opis w uwagach do pkt.10)☒ acdc_levels_info.cfg☒ acdc_x1_readme.txt (ten plik nie jest istotny do pracy, zawiera opis narzędzia)☒ compile.bat☒ decompile.bat☒ all.spawn (gamedata/spawns) Starsza wersja ACDC (jeśli na takową natrafimy) acdc11oct.pl - nie zawiera plików acdc_levels_info.cfg, acdc_.cfg - jednakże dla niej - nie są one wymagane! ponieważ configi są zapisane w pliku z rozszerzeniem .pl Chcąc wypakować zawartość all.spawn, klikamy na utworzony wcześniej plik decompile.bat. Wówczas powinno pojawić się okno dekompilatora: na screenie widoczna również zawartość folderu ACDCEwentualne problemy z dekompilacją pojawiają się w sytuacji, gdy plik all.spawn był modyfikowany xr_Spawnerem oraz w przypadku wypakowywania all.spawn'a zawierającego spawn na nowych level'ach, które nie występowały w SHOC. Taką sytuację miałem, gdy chciałem wypakować all.spawn z mapami od Kostya V (Stalker MapPack vol.1). Pod takie pliki należy szukać dopowiednich wersji ACDC. Po wypakowaniu all.spawn, powinny pojawić się pliki .ltx oraz plik section2.bin Sprawdzamy czy ilość plików alife_...ltx jest równa way_...ltx. Piszę o tym nie bez kozery, ponieważ spotkałem się z sytuacją, gdy brakowało kilku plików way...ltx. Niektóre decompilatory tworzą dodatkowy plik - jego obecność nie jest wynikiem błędu. Przy porównywaniu zawartości najistotniejsza jest zgodnosć ilości plików zawierających nazwę level'u, ponieważ dla celów smart terraina ścieżki NPC są zapisane w way_...ltx. przykładowo plikowi alife_l06_rostok.ltx odpowiada way_l06_rostok.ltx - to powinno stanowić kryterium porównawcze (nazwa lokacji). Lista kontrolna wypakowanego all.spawn'a (dla SHOC 1.0004): pliki alife_...ltx, 18 szt.alife_l01_escape.ltx,alife_l02_garbage.ltx,alife_l03_agroprom.ltx,alife_l03u_agr_underground.ltx,alife_l04_darkvalley.ltx,alife_l04u_labx18.ltx,alife_l05_bar.ltx,alife_l06_rostok.ltx,alife_l07_military.ltx,alife_l08_yantar.ltx,alife_l08u_brainlab.ltx,alife_l10_radar.ltx,alife_l10u_bunker.ltx,alife_l11_pripyat.ltx,alife_l12_stancia.ltx,alife_l12_stancia_2.ltx,alife_l12u_control_monolith.ltx,alife_l12u_sarcofag.ltx pliki way_...ltx, 18 szt + 1way_l01_escape.ltx,way_l02_garbage.ltx,way_l03_agroprom.ltx,way_l03u_agr_underground.ltx,way_l04_darkvalley.ltx,way_l04u_labx18.ltx,way_l05_bar.ltx,way_l06_rostok.ltx,way_l07_military.ltx,way_l08_yantar.ltx,way_l08u_brainlab.ltx,way_l10_radar.ltx,way_l10u_bunker.ltx,way_l11_pripyat.ltx,way_l12_stancia.ltx,way_l12_stancia_2.ltx,way_l12u_control_monolith.ltx,way_l12u_sarcofag.ltx,oraz plik dodatkowy: way_lxx_unknown.ltx (testowy)Mając już wypakowaną zawartość pliku all.spawn, dodajemy obiekty (poprzez kopiowanie sekcji) - zawsze do plików alife_...ltx! Do plików way_...ltx dodawane są współrzędne ścieżek NPC, ustawienia smart_terrain'a oraz configi Level_Changer'ów (LC) cz teleportów. Przy dodawaniu obiektów do plików (dla alife_...ltx), nowo-utworzoną sekcję numerujemy, nadając jej wartość wyższą od 8640 (w przypadku oryginalnego Shoc). Rzeczona numeracja dotyczy obiektu: box_lab_0002 zawartego w pliku alife_l10u_bunker.ltx. - jest to ostatni obiekt w czystej wersji spawna. Naszą numerację rozpoczynamy zatem od nr. 8641. W modach, które dekompilujemy - ta numeracja będzie inna, więc nalezy sprawdzić ostatni obiekt - jaki dodał autor moda. Kilka uwag: W tej wersji ACDC, do numeracji obiektów - dodana jest również nazwa poziomu - przykład: omawiany powyżej obiekt box_lab_0002 zapisany jako [l10u_bunker_8640] - my nie musimy tworzyć takiego wpisu dodając obiekt, wystarczy iż w nawias kwadr., wpiszemy kolejny nr. obiektu dodawanego, czyli [8641]. Później w toku procesu kompilacji - wartość zostanie uzupełniona o nazwę levelu. Można przekonać się o tym dodając jakikolwiek obiekt a następnie zdekompilować przetworzony spawn, sprawdzając plik alife_...ltx, w którym tworzyliśmy nasz przedmiot/mutanta/NPC'a. Ważne jest aby pomiędzy obiektami dodawanymi do plików - zachować 2-wierszowy odstęp!Ważne: jeśli mamy zamiar dodać nową anomalię, mutanta - których sekcje występują w plikach .ltx [gamedata], wówczas musimy uzupełnić plik acdc_.cfg.Przykład: tworzę odmianę anomalii odpowiedzialnej za ogień z ogniska, jednak ze zmienionymi parametrami, o zmniejszonych wartościach obrażeń. Zależy mi aby NPC nie ginęli w ogniskach. Za ogień w obozowiskach odpowiada:section_name = zone_flame_small Potrzebuję jednak - zgodnie z założeniem - nowej anomalii (jej config odpowiada za ognisko) np. tworzę więc:zone_flame_ogien Jeśli będę próbował kompilacji z nową sekcją, dodaną do pliku alife_...ltx - ta nie zostanie ukończona. Muszę zatem dodać wpis (poniższy), który uwzględnia nową sekcję podczas kompilowania.zone_flame_ogien = cse_alife_anomalous_zone W starszych wersjach ACDC, wpis ten dodawało się do acdc.pl (otwieramy Notepad'em ++). Wpis dodajemy do sekcji bliźniaczych, tzn. nie w dowolnym miejscu pliku, lecz w miejscu gdzie są wpisane obiekty danego rodzaju (np. anomalie są zgrupowane w innym miejscu niż mutanty) - w moim przykładzie wpis zone_flame_ogien ,umieszczam pod zone_flame_small, ponieważ w oparciu o niego - tworzyłem nową sekcję.Dopiero po tym zabiegu - kompilator jest gotowy do pracy z nową sekcją. Sekcje innych obiektów - dodajemy analogicznie, z uwzględnieniem właściwego miejsca ich dodania. Po dodaniu obiektu do plików alife_...ltx czy ścieżek patrolowych dla way_...ltx, zapisujemy zmiany i klikamy compile.bat. W folderze z ACDC zostanie utworzony nowy plik new.spawn, który kopiujemy do [gamedata/spawns] i zmieniamy nazwę z new na all.spawn. Zdarzyć się może, że nowo utworzony plik new.spawn posiada rozmiar nieco mniejszy niż oryginał - wynika to z zastosowanej metody kompilacji. Jeśli mamy podejrzenia, co do kompletności plików .ltx - możemy wypakować nasz nowy plik spawna, sprawdzając czy ilości plików są zgodne! Możemy cieszyć się grą!Omówienie podstawowych parametrów obiektów spawnowanych. W pracy ze spawnem nie musimy edytować wszystkich wpisów - jakie zawiera dodawany obiekt, ponieważ wiele z nich pochodzi z SDK. To co jest naprawdę istotne dla nowego obiektu:[l01_escape_93] lub w innej wersji [93] (każdy obiekt) - numer dodawanego obiektu (nie może być powtórzony w all.spawn), zawsze występuje w nawiasach [ ].section_name (każdy obiekt) - nazwa dodawanej sekcji, podstawowe to: stalker (tylko NPC) stalkerzy - wpis ten występuje bez względu na frakcję; dodając NPC - section_name = stalkerdla mutantów sekcji szukamy w [gamedataconfigcreatures] w plikach m_...ltx (spis plików znajdziemy w monsters.ltx), każdy z plików mutanta zawiera kilka wersji różniących się parametrami siły ataku, odporności etc. Przykładowo (dla dzika): boar_weak, boar_normal, boar_strong.dla anomalii wpisy znajdziemy w [gamedata]configmisc] - wykaz plików znajdziemy w zones.ltx. Szukamy właściwych sekcji w nawiasach [ ] danego pliku anomalii.level_changer (tylko Level_changer) - dla obiektu umożliwiającego przejście na inną lokacjęm_car - (tylko dla pojazdów).smart_terrain - dla obozów stalkerskichname - nazwa obiektu, zawsze dodając obiekt - tworzymy nową nazwę.position (każdy obiekt) - definiuje położenie obiektu. Współrzędne kolejno X,Y,Zdirection (każdy obiekt) - obrót obiektu po zespawnowaniu. Tym parametrem dla mutantów czy stalkerów nie warto się przejmować, ponieważ obiekt zmieni położenie wg. przypisanego smart_terraina, bądź w przypadku jego braku - będzie swobodnie przemierzał mapę. Parametr ustawiamy na 0,0,0.Parametr ma znaczenie wtedy, gdy chcemy np. zespawnować przedmiot w konkretnym położeniu.money (występuje w przypadku spawnu NPC) - ilość pieniędzy dla spawnowanego NPC, jednakże za końcową konfigurację wartości gotówki odpowiadają pliki character_desc...xml.character_profile (występuje w przypadku spawnu NPC) - parametr specyficzny, zdefiniowany jest w plikach character_desc_xxxxx.xml (xxxx - level na którym spawnujemy NPC) folder [gamedataconfiggameplay].game_vertex_id - (każdy obiekt) b.istotny dla współrzędnych obiektu parametr wierzchołkowy (każda lokacja ma inną wartość).level_vertex_id - (każdy obiekt) dla spawna, bez względu czy za pomocą ACDC czy skryptu - wymagany parametr.object_flags = 0xffffffbf - Nigdy nie zmieniamy tej wartości (dla SDK).Wpis przykładowy (występuje dla NPC)określający przynależność NPC do konkretnego obozu tj. smart_terraina: [smart_terrains]esc_lager = trueENDW przypadku braku smart_terraina[smart_terrains]none = trueENDvisual_name - ścieżka do modelu .ogf [gamedatameshesactors]. Za ostateczny wygląd odpowiada plik character_desc_xxxxx.xml, jednakże - nie pomijamy tego wpisu.health (tylko NPC/mutanty) parametr odpowiedzialny za zdrowie - wartość max. 2upd:position - (tylko NPC/mutanty) - są to koordynaty X, Y, Z - ustawiamy je tak samo jak w position!upd:condition (w przypadku obiektów np. broni, kombinezonów które zespawnujemy na ziemię) odpowiada za stopień degradacji przedmiotu. Wartości 255 - nie wolno przekraczać!Powyższy spis nie wyczerpuje listy parametrów, dlatego spawnując jakikolwiek obiekt, warto poprzez analogię tworzyć spawn. Największą bibliotekę wiedzy stanowią pod-pliki spawna.Dodając stalkera/mutanta zapamiętaj!: position = upd:position Przykładowy spawn: bez smart_terraina (wymagającego osobnego tutoriala) snorka w kordonie - screen w załączeniu.a) do wypakowanego z all.spawn pliku alife_l01_escape.ltx doddaję wpis:[8641]; cse_abstract propertiessection_name = snork_strongname = kordon_snork_0001position = -244.069931030273,-19.5495166778564,-128.138198852539direction = 0,0,0; cse_alife_object propertiesgame_vertex_id = 8distance = 21level_vertex_id = 12825object_flags = 0xffffffffcustom_data = <<END[smart_terrains]none = trueEND; cse_visual propertiesvisual_name = monsterssnorksnork; cse_alife_creature_abstract propertiesg_team = 0g_squad = 18g_group = 4health = 1.79999995231628dynamic_out_restrictions =dynamic_in_restrictions =upd:health = 1.79999995231628upd:timestamp = 0upd:creature_flags = 0upd:position = -244.069931030273,-19.5495166778564,-128.138198852539upd:o_model = 0upd:o_torso = 1.52819967269897,0,0upd:g_team = 0upd:g_squad = 18upd:g_group = 4; cse_alife_monster_abstract propertiesbase_in_restrictors = pri_stadium_snipers_restrupd:next_game_vertex_id = 65535upd:prev_game_vertex_id = 65535upd:distance_from_point = 0upd:distance_to_point = 0; cse_ph_skeleton properties; cse_alife_monster_base properties; se_monster propertiesb) zapisuję zmiany i klikam compile.bat, utworzony plik new.spawn umieszczam w gamedata/spawns - zmieniając nazwę na all.spawn.c) efektem zmian jest zespawnowany w pobliżu bunkra Sidorowicza - snork (wersja strong). • ACDC/Csky:postępujemy analogicznie jak przy ACDC SoC (nie zapominamy o zainstalowaniu środowiska pearl!)Pobieramy ACDC dla Stalker: Czyste Niebo - Link. Wypakowany folder zawiera już potrzebne pliki, również te z rozszerzeniem .bat□ распаковать.bat odpowiada za dekompilację spawna (nazwę możemy zmienić na decompile).□ упаковать.bat odpowiada za kompilację (nazwę możemy zmienić na compile). Musimy umieścić tylko plik all.spawn w folderze z wypakowanym narzędziem. Dodawanie obiektów wygląda analogicznie jak w przypadku SoC. czyli kopiowanie sekcji obiektu do pliku alife_...ltx Możemy zmienić występujący w compile.bat wpis:Íŕćěčňĺ ëţáóţ ęíîďęó äë˙ óäŕëĺíč˙ LTX ôŕčëîâ na (wersja przetłumaczona - bez polskich znaków): Nacisnij dowolny przycisk, aby usunac pliki LTX wówczas wypakowane pliki .ltx zostaną usunięte a nowy plik spawn'a: all.spawn.new - utworzony. Nazwę rzecz jasna - zmieniamy na all.spawn Nowy plik spawn'a umieszczamy w [gamedataspawns] Jeśli potrzebujemy zespawnować obiekt nieujęty w pliku kompilatora (podobnie jak w pkt. 10 - patrz uwagi dot. ACDC SoC), umieszczamy stosowny wpis w acdc.pl (edytujemy np. Notepad'em ++) i zapisujemy zmiany. • ACDC/CoP:procedura dekompilowania/kompilowania plików jest taka sama jak dla SoC czy CoP - różnice występują w zawartości wypakowanego ACDC, który - podobnie jak w podanym narzędziu dla Clear Sky - posiada wszystkie potrzebne pliki. Obiekty nie ujęte w pliku kompilatora - dodajemy jak w pkt. 7 dot. ACDC/CS.ACDC dla CoP dostępny pod linkiem: ACDC_Cop.rar ACDC w innych wersjach, dostosowanych pod mapy ok Kostya V, Build'a 3120 - dostępne na tej stronie: Stalker Inside. II. xr_SpawnerSoC wersja 1.0004 eng. Szczerze mówiąc - xr_Spawner nie jest idealnym narzędziem do modyfikowania pliku all.spawn ponieważ powoduje zmiany w pliku edytowanym - do tego stopnia, iż nie jest możliwa jego dekompilacja za pomocą ACDC! Taki plik można zmodyfikować tylko xr_Spawner'em - przykład: Solijanka,DMX. Nie powstał jeszcze dekompilator dla all.spawna modyfikowanego xr_Spawnerem, a przynajmniej nic mi na ten temat nie wiadomo...Wskazówki ogólne:Zakładka 1: Spawn Tab - jest odpowiedzialna za spawn obiektu (do plików alife_...ltx).Zakładka 2: Game Tab - odpowiada za ścieżki patrolowe NPC'ów, mutantów oraz dane dla konstrukcji level_changer'a, smart_terrain'a, które wymagją osobnych tutoriali (zapis do way_...ltx) Dodając obiekty operujemy w Spawn Tab - którego menu oraz podstawowe wskazówki dot. spawnowania zawiera screen. Pobieramy xr_Spawner (dla 1.0004) pod naszą wersję gry. W załączniku (na wypadek gdyby link wygasł) - xr_Spawner 1.0004 (menu w wersji eng.).xr_spawner 1.0004.rar Niestety większość możliwych do pobrania spawner'ów - to wersje rosyjskie, dlatego dodaję trudno dostępną wersję eng.- do pobrania z naszej strony. Pobieramy również xr_Spawner w wersji rosyjskiej (Link), nie będziemy go używać, ale posiada bardziej rozbudowaną - niż w wersji eng. - bibliotekę obiektów. Jest to plik o nazwie spawn.base, który kopiujemy do folderu z rozpakowanym xr_Spawner'em (wersja eng.). Podstawowa wersja w/w pliku zawiera jedynie sekcje 2: □ Transport (Cars)□ Monsters (Mutants). Natomiast wersja rosyjska spawner'a - 5 sekcji + podsekcje(opis pkt.6) Po skopiowaniu powyższego, do folderu xr_Spawner'a wklejamy nasz plik all.spawn (pamiętamy o wersji gry do której stworzono spawner). Otwieramy xr_Spawner, wchodzimy w File → Open (Ctrl+O) i wybieramy nasz plik all.spawn. Po otwarciu naszym oczom ukaże się menu zawierające szereg opcji - opis w screenie powyżej. Chcąc dodać obiekt/NPC'a/mutanta - z listy rozwijanej w sekcji Add Object (górny prawy róg spawner'a) → wybieramy rodzaj obiektu do spawnowania np. sekcja Stalkers a następnie NPC'a, którego mamy zamiar dodać - np. bandit, klikając Add w sekcji dolnej. Procedura dla innych obiektów jest taka sama, więc skupię się na spawnie stalkera. - w przykładzie wykorzystałem spawn NPC'a. W bibliotece z rosyjskiej wersji xr_Spawner'a mamy następujące sekcje przedmiotów możliwych do spawna: □ Transport (pojazdy): Niva Green, Kamaz, Zaporozhez, Tractor TR13, BTR, UAZ, Niva White.□ Monstrs (mutanty): Burer_01, Dog_weakxa, pseudoDog_weakxa, bloodsucker_normalxa, Tushkano_normalxa, m_controller_normalxa, psy_dog_radarxa, esc_zombie_ambushxa, controller_tubemanxa, Snork_weakxa.□ Stalkers (NPC): bandit, novichek u Petruxi, novichek u Petruxi2, barniy stalker, barniy dolg, Stalker trade petrenko, stalker wolker, Nastoyashiy Petruxa, Prizak.□ phuzic objects (obiekty fizyczne): box 1 a, box 1, box vse, box vse2, yashic vse.□ anomaly (anomalie): Zone_gravixa. Pamiętajmy że mamy do czynienia z biblioteką rosyjską - stąd dziwne nazwy. Pomimo,iż biblioteka nie jest zbyt pokaźna - poprzez zmiany ścieżki do modelu, nazwy etc. - otrzymujemy mnogosć wariantów spawnowania. Obiekt dodany pojawia się na liście (po lewej stronie menu), w sekcji InTurn - zostaje nadany kolejny numer obiektu. W oryginalnym Shoc - niezawierającym modowanego spawn'a, kolejny numer obiektu to 8641. Zmieniamy nazwę obiektu na unikalną, najlepiej aby nie powtórzyła się, czyli w Object Name wpisuję - dla celów przykładowych: esc_tutorial_bandit1 Level_ID - w tej sekcji wybieramy mapę, na której spawnujemy obiekt - np. l01_escape (Kordon). Sekcję Object Path - zmieniamy tylko wtedy, gdy chemy zmienić model ogf. naszej postaci, jednakże sugeruję zostawić go bez zmian, ponieważ zmianę obiektu można uzyskać z pliku .xml - odpowiedzialnego za config postaci. Ważne jest aby model wpisywać bez rozszerzenia, bowiem spawner automatycznie je uwzglednia - jednak do tego nalezy skonfigurować postać w oknie skryptu. W sekcji Script możemy przypisać smart terrain, jednakże jego utworzenie to temat innego tutoriala, dlatego możemy dla celów testowych wpisać poniższe ustawiania, przy których nasz NPC - nie ma przypisanego obozu:[smart_terrains]none = trueEND[spawn]medkitW sekcji Coord.X, Coord.Y, Coord.Z - wpisujemy współrzędne obiektu. Uwaga: współrzędne oddzielamy przecinkiem! Vector X, Vector Y, Vector Z - odpowiada za obrót obiektu - jest to mało istotny parametr w przypadku obiektów mobilnych jak NPC czy mutanty, ponieważ samoczynnie zmienią one położenie. Możemy ustawić wartości 0,0,0 Story_ID - zmieniamy tylko wówczas, gdy NPC będzie zlecał questy - lub będzie istotny dla fabuły z uwagi na np. infoportion. Ja pozostawiam niezmieniony (w przykładzie). Klikamy - po wprowadzeniu wszystkich parametrów: Save Changes a następnie File → save. Zmodyfikowany plik all.spawn wklejamy do gamedata/spawns - sprawdzając rezultat. Menu spawnera w zakładce: Edit - zawiera opcję dodawania (Add Object) oraz usuwania (Remove object) obiektów. Warto pamiętać o tym udogodnieniu w przypadku ewentualnych poprawek.Ważne: dodając obiekt - który w podstawowej wersji gry - nie występował np. połamaniec, kot, burer etc. pamiętajmy iż kwestia spawna nie rozwiązuje ewentualnych problemów wynikających z braku odpowiedniej konfiguracji, bowiem na spawn obiektu przypada ustawienie modelu, dodanie tekstury zarówno jako pliku .dds jak również sparametryzowania bump mapingu w textures.ltx, ponadto config .xml, .ltx ewentualnie .script. Pamiętajmy o tym spawnując obiekt, którego poszczególne składowe - musimy włączyć do plików gry.P.S - wszystkim modderom pragnącym realizować spawn za pomoca xr_Spawnera - polecam sprawdzić all.spawn z Solijanki/DMX'a - bowiem stanowi on kompleksowe źródło wiedzy o sposobie dodawania obiektów w/w narzędziem - poprzez analogię, ze szczególnym uwzglednieniem okna script zawierającego istone dla konfiguracji informacje. Osobiście używam ACDC, i w oparciu o nadmieniony dekompiler - powstaną kolejne tutoriale, jednakże - warto mieć wybór sposobu spawnowania. III. Spawn poprzez skrypty.Spawn za pomocą skryptu (testowane na SoC). Jeśli masz zamiar poznać sposoby tworzenia modyfikacji zawierających własne skrypty oraz sposób ich aktywowania, powinieneś przeczytać całą część zawierającą przykłady na tyle oryginalne, iż dzięki nim zrozumiesz sposób - w jaki zostały one skonstruowane oraz jakich wymagają konfiguracji. Poradnik nie wyczerpuje wszystkich możliwości jakie niesie skryptowanie, ale jest wystarczający do tworzenia własnego spawna oraz związanych z nim mozliwości tworzenia questów. Sama metoda nie wymaga ingerencji w plik all.spawn i umożliwia dodanie żądanego obiektu w dowolnym momencie rozgrywki. Ważne jest aby skrypt zawierający funkcję spawnu - w przypadku obiektów charakterystycznych jak np. zleceniodawca zadań, unikalna broń czy handlarz - był wywoływany tylko raz. Nie chcielibyśmy 2 tych samych postaci, zlecających questy, albo spawnujących się w sytuacji gdy "przeszły w stan spoczynku" na cerkiewnym cmentarzu.Musimy zatem doprowadzić do jednorazowego układu infoportion, który aktywowany dialogiem - uruchomi naszą funkcję. Więcej szczegółowych informacji na temat infoportion i dialogów oraz tworzenia zadań, znajdziemy pod linkiem do tego tutoriala:Tworzenie zadań z wykorzystaniem własnego skryptu. - proszę traktować w/w poradnik jako uzupełnienie.Przypomnę jednak ogólną zasadę tworzenia spawna za pomocą skryptu - na potrzeby niniejszego opracowania. Spawn mutanta (bez smart_terraina):W katalogu [gamedata/scripts] tworzymy plik z rozszerzeniem .script - nadając mu nazwę dowolną np. my_spawn.script W utworzonym pliku umieszczamy wpis, który będąc aktywowanym - spowoduje spawn mutanta. Dla przykładu zespawnuję nibypsa w wersji strong, którego możemy znaleźć w pliku m_pseudodog.ltx. Pozostałe mutanty znajdziemy w gamedataconfigcreatures w odpowiednich plikach .ltx - nazwy są ujęte w nawiasy kwadratowe dla poszczególnych wariantów odporności i siły ataku - potwora. Dodajemy zatem wpis: --początek_funkcjifunction spawn_monstrer1()alife():create("pseudodog_strong",vector():set(-244.069,-19.549,-128.138),12825,8)end--koniec_funkcji. Gdzie:□ X,Y,Z - koordynaty [ X: -244.069, Y: -19.549, Z: -128.138 ]□ level_vertex_id: 12825□ game_vertex_id: 8□ pseudodog_strong - mutant którego spawnujemy (plik: m_pseudodog.ltx). Za pomocą dialogu możemy aktywować funkcję, zatem w pliku zawierającym drzewo dialogowe [gamedata/config/gameplay] - w przykładzie dialogs_escape.xml (ponieważ spawnuję obiekt w kordonie) dodajemy wpis do utworzonego dialogu - patrz poradnik pkt. 4 - link <action>my_spawn.spawn_monstrer1</action> Action jest tagiem umożliwiającym wywołanie skryptu. W/w wpis oznacza iż: w pliku skryptu my_spawn.script jest wywoływana funkcja - uprzednio zdefiniowana tj.spawn_monstrer1.Możemy również rozbudować naszą funkcję spawnu do kilkunastu obiektów, jednak ich spawn - będzie skutkował spadkiem płynności gry (przy dużej liczbie wpisów). Inna postać funkcji spawn_monstrer1() - 3 w 1 czyli jednoczesny spawn: mutanta, obiektu (egzoszkielet) oraz artefaktu na zadanych koordynatach. Funkcja Alternatywna:function spawn_monstrer1()local obj = alife():create("pseudodog_strong",vector():set(-244.069,-19.549,-128.138),12825,8)local obj = alife():create("outfit_exo_m1",vector():set(-213.307,-20.442,-155.432),39896,49)local obj = alife():create("af_fireball",vector():set(-235.489,-19.987,-142.908),20055,47)end Gdzie:□ outfit_exo_m1 - ulepszony egzoszkielet, plik unique_items.ltx [gamedataconfgmisc]□ af_fireball - artefakt kula ognista, plik artefacts.ltx [gamedataconfigmisc] koordynaty - analogicznie do pkt 2.Przypominam - nazwy obiektów ujęte są w plikach .ltx w nawiasy [ ]. Obiekt musi być zdefiniowany w pliku konfiguracyjnym np.□ przedmioty: items.ltx [gamedataconfigmisc]□ kombinezony: outfit.ltx [gamedataconfigmisc]□ artefakty: artefacts.ltx [gamedataconfigmisc]□ mutanty: m...ltx np. m_poltergeist.ltx, m_pseudodog.ltx, m_flesh.ltx etc. [gamedataconfigcreatures]□ stalkerzy: spawn_sections.ltx [gamedataconfigcreatures].□ unikalne przedmioty: unique_items.ltx [gamedataconfigmisc]□ bronie: w_...ltx, np. w_l85.ltx, w_svd.ltx, w_sig550.ltx Możemy oczywiście stworzyć nowe przedmioty/mutanty czy NPC i podłączyć je do gry, dopiero wówczas je spawnujemy - co jest logiczne, bowiem - nie możemy spawnować przedmiotu,który nie istnieje. Pamiętajmy o tym - być może oczywistym fakcie, najpierw znajdując przedmiot a następnie go dodając do skryptu. Nie kopiujmy sekcji z innych modów - jeśli nie mamy pewności, czy występuje on w naszym gamedata. W toku toczonej rozmowy, następuje spawn obiektów, które zdefiniowaliśmy w skrypcie, jednakże do pełni szczęścia potrzeba dodatkowej konfiguracji.Przykładowe funkcje zawierające spawn:• plecak z ekwipunkiem. (wzorowane na zadaniach Kostyi z Solijanki)Do pliku devices.ltx [gamedataconfigmisc] pod sekcją [inventory_box], wiersz 34 pliku podstawowego: dodaję wpis:;plecak1[m_inventory_box]:inventory_boxvisual = equipmentsitem_rukzak ;model .ogf plecakaradius = 1Do pliku skryptu (wykorzystam omawiany w pkt.2 plik my_spawn.script katalog: gamedata/scripts ), dodaję wpis:--' Spawn_plecaka ucieczkowegofunction spawn_prepers_bag()local se_obj = alife():create("m_inventory_box1", vector():set(-213.307,-20.442,-155.432),39896,49)end gdzie: m_inventory_box1 - zdefiniowana w pkt. 3 sekcja ekwipunku. Tworzymy plik m_inventory_box1.ltx w [gamedataconfigscripts] - zgodnie z wpisem dodanym do funkcji w/w, do którego dodajemy poniższe dane (przedmioty spawnujące się w plecaku - możemy stworzyć własny zestaw):[spawn]antirad = 2medkit = 1ammo_og-7b = 3wpn_rpg7 = 1kolbasa = 2 Tak jak poprzednio - trzeba wkomponować w szkielet dialogowy - aktywator funkcji, zatem dodaję wpis w dialogs_escape.xml [gamedataconfiggameplay] (przypominam - plik dialogu zależny jest od umiejscowienia postaci zlecającej zadanie):<action>my_spawn.spawn_prepers_bag</action> Powyższy wpis wywołuje funkcję spawn_prepers_bag - zdefiniowaną w pkt. 2, pliku my_spawn.script W pliku spawn_sections.ltx [gamedataconfigcreatures] - umieszczamy wpis: ;;-------- Plecak_ucieczkowy -----------------------[m_inventory_box1]:inventory_boxvisual = equipmentsitem_rukzakradius = 1custom_data = scriptsm_inventory_box1.ltx; -------- Plecak_ucieczkowy -----------------------Efektem naszej pracy jest: Najciekawszy fakt wynikający z powyższego rozwiązania, to możliwość dodawania takiego plecaka w dowolnym momencie rozgrywki. Rozwiązanie zaczerpnąłem z Solijanki (plecaki Kostyi) i przetestowałem. W kryzysowej sytuacji mozna dodać sobie tym sposobem przedmiot, którego potrzebujemy - chociaż są szybsze metody. • teleport, którego wykorzystanie zalezy od naszej wyobraźni. Grający w solijankę wiedzą jak potrafiły utrudnić życie Naznaczonemu - a niejednokrotnie umożliwiały dostęp w m-ca niedostępne. Do pliku zone_teleport.ltx [gamedataconfigmisc] dodajemy wpis konfigurujący (opis parametrów poniżej):;---Nowy_teleport_1[m_teleport_1]:zone_teleportteleport = standartscript_binding = bind_mteleport.bind ; odwołanie do pliku skryptu!;Parametry teleporturadius = 2 ; promień pola teleportu;Promień działania teleportuz_radius = 2;Miejsce docelowe teleportacjipoz_x = -235.48901367188 ; współrzędna Xpoz_y = -19.987777709961 ; współrzędna Ypoz_z = -142.90892028809 ; współrzędna Z; Parametr pozostawiany bez zmian (obrót postaci)rotate = 1.5 ; obrót postaci po teleportacji;---Nowy_teleport_1W pliku skryptu - analogicznie jak w poprzednio omawianym spawnie, dodajemy funkcję (korzystam z utworzonego wcześniej pliku my_spawn.script) o treści następującej:--' Spawn_teleportufunction spawn_teleport1()local obj = alife():create("m_teleport_1",vector():set(-213.307,-20.442,-155.432),39896,49)end gdzie: m_teleport_1 - utworzono w pkt. 1 (zone_teleport.ltx) W pliku odpowiedzialnym za szkielet dialogowy - w przykładzie: dialogs_escape.xml [gamedataconfiggameplay] - dodaję wpis odpowiedzialny za aktywowanie funkcji, zatem kopiujemy poniższe:<action>my_spawn.spawn_teleport1</action> Ponieważ plik zone_teleport.ltx - omawiany powyżej, posiada wpis:script_binding = bind_mteleport.bind Musimy stworzyć plik skryptu, który określa cechy teleportu. Zatem, w folderze [gamedata/scripts] tworzymy plik bind_mteleport.script i umieszczamy tam następującą zawartość (autorem funkcji jest IMP, plik występuje w Solijance): --dodaj zawartość do pliku:-- ************************************************-- ** Autor Skryptu: Imp **-- ************************************************local teleport_binders ={} -- Lista_Teleportówfunction abs_comp(a,b) -- Funkcja obliczania różnicy if( a < b) then return (b - a) else return (a - b) endendfunction teleportate(x,y,z)-- Funkcja teleportacji local a = vector() -- Określanie współrzędnych a.x = x a.y = y a.z = z -- Ustawienie pozycji db.actor:set_actor_position(a) -- Wykorzystywany dźwięk local snd_obj = xr_sound.get_safe_sound_object([[affectstinnitus3a]]) snd_obj:play_no_feedback(db.actor, sound_object.s2d, 0, vector(), 1.0)endfunction actor_update(delta) local i,v,acter_poz,s -- Uaktualnienie pozycji aktora acter_poz = db.actor:position() -- Sprawdzanie teleportów for i, v in pairs(teleport_binders) do s = v.parametrs local obj = level.object_by_id( i ) if obj ~= nil then -- Teleport-offline if s.teleporte ~= nil and s.teleporte ~= false then -- Teleport_start if ( time_global() <= s.time ) then -- Zależność teleportacji w funkcji czasu -- Atkywacja teleportru teleportate(s.poz_x,s.poz_y,s.poz_z) if s.rotate ~= nil then db.actor:set_actor_direction(s.rotate) end s.teleporte = false end return end -- dodatkowe warunki sprawdzające stan położenia aktora if (abs_comp(s.x, acter_poz.x)< v.parametrs.radius and abs_comp(s.z, acter_poz.z)< v.parametrs.radius and abs_comp(s.y, acter_poz.y)< v.parametrs.z_radius) then -- Aktor w zasięgu pola teleportacji s["teleporte"] = true s["time"] = time_global() + 500 -- Efekt wizualny .ppe level.add_pp_effector ("teleport.ppe", 2006, false) end end endendfunction bind( obj ) obj:bind_object( restrictor_teleport( obj ) )end----------------------------------------------------------------------------------------------------class "restrictor_teleport" ( object_binder )function restrictor_teleport:__init(obj, char_ini) super(obj)endfunction restrictor_teleport:net_spawn(data) local char_ini = system_ini() -- Jeśli teleport pozostaje zespawnowany - dodaj odpowiedni wpis. if self.teleport == true then teleport_binders[self.object:id()] = self -- Parametryzacja teleportu self["parametrs"] = {} if char_ini:line_exist(self.section, "radius") then self.parametrs["radius"] = tonumber(char_ini:r_string(self.section, "radius")) else self.parametrs["radius"] = 2 -- Promień pola teleportacji end if char_ini:line_exist(self.section, "z_radius") then self.parametrs["z_radius"] = tonumber(char_ini:r_string(self.section, "z_radius")) else self.parametrs["z_radius"] = self.parametrs["radius"] -- Jeśli nie określono wartości promienia - ustaw xy end -- Zapamiętaj pozycję. local s_obj = alife():object(self.object:id()) self.parametrs["x"] = tonumber(s_obj.position.x); self.parametrs["y"] = tonumber(s_obj.position.y); self.parametrs["z"] = tonumber(s_obj.position.z); -- Obliczanie parametrów, zapamiętywanie pozycji. self.parametrs["poz_x"] = tonumber(char_ini:r_string(self.section, "poz_x")) self.parametrs["poz_y"] = tonumber(char_ini:r_string(self.section, "poz_y")) self.parametrs["poz_z"] = tonumber(char_ini:r_string(self.section, "poz_z")) if char_ini:line_exist(self.section, "rotate") then self.parametrs["rotate"] = tonumber(char_ini:r_string(self.section, "rotate")) end end return trueendfunction restrictor_teleport:net_destroy() -- Usuń teleport teleport_binders[self.object:id()] = nil self.parametrs = nil object_binder.net_destroy(self)endfunction restrictor_teleport:reload(section) local char_ini = system_ini() self.section = section -- Teleport. if char_ini ~= nil and char_ini:line_exist(self.section, "teleport") then self["teleport"] = true endend Do pliku bind_stalker.script [gamedata/scripts] dodajemy wpis odnoszący się do powyższego bind_mteleport.script. W niemodowanym Shoc, dodaję w linijce 276. Kopiujemy poniższe: -- Aktualizacja teleportu. bind_mteleport.actor_update(delta) Żeby nie było wątpliwości gdzie wkleić wpis: - przykład z mojego pliku, trzeba tylko znaleźć właściwe sekcje i pomiędzy nie dodac wpis (wg. poniższego szukamy m-ca dodania): -- îáíîâëĺíčĺ đĺńňđčęňîđîâ, ęîňîđűĺ ďîä ëîăčęîé, ńđŕáŕňűâŕĺň ÷ĺđĺç číňĺđâŕëű âđĺěĺíč if self.next_restrictors_update_time < time then bind_restrictor.actor_update(delta) -- Aktualizacja teleportu. bind_mteleport.actor_update(delta) ---Tutaj dodaję wpis. self.next_restrictors_update_time = time + 200 task_manager.actor_update() end Teraz możemy spawnować teleport.Efekt naszej pracy wygląda następująco: • Spawn mutanta (w 3 podstawowych krokach) zawierającego przedmioty - na podst. zadania z Solijanki - zlecanego przez Wieprza "Odzyskać skarb stalkera".Tworzymy plik skryptu -np. my_spawn.script [gamedata/scripts], w którym umieszczamy funkcję: --' Spawn_żarłocznego_mięsaczafunction zgubione_przedmioty()local contr,habrcontr = alife():create("flesh_strong",vector():set(-244.069,-19.549,-128.138),12825,8)repeathabr = alife():object(contr.id)until ( habr~=nil )alife():create("wpn_spas12",habr.position,habr.m_level_vertex_id,habr.m_game_vertex_id,habr.id)alife():create("outfit_exo_m1",habr.position,habr.m_level_vertex_id,habr.m_game_vertex_id,habr.id)alife():create_ammo("ammo_12x70_buck",habr.position,habr.m_level_vertex_id,habr.m_game_vertex_id,habr.id,10)end W powyższej funkcji, przedmioty które otrzymamy - rozpruwając mięsacza: wpn_spas12, outfit_exo_m1, ammo_12x70_buck w ilości 10 szt. Nie musimy ich definiować w configach, ponieważ są to oryginalne itemy. Stosujemy ten sam zabieg - wywołania funkcji dialogiem, korzystam z plikudialogs_escape.xml [gamedataconfiggameplay] i dodaję wpis aktywujący funkcję w szkielecie dialogowym:<action>my_spawn.zgubione_przedmioty</action>Na screenie możemy zobaczyć, iż mięsacz posiada przedmioty, które zespawnowaliśmy w jego wnętrzu. Uwaga!: z tym sposobem zpawnowania przedmiotów - w ciele potwora jest jeden błąd, otóż nie możemy kliknąć "Weź wszystko" ponieważ pojawi się następujący błąd: FATAL ERROR [error]Expression : assertion failed[error]Function : CSafeFixedRotationState::create[error]File : e:stalkerpatch_1_0004xr_3daxrgamephvalidevalues.h[error]Line : 81[error]Description : dBodyStateValide(b) Sposobem na jego ominięcie jest przeciąganie itemów do ekwipunku pojedyńczo - jest to coprawda małe nieudogodnienie, ale nie znalazłem jeszcze sposobu na ominięcie w/w błędu - jeśli takowy znajdę, dam znać w temacie. Przypominam, iż w celu uzyskania kompletnego zestawu plików oraz wpisów (zwłaszcza dot. infoportions czy kwestii dialogowych) - należy zapoznać się z poradnikiem dostępnym pod tym linkiem. W niniejszych przykładach ze skryptami, skupiłem się na elementach dotyczących stricte skryptowania, wraz z uwzględnieniem potrzebnych configów, które dla potrzeb wymienionego w linku poradnika dot. zadań - nie były istotne, stąd podany powyżej przykład zawierający spawn itemów w ciele mięsacza - nie jest rozbudowany. W oparciu o wskazówki poradnika - jesteśmy w stanie stworzyć zadanie zawierające rozwiązania oparte o skryptowy spawn przedmiotów, które nie wymagają dekompilacji pliku all.spawn [Tutorial]: Smart Terrain. Prawa autorskie na podstawie regulaminu, pkt.1.6. - The Emperor, wyłączność: StalkerTeam.__________________________Autor: The Emperor dla StalkerTeam 6 Odnośnik do komentarza Udostępnij na innych stronach Więcej opcji udostępniania...
Rekomendowane odpowiedzi