Skocz do zawartości

[Tutorial] Podstawowe metody spawnowania: ACDC/xr_Spawner/skrypty cz. I


Rekomendowane odpowiedzi

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.zip

Umożliwia określenie współrzędnych: X, Y, Z oraz game_vertex i level_vertex. (opis: link )

Uwagi dot. tekstu ujętego w code

Gdyby 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.7z

Podane 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 ACDC
    post-3466-0-04851900-1372690339_thumb.jp
    Ewentualne 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 + 1
    way_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 = stalker
    • dla 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 stalkerskich
  • name - nazwa obiektu, zawsze dodając obiekt - tworzymy nową nazwę.
  • position (każdy obiekt) - definiuje położenie obiektu. Współrzędne kolejno X,Y,Z
  • direction (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 = trueEND
    W przypadku braku smart_terraina
    [smart_terrains]none = trueEND
  • visual_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. 2
  • upd: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 properties

b) 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).

 

post-3466-0-51950400-1372693625_thumb.jp

 

 

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_Spawner

SoC 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.

 

post-3466-0-79793900-1372696461_thumb.pn

 

  • 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]medkit
  • W 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 = 1
  • Do 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:

 

post-3466-0-07384100-1372703041_thumb.jp

 

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_1
  • W 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:

 

post-3466-0-01289300-1372704677_thumb.jp

 

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 pliku
    dialogs_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.

    post-3466-0-37661700-1372705414_thumb.jp

    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

  • Dodatnia 7
Odnośnik do komentarza
Udostępnij na innych stronach

  • Meta zablokował(a) ten temat
Gość
Ten temat został zamknięty. Brak możliwości dodania odpowiedzi.
×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

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