Dialogi
Żeby napisać dialog dla postaci, potrzebować będziesz dwóch plików. Jeden to plik tekstowy, który będzie zawierać, cały tekst dialogu, drugi będzie skryptem postaci określającym kiedy i co postać powie. Będą one miały ta sama nazwę, ale plik tekstowy będzie nazwany NAME.msg, a plik skryptu NAME.int. Plik tekstowy będzie umieszczony w folderze data\text\english\dialog, tam gdzie zainstalowany jest Fallout. Plik skryptu zostanie umieszczony w folderze data\scripts.
Plik tekstowy wygląda w taki sposób:
{100} {} {Linia dialogu}
{101} {} {Inna linia dialogu}
I tak dalej. Nie jest istotne w jakiej kolejności są linie, ale ich numery musza być niepowtarzalne dla każdej linii dialogu. To jest łatwa część. Skrypt będzie określał, która linia/linie dialogu pokażę się w określonym momencie. To jest trudniejsza część.
Pierwsza rzeczą, której będziesz potrzebować w skrypcie jest procedura talk_p_proc Ta procedura będzie wywołana kiedy gracz spróbuje rozpocząć rozumowe z critterem (jakąś postacią w grze, choć nie koniecznie musi to być człowiek.. A możliwe jest rozmawiać nawet z elementem scenografii heh
) Podstawowa procedura będzie wyglądać następująco:
procedure talk_p_proc begin
start_gdialog(NAME,self_obj,4,-1,-1);
gSay_Start;
call Node001;
gSay_End;
end_dialogue;
end
Możesz się rozejrzeć w instrukcji mappera, co inne komendy robią, ale główna rzecz na którą zwróć uwagę jest linia: call Node001. Ona wywoła procedurę rozpoczęcia dialogu. Więc napiszemy tryb Node001.
procedure Node001 begin
Reply(100);
NOption(101,Node999,004);
end
Linia: Reply(100) oznacza co NPC (postać inna niż gracz) powie w linii pliku tekstowego oznaczonego numerem 100. Natomiast: NOption(101,Node999,004) określa co gracz ma do powiedzenia, a zawiera się to w pliku tekstowym pod numerem 101 jeśli jego inteligencja jest większą niż 4, potem procedura Node999 będzie wywołana. Procedura Node999 jest zawsze procedura, która kończy dialog. Mamy teraz kompletny chociaż dość krotki dialog. Napiszmy teraz następną procedurę:
procedure Node002 begin
Reply(103);
NOption(104, Node999, 004);
end
i zmieńmy procedurę Node001 na:
procedure Node001 begin
Reply(100);
NOption(102,Node002,006);
NOption(101,Node999,004);
end
Teraz w Node001 gracz ma opcje powiedzieć linie 102, jeśli jego inteligencja jest lepsza niż 6. Jeśli to powie: Node002 będzie wywołane co da w rezultacie wypowiedzenie przez NPC linii 103 po tym gracz ma jedynie do wyboru powiedzieć to co zawarte jest w linii 104. Tak to w uproszczeniu wygląda. Pisanie dialogów to łączenie rożnych nodes w drzewie dialogu jednych z drugimi (trzeba to sobie trochę rozplanować zanim zacznie się pisać).
Reply, NOption i numer innego dialogu odnosi się do komend makr gSay/giQ spokrewnione komendy. Tutaj jest kompletny opis najważniejszych gSay komend:
Name: gSay_Message
Returns: void Dialog (pusty dialog)
Arguments:
msg_list (int)
msg_num (int)
reaction (int)
Ustawia sayMessage, które odpowiada zwykła opcje [Done]. msg_list determinuje, który plik wiadomości jest pokazany, a msg_num określa która linia jest użyta z tego pliku.
Name: gSay_Option
Returns: void Dialog
Arguments:
msg_list (int)
msg_num (int)
target (procedure)
reaction (int)
Ustawia opcje wyboru dla blokady odpowiedzi, dostaje linie z pliku wiadomości (msg_list) i numer wiadomości (msg_num), który spowoduje reakcje (reaction) i jeśli zostanie wybrane skoczy do danej (target) procedury. (mam nadzieje ze to chwytacie, jak by co zajrzyjcie do oryginalnego tekstu :-p)
Name: gSay_Reply
Returns: void Dialog
Arguments:
msg_list (int)
msg_num (int)
Ustala blokadę odpowiedzi (co Critter powie)
Name: giQ_Option
Returns: void Dialog
Arguments:
iq_test (int)
msg_list (int)
msg_num (int)
target (procedure)
reaction (int)
Ustawia opcje wyboru dla blokady odpowiedzi jeśli statystyka IQ gracza jest równa lub większa od podanej wartości (iq_test) dostaje linie z pliku wiadomości (msg_list) i numer wiadomości (msg_num), któro spowoduje otrzymanie reakcji (reaction) i jeśli będzie wybrane skoczy do danej (target) procedury.
Autor: Daniel Sjoblom 2004 (mam nadzieję, że zrozumiale przetłumaczyłem Lich)
(Skonsultowałem się z Jargo i postanowiłem nieco dopisać, żeby wszystko stało się jaśniejsze- w powyższym tekście jak się okazało nie jest wszystko wytłumaczone).
Skąd program wie, który tekst dialog.msg ma wyświetlić?
Właśnie w tej stałej NAME jest określone z którego pliku msg skryptu ma dialog korzystać (bo może korzystać z plików msg innych skryptów, ale nie będę o tym pisał, żeby Ci nie zamącić :D ).
Definicje znajdziesz w hedersach (czyli plikach nagłówkowych) w pliku scripts.h znajdziesz deklaracje wszystkich skryptów. Ta deklaracja to po postu numer skryptu.
Najprościej mówiąc: każdy skrypt w Fallu ma swój unikalny numer (standartowo są to numery od 0 do 1304). Każdy skrypt z kolei ma jeden plik msg z tekstami, o takiej samej nazwie jak on sam (acklint.int ma plik o nazwie acklint.msg) różnią się tylko rozszerzeniem.
Aby dostać się do tekstu w pliku msg należy podać numer skryptu do którego należy ten plik msg, czyli jeżeli chcesz wyświetlić tekst z pliku acklint.msg, to musisz podąć numer skryptu acklint.int.
No dobra, powiesz: To czemu nie wiedzę tych numerów w skrypcie?. Ano dlatego, że programiści interplaya sobie ułatwili sprawę i używają definicji NAME, która w rzeczywistości jest numerem aktualnego skryptu.
Jeżeli chcesz dodać swój własny skrypt, musisz go zarejestrować (przeczytaj tekst na ten temat na FMC) w plikach scripts.lst i scripts.h, a następnie zmienić definicję NAME z SCRIPT_ACKLINT na jakiś nowy, który wpisałeś w scripts.h.
Potem juz tworzysz plik msg o nazwie jak Twój skrypt tylko z rozszerzeniem msg tam dajesz wszystkie teksty i przegrywasz do folderu dialog.
Skrypt powinien działać dobrze.
Największym problemem podczas pisania dialogów jest to, że mamy do czynienia z dwoma plikami. W jednym opisana jest procedura, w którymś momencie postać coś powie (plik .lst), a w drugim określa co powie (plik .msg); więc można się pogubić, lub łatwo popełnić błąd. Istnieje jednak bardzo łatwe rozwiązanie tego problemu- otóż program czyta tylko zawartość tekstów umieszczonych w nawiasach pliku msg., węc w nim dokonamy połączenia danych z obu plików :-D To w nim można projektować własny złożony i długi dialog. Wszystkie linijki procedur można pozostawić- nie wpłynie to na pojawienie się błędów podczas gry. Błąd pobierania dialogu jaki zauważyłem to sytuacja w której nie domknie się jednego z nawiasów {} (tak ułożony tekst można potem wkleić do .lst usuwając jednak zawartość dialogu- wszystkie teksty w nawiasach) Wyglądać to będzie mniej, więcej w ten sposób (na podstawie rozmowy z klintem: acklint) autor: Lich
procedure Node001 begin
Reply(mstr(103)+obj_name(dude_obj)+mstr(104));
{103}{}{Witaj, }
{104}{}{. Nie możesz przejść, twoja próba jeszcze się nie zakończyła.}
NLowOption(105,Node002);
{105}{}{Uch...}
NOption(106,Node003,004);
{106}{}{Muszę wrócić do wioski.}
NOption(107,Node004,004);
{107}{}{Chcę zadać ci kilka pytań.}
NOption(108,Node999,004);
{108}{}{Dobra, idę przejść tę próbę.}
end
procedure Node002 begin
Reply(mstr(109)+obj_name(dude_obj)+mstr(110));
{109}{}{(westchnienie) }
{110}{}{. Idź do Świątyni. Ukończ próbę. Nie wracaj tu więcej! To rozkaz Starszej. Idź!}
NLowOption(111,Node999);
{111}{}{Moja iść.}
end
procedure Node003 begin
Reply(mstr(112)+obj_name(dude_obj)+mstr(113));
{112}{}{Wybacz mi, }
{113}{}{, ale nie mogę Cię przepuścić. Jeśli chcesz wrócić do wioski, musisz ukończyć próbę, która czeka na ciebie w Świątyni.}
NOption(114,Node999,004);
{114}{}{Rozumiem. Do zobaczenia.}
NOption(115,Node004,004);
{115}{}{Dobrze, ale czy mogę zadać Ci kilka pytań, nim przejdę próbę?}
NOption(116,Node005,004);
{116}{}{Mogę po prostu skopać Ci tyłek i przejść po Tobie...}
end
procedure Node004 begin
Reply(117);
{117}{}{Wybacz, ale nie znam odpowiedzi na Twoje pytania. Przejdę próbę, którą wyznaczyła Ci Starsza i udowodnij nam, że jesteś Dzieckiem Przeznaczenia, godnym, by poprowadzić nasz lud.}
NOption(118,Node999,004);
{118}{}{Dobrze.}
end
procedure Node005 begin
Reply(119);
{119}{}{Aby przesunąć obelisk zagradzający drogę, potrzeba dwóch ludzi. Samotnie niewiele zdziałasz. Nie mam zamiaru Ci pomóc, póki nie udowodnisz, że jesteś Dzieckiem Przeznaczenia!}
NOption(120,Node999,004);
{120}{}{Y-hy. Już wszystko rozumiem.}
end
procedure Node006 begin
Reply(121);
{121}{}{Witaj, Dziecko Przeznaczenia! Jak miło mi Cię spotkać! Czym mogę Ci służyć?}
NLowOption(122,Node007);
{122}{}{Moja cześć. To wszystko!}
NOption(123,Node007,004);
{123}{}{Jestem tu, żeby się pożegnać, nim wyruszę ze swą misję.}
end