RkBlog

Hardware, programming and astronomy tutorials and reviews.

Tworzenie własnych NPC w weidu

Zaczniemy od rzeczy przyjemnych i łatwych. Uruchom BG II i stwórz postać. Najlepiej gdy rozpoczniesz grę dla wielu graczy (port szeregowy, ty jesteś jedynym graczem) a postać przeznaczona na NPC nie będzie postacią główną (dziecięciem Bhaala). Tworząc postać nie przejmuj się cechami czy biegłościami. Wszystko będzie można potem zmienić. Postaci tej możesz dać własne fotki. Wystarczy wrzucić je do katalogu Portraits. Zestawy takich portretów możesz ściągnąć z Sorcerers.net. Gdy już gra rozpoczęta możesz dodać swojej postaci poziomów (przez konsolę kodów), dać jakieś przedmioty (choć to wszystko można zrobić później przez odpowiedni program). Eksportujemy postać.
Ja stworzyłem mnicha o imieniu Grimnosh i wyeksportowałem go jako 0grim.

Teraz tak. Tworzymy sobie gdzieś jakiś katalog, w którym będziemy trzymać pliki naszego "moda", ja stworzyłem sobie katalog "mnich". W tym katalogu tworzymy podkatalog, ja swój nazwałem 4 (bo miało być 4 NPC :P). Do tego podkatalogu wrzucamy obecnie 2 pliki portretu postaci (mały i duży). Jeżeli są to portrety zawarte w BG II to tego robić nie musimy.

Ściągamy sobie WeiDu z Weidu.org oraz NearInfinity (jest w dziale download). Przydać się może również ShadowKeeper (jest na sorcerers.net).Rozpakowujemy WeiDu i plik WeiDu.exe wrzucamy do katalogu BG II. Instalacja NearInfinity opisana jest w artykule "wstęp do tworzenia modów".

Uruchamiamy NearInfity, wchodzimy do katalogu "Characters" i plik naszej wyeksportowanej postaci (u mnie 0grim.chr) podświetlamy. Na poziomym menu na górze bierzemy "File" i wybieramy opcję "Convert CHR to CRE". Plik zapisujemy w katalogu Override. Teraz wychodzimy z NearInfinity i wchodzimy do ShadowKeepera (jak nie mamy to może być znowu NearInfinity, wyjść trzeba by program zobaczył nowy plik). W ShadowKeeperze bierzemy "View" a następnie "Creature Browser". Szukamy naszego pliku cre i otwieramy go. Teraz możemy zmieniać go do woli, np polepszyć Thac0, dodać jakieś przedmioty, zdolności wrodzone itp. Zapisujemy go. Teraz otwieramy go w NearInfinity (będzie w katalogu "override").
Bierzemy zakładkę "edit". Jak widzicie można tutaj również edytować jego parametry. Następujące żeczy musimy zmienić!: "ENEMY-ALLY" - wybieramy "Neutral", "DIALOG" - tutaj wybierzemy nasz dialog dla NPC. Na razie go nie ma więc nic tu nie ruszamy.
Wrzucamy plik cre do naszego podkatalogu (tam gdzie są ewentualne fotki).

Dialog

W naszym podkatalogu tworzymy plik txt o dowolnej nazwie (chociaż powinna być powiązana z nazwą npc, ja nazwałem go 0grim). Po zapisaniu zmieniamy jego rozszerzenie z txt na "d" tj. będzie 0grim.d
Plik ten nadal możemy edytować tak jak plik tekstowy (przez notatnik). Teraz zaczynamy pisać plik dialogu dla WeiDu, pokażę to na przykładzie pliku 0grim.d, oto cała zawartość pliku:

BEGIN 0grim
IF ~NumTimesTalkedTo(0)~ THEN BEGIN FirstMeeting
SAY ~Witaj! Jestem Grimnosh.~


