W tym artykule przedstawię Wam podstawy tworzenia misji/cutscenek do GTA: San Andreas. Istnieje kilka programów do robienia takich rzeczy, ja wybrałem Sanny Builder. Dlaczego akurat ten? Spośród wszystkich programów, ten jest najbardziej rozbudowany i cały czas aktualizowany.
Tworzenie misji w Sanny Builder opiera się na ogromnej ilości funkcji. Oczywiście nie będę tutaj opisywał ich wszystkich. Jeśli będziesz jakiejś potrzebował, zajrzyj do "opcodes". Teraz pora zaopatrzyć się w niezbędne programy.
Sanny Builder - bez tego ani rusz. W nim będziemy pisać oraz kompilować misje.
SA Place Manager - Program do zapisywania współrzędnych (coordsów). Nie koniecznie musisz z niego korzystać, gdyż menadżer coordsów jest też dostępny w Sanny Builder.
Ped Editor - Program do podglądu postaci w San Andreas. Jeśli będziesz chciał użyć konkretnej postaci - sięgnij po ten program.
SA GXT Editor - Program do tworzenia/edycji plików GXT, w których zawarte są teksty, które będziemy mogli wyświetlić podczas gry.
Kliknij na nazwę programu, aby go pobrać (musisz być zalogowany).
Po zebraniu potrzebnych programów możemy przejść do sedna sprawy. Kody będę umieszczał po kawałku i postaram się je dokładnie opisać.
Kod:
DEFINE OBJECTS 0
DEFINE MISSIONS 1
DEFINE MISSION 0 AT @MISJA
DEFINE EXTERNAL_SCRIPTS -1
DEFINE UNKNOWN_EMPTY_SEGMENT 0
DEFINE UNKNOWN_THREADS_MEMORY 0
W powyższym kodzie znajdują się najważniejsze definicje. Pierwsza, definiuje obiekty. Teraz nie będziemy korzystać z żadnych, więc ustawiamy na 0. Druga definicja informuje o ilości misji. W tym artykule zrobimy tylko jedną, więc musimy ustawić na 1. W przypadku większej tworzenia większej ilości misji musimy zwiększyć tą wartość. Trzecia definicja określa misję początkową (ID 0). Więc wpisujemy nazwę misji, która ma startować pierwsza, w tym wypadku jest to MISJA. Następna definicja informuje o ilości skryptów. W naszym wypadku musimy ustawić na -1, gdyż nie mamy żadnych. Ostatnie dwie definicje nie są opisane w dokumentacji.
Po najważniejszych definicjach, następuje "główna sekcja", która nosi nazwę "MAIN", wiadomo dlaczego.
Kod:
thread 'MAIN'
var
$PLAYER_CHAR : Player
end
set_weather 3
00C0: set_current_time 21 00
01F0: set_max_wanted_level_to 6
$PLAYER_CHAR = Player.Create(#NULL, 0.0, 0.0, 0.0)
$PLAYER_ACTOR = Actor.EmulateFromPlayer(
$PLAYER_CHAR)
$PLAYER_CHAR.SetClothes(
"PLAYER_FACE",
"HEAD", Head)
$PLAYER_CHAR.SetClothes(
"JEANSDENIM",
"JEANS", Legs)
$PLAYER_CHAR.SetClothes(
"SNEAKERBINCBLK",
"SNEAKER", Shoes)
$PLAYER_CHAR.SetClothes(
"VEST",
"VEST", Torso)
$PLAYER_CHAR.Build
$PLAYER_CHAR.CanMove(True)
016C: restart_if_wasted at 2027.77 -1420.52 15.99 angle 137.0
unknown 0
016D: restart_if_busted at 1550.68 -1675.49 14.51 angle 90.0
unknown 0
fade 1 (out) 0 ms
start_mission 0
end_thread
Po nazwach funkcji można intuicyjnie domyślić się co one robią. Nie będę opisywał dokładnie każdej z nich, powiem jedynie co one kolejno robią: Ustawia pogodę, ustawia czas, ustawia maksymalny poziom "Wanted" (potocznie mówiąc ilość gwiazdek policyjnych), ustawia ubrania gracza, ustawia miejsce wznowienia gry, gdy gracz zginie lub zostanie złapany. W sekcji "MAIN" można ustawić dużo innych rzeczy, na przykład statystyki (muskuły, stamina itd.). Jeśli chcesz ustawić inną pogodę, bądź inne ubrania, zajrzyj do pomocy programu Sanny Builder. Znajdziesz tam listę z identyfikatorami i nazwami ubrań/pogody/broni/stref itd.
Teraz przyszła pora na napisanie właściwej części naszej misji. W tym miejscu opiszę jak będzie ona wyglądać. Gracz rozpocznie swoją "przygodę" w samochodzie, niedaleko dzielnicy Ganton. Będzie on miał za zadanie dojechać do wydzielonego przez nas miejsca. Po dojechaniu do celu, gracz wysiada z samochodu. Następnym zadaniem jest zabicie pewnego człowieka, który gada ze swoim kolegą. W tym celu, przed graczem leżą 3 bronie, może on wybrać jedną z nich. Po załatwieniu sprawy, misja jest wykonana. Dość prosty scenariusz, idealny na początek. A więc... do dzieła!
Kod:
:MISJA
thread 'MISJA'
0247: request_model 223
0247: request_model 217
0247: request_model #GREENWOO
0247: request_model #micro_uzi
0247: request_model #mp5lng
0247: request_model #tec9
038B: load_requested_models
Pierwsze dwie linijki rozpoczynają procedurę/misje. W dalszej części kodu ładujemy modele postaci, samochodu i broni. Ostatnia linijka ładuje wszystkie modele, które wcześniej okresliliśmy. Zwróć uwagę na opisy, które występują po "//". Są to komentarze. Nie są one interpretowane w żaden sposób przez kompilator. Dobrym zwyczajem jest stosowanie komentarzy, gdyż pomagają one w znalezieniu poszczególnych części kodu.
Kod:
00A5: $WOZ = create_car #GREENWOO at 2288.7903 -1673.1986 14.3883
0175: set_car
$WOZ z_angle_to 358.2751
0229: set_car
$WOZ color_to 2 1
072A: put_actor
$PLAYER_ACTOR into_car
$WOZ driverseat
W pierwszej linijce tworzymy samochód o nazwie "WOZ", wykorzystując wcześniej załadowany model "#GREENWOO" (Greenwood) i ustawiamy go w miejscu o podanych współrzędnych. W drugiej linijce obracamy wcześniej stworzony samochód o 358 stopni. Następnie ustawiamy kolor samochodu na niebiesko biały. Pamiętaj że w nazwach zmiennych (np. $WOZ, $AKTOR, $DOM) nie możesz używać polskich znaków!
Kod:
072A: put_actor
$PLAYER_ACTOR into_car
$WOZ driverseat
02A7: $CEL = create_icon_marker_and_sphere 56 at 2485.9736 -1670.7662 13.0223 radius 3.0
054C: use_GXT_table
'MISJA'
00BC: show_text_highpriority GXT
'TXT1' time 3000 flag 1
W powyższej części kodu najpierw wsadzamy gracza ($PLAYER_ACTOR) jako kierowcę wcześniej stworzonego samochodu "WOZ". Następnie tworzymy sferę (czerwony obszar na mapie) razem z ikoną na radarze o ID 56 (żółte światełko). Sferę ustawiamy w miejscu o podanych współrzędnych (niedaleko domu CJ'a). W 3 linijce zaczynamy używać tekstów z pliku GXT. Wybieramy tabelę o nazwie "MISJA", a następnie wyświetlamy z niej wartość o nazwie "TXT1". Napis będzie widoczny przez 3000 milisekund (3 sekundy). Gdy już raz wybierzesz tabelę z GXT, nie musisz później znów jej wybierać.
Kod:
:petla1
wait 0
if
0103: actor
$PLAYER_ACTOR in_sphere 2485.9736 -1670.7662 13.0223 radius 3.0 3.0 3.0 sphere 0 stopped_in_car
jf @petla1
W tym miejscu tworzymy nową procedurę o nazwie "petla1". W niej czekamy stosujemy instrukcję
wait (jeśli procedura będzie zapętlana to musimy odczekać jakiś czas, w przeciwnym wypadku gra się zawiesi). Wbrew pozorom, parametr
0 też powoduje przerwę. Następnie używamy funkcji if (ang. jeśli). Zaraz po tym sprawdzamy czy gracz znajduje się w sferze, umiesczonej w miejscu o podanych współrzędnych. Parametr "radius" (ang. promień) wyznacza pole, w którym ma się znajdować gracz. Dzięki temu nie musimy dokładnie stanąć w wyznaczonym punkcie, gdyż byłoby to praktycznie nie możliwe. W następnej linijce robimy przeskok do tej samej procedury, jeśli gracz nie będzie w wyznaczonym obszarze.
Kod:
$PLAYER_CHAR.CanMove(False)
fade 0 1000
wait 1000
Marker.Disable(
$CEL)
009A: $OFIARA = create_actor_pedtype 20 model 223 at 2496.8665 -1643.7655 13.7826
009A: $KOLEGA = create_actor_pedtype 4 model 217 at 2498.9758 -1643.5474 13.7826
01B2: give_actor
$OFIARA weapon 26 ammo 20
0639: AS_actor
$OFIARA rotate_to_actor
$KOLEGA
0639: AS_actor
$KOLEGA rotate_to_actor
$OFIARA
0605: actor
$OFIARA perform_animation_sequence
"IDLE_CHAT" from_file
"PED" 4.0 loop 1 0 0 0 -1 ms
0605: actor
$KOLEGA perform_animation_sequence
"IDLE_CHAT" from_file
"PED" 4.0 loop 1 0 0 0 -1 ms
032B: $UZI = create_weapon_pickup #micro_uzi group 5 ammo 50 at 2489.8123 -1663.3979 13.3359
032B: $MP5 = create_weapon_pickup #mp5lng group 5 ammo 30 at 2488.2542 -1663.2462 13.3359
032B: $TEC9 = create_weapon_pickup #tec9 group 5 ammo 50 at 2486.9492 -1662.6134 13.3359
0187: $CEL2 = create_marker_above_actor
$OFIARA
02A3: enable_widescreen 1
fade 1 1000
Ten kod wykona się tylko wtedy, gdy gracz już znajdzie się w wyznaczonym wcześniej obszarze. Najpierw uniemożliwiamy graczowi ruch. Następnie zaciemniamy płynnie obraz i czekamy 1 sekundę (zaczniemy robić pozostałe rzeczy jak już obraz zaciemni się do końca). Usuwamy czerwoną sferę, gdyż już nie jest nam potrzebna. Zaraz po tym tworzymy dwóch aktorów: "OFIARA" i "KOLEGA". Pierwsza wartość "20" u ofiary oznacza typ postaci, w tym wypadku jest to kryminalista, natomiast koledze dajemy typ 4, cywil. W dalszej części funkcji okreslamy model postaci, który na początku załadowaliśmy. Obydwie postacie pojawiają się w miejsach o wyznaczonych współrzędnych. Następnie dajemy ofierze broń o ID 26 (sawnoff) z ilością nabojów równą 20. Po tym każemy ofierze odwrócić się do kolegi, a koledze odwrócić się do ofiary. Później animujemy aktorów, stosując animację "IDLE_CHAT" z pliku "PED". Następnie tworzymy pick-upy broni, które będzie mógł podnieść gracz. Określamy tam model broni, którą także wcześniej załadowaliśmy, grupę, amunicję i pozycję. W następnej linijce tworzymy marker (strzałkę, oznaczenie) nad aktorem o nazwie "OFIARA". W przedostatniej linijce włączamy ekran "kinowy", charakterystczny dla cutscenek, przerywników. Wszystkie te operacje wykonaliśmy z przyciemnionym ekranem, po to żeby gracz nie widział pojawiania się obiektów, aktorów. Teraz trzeba przywrócić ekran do poprzedniego stanu, co robimy w ostatniej linijce.
Kod:
Camera.SetPosition(2489.7737, -1655.042, 13.3536, 0.0, 0.0, 0.0)
Camera.OnVehicle(
$WOZ,15,2)
00BC: show_text_highpriority GXT
'TXT2' time 3000 flag 1
wait 3000
Camera.SetPosition(2497.2175, -1649.142, 14.5602, 0.0, 0.0, 0.0)
Camera.OnPed(
$OFIARA,15,2)
00BC: show_text_highpriority GXT
'TXT3' time 2000 flag 1
wait 2000
02A3: enable_widescreen 0
$PLAYER_CHAR.CanMove(True)
015A: restore_camera
W poprzednim kodzie ustawiliśmy ekran "kinowy", gdyż teraz chcemy przedstawić zadanie do wykonania. Ustawiamy kamerę w miejscu o określonych współrzędnych i obracamy ją w kierunku samochodu "WOZ". Pokazujemy tekst z pliku GXT i tabeli "MISJA" (wcześniej jej używaliśmy to teraz też możemy) o nazwie "TXT2". Ten tekst wyświetlamy 3 sekundy, więc teraz musimy odczekać, zanim zrobimy następną rzecz. Ustawiamy kamerę w innym miejscu i obracamy ją do aktora o nazwie "OFIARA". Następnie wyświetlamy tekst o nazwie "TXT3" przez 2 sekundy. Czekamy... i przywracamy ekran do porzpedniego stanu (wyłączamy ekran "kinowy"). Spowrotem pozwalamy graczowi poruszać się i przywracamy kamerę do pierwotnego stanu (widok zza pleców gracza).
Kod:
:petla2
wait 0
if
02E0: actor
$PLAYER_ACTOR aggressive
jf @petla3
01B9: set_actor
$OFIARA armed_weapon_to 26
05E2: AS_actor
$OFIARA kill_actor
$PLAYER_ACTOR
:petla3
wait 10
if
0118: actor
$PLAYER_ACTOR dead
jf @petla4
00BA: show_text_styled GXT
'M_FAIL' time 5000 style 1
Marker.Disable(
$CEL)
Marker.Disable(
$CEL2)
00A6: destroy_car
$WOZ
009B: destroy_actor
$OFIARA
009B: destroy_actor
$KOLEGA
0215: destroy_pickup
$UZI
0215: destroy_pickup
$MP5
0215: destroy_pickup
$TEC9
start_mission 0
:petla4
wait 10
if
0118: actor
$OFIARA dead
jf @petla2
01E3: show_text_1number_styled GXT
'M_PASS' number 100 time 5000 style 1
0109: player
$PLAYER_CHAR money += 100
0394: play_music 1
Marker.Disable(
$CEL2)
end_thread
Tworzymy kolejną procedurę, tym razem o nazwie "petla2". Robimy następną konstrukcję if i tym razem sprawdzamy czy gracz jest agresywny. Jeśli nie, to przeskocz do następnej procedury o nazwie "petla3". Następnie jest kod, który wykona się tylko wtedy, jeśli spełni się warunek podany poprzedni (czy gracz jest agresywny). Wybieramy ofierze broń, którą wcześniej mu daliśmy. Następnie każemy ofierze zabić gracza. Zaraz po tym tworzymy nową procedurę o nazwie "petla3" (przeskakiwaliśmy do niej, gdy gracz nie był agresywny). W niej jest następny warunek, tym razem sprawdzamy czy gracz jest martwy. Jeśli tak, wyświetl napis "MISSION FAILED" przez 5 sekund. Następnie usuwamy samochód, aktorów i pickupy, gdyż już ich nie potrzebujemy. Po "zatarciu śladów", rozpocznij misję od nowa. Jeśli natomiast gracz będzie wciąż zył to przeskakujemy do procedury "petla4". W niej sprawdzamy czy ofiara jest martwa. Jeśli tak to wyświetlamy napis "MISSION PASSED" przez 5 sekund, jednocześnie dodając 100$ do konta gracza oraz odtwarzamy odpowiednią muzykę, a następnie usuwamy marker z ofiary. Ostatnią linijką kończymy misję i jednocześnie cały plik.
Gdy mamy już gotowy skrypt, czas go zapisać i skompilować. W tym celu wybieramy z menu programu "Uruchom/Kompiluj". Skompilowany plik pojawi się w tym samym folderze co plik źródłowy skryptu, chyba że zmienisz to w ustawieniach. Zauważ że jest tam jeszcze opcja "Kompiluj + Kopiuj". Po wybraniu jej, program kompiluje skrypt i kopiuje go od razu do plików gry, dzięki temu nie musimy już później podmieniać plików, wszystko robi za nas program. Po pomyślnej kompilacji powinniśmy ujrzeć okienko, podobne do tego:
Skompilowany plik musimy wkleić do folderu "[katalog_z_grą]data/script/" pod nazwą "main.scm", natomiast plik GXT do "[katalog_z_grą]text/" pod nazwą "american.gxt". Poniżej zamieszczam kilka screenów z misji:
- Kod Źródłowy
- Skompilowany plik
- Plik GXT
Początki zawsze są trudne i nie należy się zniechęcać jak coś nie wychodzi. Robienie misji do GTA nie należy do najłatwiejszych czynności, więc trzeba poświęcić na to trochę czasu.
Posting comments to this article is disabled.