IF ~~ THEN REPLY ~Witam. Możesz przedstawić się?~ GOTO Powitanie
IF ~Class(Player1,MONK)~ THEN REPLY ~O, widzę że kolega po fachu!~ GOTO BothMonks
IF ~~ THEN REPLY ~Zejdź mi z oczu śmieciu!~ GOTO GoAway
END

IF ~~ THEN BEGIN BothMonks
SAY ~No proszę, dwóch prawdziwych wojowników w jednym mieście. Może zabawimy się wspólnie?~
IF ~~ THEN REPLY ~Zapowiada się ciekawie. Wskakuj do ekipy Bracie!~ DO ~SetGlobal("0grimJoined","LOCALS",1)
JoinParty()~ EXIT
IF ~~ THEN REPLY ~Nie, nie teraz.~ GOTO GoAway
END

IF ~~ THEN BEGIN Powitanie
SAY ~Jestem Grimnosh, mnich zakonu Mroźnego Dotyku. Niecały rok temu opuściłem północne krainy, mój dom, by zdobyć wiedzę i umiejętności potrzebne by służyć Mroźnej Pani, Auril. W czasie wędrówki przyłączałem się do drużyn poszukiwaczy przygód w ich wyprawach po skarby i sławę służąc im mymi zdolnościami i umiejętnościami, które zarazem doskonaliłem... Czy chcesz abym dołączył do twojej drużyny? Widzę że nie jesteś przeciętnym frajerem ze scyzorykiem.~
IF ~~ THEN REPLY ~A ja widzę że nie jesteś mnichem tylko z nazwy. Witaj w drużynie.~ DO ~SetGlobal("0grimJoined","LOCALS",1)
JoinParty()~ EXIT
IF ~~ THEN REPLY ~Raczej nie.~ GOTO GoAway
END


IF ~~ THEN BEGIN GoAway
SAY ~Jak sobie życzysz , będę oczekiwał twojego powrotu.~
IF ~~ THEN EXIT
END

IF ~NumTimesTalkedToGT(0)~ THEN BEGIN ReturnDialogue
SAY ~Widzę, że wróciłeś.~
IF ~~ THEN REPLY ~Tak, potrzebuję ciebie w mojej drużynie.~ DO ~SetGlobal("0grimJoined","LOCALS",1)
JoinParty()~ EXIT
IF ~~ THEN REPLY ~Tak, ale nadal nie potrzebuję ciebie.~ GOTO RefusedAgain
END

IF ~~ THEN BEGIN RefusedAgain
SAY ~Szkoda, chyba golnę sobie trochę nalewki rzepowej.~
IF ~~ THEN EXIT
END

BEGIN 0grimP
IF ~Global("0grimJoined","LOCALS",1)~ THEN BEGIN KickOut
SAY ~Czy mam opuścić tą drużynę?~
IF ~~ THEN REPLY ~Oj, pomyńka, nie ty.~ DO ~JoinParty()~ EXIT
IF ~~ THEN REPLY ~Tak, już ciebie nie potrzebuję~ DO ~SetGlobal("0grimJoined","LOCALS",0)~ EXIT
END

IF ~Global("0grimJoined","LOCALS",0)~ THEN BEGIN Rejoin
SAY ~Mam spowrotem dołączyć do ciebie?~
IF ~~ THEN REPLY ~Tak jest!~ DO ~SetGlobal("0grimJoined","LOCALS",1)
JoinParty()~ EXIT
IF ~~ THEN REPLY ~Nie, nie rób sobie nadziei.~ EXIT
END

Straszne? Nie sądzę.... już tłumaczę

BEGIN 0grim - to mówi WeiDu by stworzył plik 0grim.dlg (plik dialogu postaci). 0grim to nazwa naszego pliku, więc możesz ją zmieniać jak chcesz.

IF ~NumTimesTalkedTo(0)~ THEN BEGIN FirstMeeting - to warunek dla pierwszego spotkania (jeżeli pierwszy raz się widzą to odpal ten dialog poniżej)

SAY ~Witaj! Jestem Grimnosh.~ - To powie nasz NPC

IF ~~ THEN REPLY ~Witam. Możesz przedstawić się?~ GOTO Powitanie
IF ~Class(Player1,MONK)~ THEN REPLY ~O, widzę że kolega po fachu!~ GOTO BothMonks
IF ~~ THEN REPLY ~Zejdź mi z oczu śmieciu!~ GOTO GoAway
END
1 linijka to pierwsza możliwa odpowiedź naszej postaci i jej efekt - jeżeli wybiorę możliwość 1. "Witam. Możesz przedstawić się?" to dialog przejdzie do "bloku" "Powitanie"(tj. kolejnego takiego czegoś z tekstem NPC i kilkoma możliwościami odpowiedzi).
2 linijka będzie dostępna gdy nasza główna postać jest również mnichem. Jeżeli ją wybierzemy to przejdziemy do bloku o nazwie "BothMonks" - czyli obaj mnisi. Gdybyśmy robili druida i też chcielibyśmy linię dialogu gdy nasza główna postać jest druidem to zamiast Class(Player1,MONK) trzeba by było dać Class(Player1,DRUID) to samo dla np. paladyna (PALADIN), czarownika (SORCERER) itp.
3 linijka to przykład zakończenia dialogu, dialog przejdzie do bloku "GoAway" - w którym umieszczone jest pożegnanie :)
4 linijka czyli END kończy "blok".

Sumując to wszystko zróbmy szablon bloku:
IF ~NumTimesTalkedTo(0)~ THEN BEGIN FirstMeeting
SAY ~TEKST NPC~
IF ~~ THEN REPLY ~1 ODPOWIEDŹ NASZA~ GOTO BLOK A
IF ~~ THEN REPLY ~2 ODPOWIEDŹ NASZA~ GOTO BLOK B (itd :)
IF ~Class(Player1,NAZWAKLASY)~ THEN REPLY ~ODPWIEDŹ NASZA GDY KLASY TAKIE SAME~ GOTO BLOK X
IF ~~ THEN REPLY ~ODPOWIEDŹ POŻEGNALNA~ GOTO BLOK pożegnalny
END
Oczywiście opcje dialogu typu IF ~Class(Player1,NAZWAKLASY)~ THEN REPLY .... są opcjonalne, nie muszą się znajdować w dialogu.
Gdy mamy dialog powitalny to musimy teraz stworzyć wszystkie bloki do jakich się on odwołuje, tj weźmy 1 linijkę: IF ~~ THEN REPLY ~Witam. Możesz przedstawić się?~ GOTO Powitanie
Robimy blok powitanie:
IF ~~ THEN BEGIN Powitanie
SAY ~Jestem Grimnosh, mnich zakonu Mroźnego Dotyku. Niecały rok temu opuściłem północne krainy, mój dom, by zdobyć wiedzę i umiejętności potrzebne by służyć Mroźnej Pani, Auril. W czasie wędrówki przyłączałem się do drużyn poszukiwaczy przygód w ich wyprawach po skarby i sławę służąc im mymi zdolnościami i umiejętnościami, które zarazem doskonaliłem... Czy chcesz abym dołączył do twojej drużyny? Widzę że nie jesteś przeciętnym frajerem ze scyzorykiem.~
IF ~~ THEN REPLY ~A ja widzę że nie jesteś mnichem tylko z nazwy. Witaj w drużynie.~ DO ~SetGlobal("0grimJoined","LOCALS",1) JoinParty()~ EXIT
IF ~~ THEN REPLY ~Raczej nie.~ GOTO GoAway
END
Teraz tak. IF ~~ THEN BEGIN Powitanie - "tytuł" bloku (IF ~~ THEN BEGIN [nazwa bloku tutaj]). Musimy pamiętać o zastosowaniu takich samych nazw bloków jakie użyliśmy wcześniej (jak tam było GOTO Powitanie, to tytuł też musi być Powitanie)
SAY ~ - To powie NPC
~ DO ~SetGlobal("0grimJoined","LOCALS",1)JoinParty()~ EXIT
- to jest "polecenie" przyłączenia NPC do drużyny. W miejsce 0grim wpisujemy nazwę naszego pliku cre. EXIT - kończy dialog
IF ~~ THEN REPLY ~Raczej nie.~ GOTO GoAway - znana konstrukcja, odpowiedź i instrukcja udania się do bloku GoAway

Dalej robimy blok "pożegnalny":
IF ~~ THEN BEGIN GoAway
SAY ~Jak sobie życzysz , będę oczekiwał twojego powrotu.~
IF ~~ THEN EXIT
END
- jeżeli NPC rozmawia z babą to powie "Pani" jeżeli z facetem to "Panie" :)
IF ~~ THEN EXIT
- kończy dialog (kliknięcie "zakończ dialog")

HURRA mamy już dialog na "1 spotkania". Teraz jeszcze dialog gdy nie przyłączymy NPC za pierwszym razem:
IF ~NumTimesTalkedToGT(0)~ THEN BEGIN ReturnDialogue
SAY ~Widzę, że wróciłeś.~
IF ~~ THEN REPLY ~Tak, potrzebuję ciebie w mojej drużynie.~ DO ~SetGlobal("0grimJoined","LOCALS",1)
JoinParty()~ EXIT
IF ~~ THEN REPLY ~Tak, ale nadal nie potrzebuję ciebie.~ GOTO RefusedAgain
END
Wszystko jest tu znane oprócz IF ~NumTimesTalkedToGT(0)~ THEN BEGIN ReturnDialogue - jest to "znacznik" dla dialogu który ma być rozpoczęty tylko wtedy, gdy rozmawialiśmy już z tym NPC. Blok RefusedAgain macie powyżej, w całym pliku .d
BEGIN 0grimP - To odnosi się do dialogu wykopania. Skpiujcie po prostu wszystko od tego Begin do końca pamiętając by dać swoje nazwy:)
99% zrobione:D Robiąc swój plik .d skopiuj ten, pozmieniaj nazwy cre, a potem zmieniaj teksty dialogów itp. Teraz wracamy do naszego pliku cre. Do override wrzucamy jakiś plik txt i zmieniamy jego nazwę na nazwę naszego przyszłego pliku dialogowego (to co mamy w BEGIN pliku .d) oraz nadajemy rozszerzenie dlg. Odpalamy NearInfinity i edytujemy nasz plik CRE. Wybieramy nasz plik dlg i zapisujemy CRE. Pod którymś ze "SCRIPTS" może być jakiś plik BCS. wybieramy NONE ! (wpisać a on znajdzie tą opcję).
Do naszego podkatalogu wrzucamy plik .d oraz .cre.
Kopiujemy plik WeiDu.exe do naszego Katalogu (nie podkatalogu) i zmieniamy jego nazwę na Setup-coś.exe gdzie coś to nasza wybrana nazwa :). Tworzymy plik txt i zmieniamy go na Setup-coś.tp2 (te same "coś'e" oczywiście), w podkatalogu tworzymy podkatalog backup.

Teraz piszemy w pliku tp2 (na przykładzie Grimnosha):
BACKUP ~4 ackup~ --Katalog na kopię plików które muszą zostać zastąpione
AUTHOR ~www.pcrpg.prv.pl~ --autor :)
BEGIN ~Monk~ -- Nazwa moda. WeiDu napisz przy instalacji "Install component "Monk" ?

COPY ~4\DrfM4L.bmp~ ~override\DrfM4L.bmp~ -Kopiowanie fotek (zewnętrznych, nie z BGII)
COPY ~4\DrfM4s.bmp~ ~override\DrfM4s.bmp~
COPY ~4grim.cre~ ~overridegrim.cre~ - Kopiowanie pliku cre
SAY NAME1 ~Grimnosh~ - Imię NPC
SAY NAME2 ~Grimnosh~
SAY SELECT_COMMON4 ~Blah blah blah.~ [Female1] --Tu zaczynają się dźwięki, Tekst między ~ pojawi się w okienku dialogowym, a [Female1] oznacza nazwę pliku wav jaki NPC wykorzystuje. Tutaj nie jest on dobrany, gdyż skojarzenie od czego dany plik wav jest zajmuje trochę czasu, a można to zrobić błyskawicznie wybierając zestaw dźwięków po przyłączeniu NPC do drużyny, dałem Female (tj, odgłos BGII kobiecy któryś tam, by coś było :P)...
SAY SELECT_COMMON5 ~Za Auril.~ [Female2]
SAY SELECT_COMMON6 ~Gdzie?.~ [Female3]
SAY SELECT_ACTION1 ~Już lecę.~ [Female4]
SAY SELECT_ACTION2 ~Idę.~ [Female5]

COMPILE ~4grim.d~ - przemienia plik .d na .dlg
USING ~~

Czyli tworząc plik tp2 musisz dać a) pliki do przeniesienia, b) kompilację pliki .d i c) przeniesienie i opis pliku .cre. Dla ułatwienia cały plik tp2 Grimnosha:


BACKUP ~4 ackup~
AUTHOR ~www.pcrpg.prv.pl~
BEGIN ~Monk~

COPY ~4\Ar0515.are~ ~override\Ar0515.are~
COPY ~4\DrfM4L.bmp~ ~override\DrfM4L.bmp~
COPY ~4\DrfM4s.bmp~ ~override\DrfM4s.bmp~
COPY ~4grim.cre~ ~overridegrim.cre~
SAY NAME1 ~Grimnosh~
SAY NAME2 ~Grimnosh~
SAY SELECT_COMMON4 ~Blah blah blah.~ [Female1]
SAY SELECT_COMMON5 ~Za Auril.~ [Female2]
SAY SELECT_COMMON6 ~Gdzie?.~ [Female3]
SAY SELECT_ACTION1 ~Już lecę.~ [Female4]
SAY SELECT_ACTION2 ~Idę.~ [Female5]

COMPILE ~4grim.d~
USING ~~

Jak widzisz pojawiła się jeszcze jedna linijka COPY ~4\Ar0515.are~ ~override\Ar0515.are~ - to zmodyfikowany w NearInfinity plik jednego z obszarów. Pliki ARE przetrzymują gdzie są przedmioty, pułapki i osoby!. Otwieramy NearIninity i idziemy do "katalogu" ARE. Wybieramy jakiś małą planszę na której jest jakiś wieśniak lub coś tym stylu (ktoś, kto nie jest do niczego potrzebmy). AR0515 to najwyższe piętro karczmy Delarosa w dzielnicy mostów :) Możecie skorzystać z niego. Bierzemy w NearInifity zakładkę EDIT i zjeżdżamy na dół aż znajdziemy "ACTOR". Klikamy na jednego 2 razy. Kliknąłem na 1 i okazało się że jest to "Marynarz" czyli do niczego nie potrzebna osoba :) Zmieniamy: "CHARACTER" na nasz plik cre, "DIALOG" - na nasz plik dlg. Zapisujemy Plik Are (jeżeli klikniemy na inny plik are to zapyta się czy zachować zmiany).

Przenosimy nasz zmodyfikowany plik are do podkatalogu z plikami moda. Z OVERRIDE usuwamy lipny plik dlg, plik cre (wszystkie, które edytowaliśmy)
Wrzucamy do katalogu BG II podkatalog z plikami moda oraz pliki SETUP-coś.exe i .tp2. URUCHAMIAMY exe, bierzemy Y i mod powinien się zainstalować.
"Nowa gra" (przed uruchomieniem gry, w pliku baldur ini pod Game Options wpisujemy Debug Mode=1) i:
Wciskamy CTRL+Spacja i piszemy: CLUAConsole:MoveToArea("AR0515") i enter. To przeniesie nas od razu do obszaru 0515, gdzie jest nasz NPC, jeżeli wszystko jest OK, będzie tam :)
RkBlog

Modowanie Silnika Infinity, 14 July 2008, Piotr Maliński

Comment article