Do pisania skryptów w GTA IV będziemy potrzebować silnika, który nam dostarczy wszystko czego potrzebujemy. Jest ich kilka, ale jako przykład dam
Alice autorstwa
Alexandra Blade'a, który bazuje na języku skryptowym
LUA. Niektórzy być może kojarzą go z tworzenia map do MTA.
Na marginesie powiem, że jest możliwość tworzenia tego typu skryptów w języku C++ dzięki specjalnym bibliotekom.
Najpierw ściągnij pliki silnika stąd:
-
Alice
Następnie skopiuj zawartość katalogu
copy do głównego katalogu z GTA IV. Pliki, które powinny się tam znaleźć:
Kod:
- Alice (katalog)
Alice.asi
binkhooked.dll
binkw32.dll
lua.dll
lualib.dll
W katalogu
Alice będą przechowywane pliki ze skryptami *.lua.
GTA IV ma wiele skryptowych funkcji zwanych "funkcjami natywnymi". Alice umożliwia wykonanie każdej z nich. Kilka podstawowych operacji:
PushInt(wartość) - Służy do przekazania liczby całkowitej jako parametru do funkcji.
PushFloat(wartość) - To samo, tylko z liczbą po przecinku.
Zmienna = GetIntParam(NumerParametru) - Służy do odczytania liczby całkowitej jako parametru, który został wcześniej przekazany do funkcji. Zwrócona wartość będzie przekazywana w zmiennej o podanej nazwie. Tu: "Zmienna".
Zmienna = GetFloatParam(NumerParametru) - To samo, tylko z liczbą po przecinku.
Wynik = GetIntResult() - Zwraca wynik (w postaci liczby całkowitej) wcześniej wykonanej funkcji.
Wynik = GetFloatResult() - To samo, tylko zwraca liczbę po przecinku.
CallNative("NAZWA_FUNKCJI") - Wywołanie funkcji o podanej nazwie.
Przekazywanie i odczytywanie parametrów może wydawać się nieco skomplikowane, ale można szybko do tego przywyknąć. Wszystkie wątpliwości powinny zostać rozwiane po analizie dalszego przykładu.
Istotnym elementem jest to, że funkcje natywne mogą zostać wywołane tylko podczas gry. Dlatego na początku każdego skryptu jesteśmy zmuszeni sprawdzić, czy gracz został stworzony.
Kod:
IsPlayerPoolCreated()
Na koniec jeszcze dodam, że komentarze w kodzie tworzymy za pomocą dwóch myślników (--).
Kod:
-- To jest komentarz
IsPlayerPoolCreated()
Przykładem w tym poradniku będzie skrypt na tzw. Bullet Time, czyli spowolnienie czasu. Będziemy aktywować ten tryb poprzez wciśnięcie klawisza TAB. Wyłączanie będzie odbywało się po wciśnięciu tego samego klawisza.
Kod:
--zmienne globalne
PLAYER_ID, PLAYER_INDEX, PLAYER_CHAR, Time = 0
function InitScript()
Wait(10000)
end
function WaitForPlayerPoolCreation()
while (IsPlayerPoolCreated() == 0) do
Wait(2000)
end
end
Tworzymy standardowe funkcje, które są niezbędne na początku skryptu. Inicjalizujemy go, a następnie sprawdzamy, czy gracz został stworzony. Należy pamiętać, że są to tylko stworzone przez Nas funkcje i na razie nie zostały one wywołane. Wszystko zostanie wykonane w głównej funkcji o nazwie
main().
Kod:
function WaitForValidPlayer()
PLAYER_CHAR = 0
repeat
CallNative("GET_PLAYER_ID")
PLAYER_ID = GetIntResult()
if (PLAYER_ID >= 0) then
PushInt(PLAYER_ID)
CallNative("CONVERT_INT_TO_PLAYERINDEX")
PLAYER_INDEX = GetIntResult()
PushInt(PLAYER_INDEX)
PushVarPtr()
CallNative("GET_PLAYER_CHAR")
PLAYER_CHAR = GetIntParam(1)
if (PLAYER_CHAR <= 0) then
Wait(1000)
end
end
until (PLAYER_CHAR > 0)
end
Sprawdzamy poprawność gracza. Mówiąc bardziej szczegółowo, najpierw pobieramy jego ID. Zauważ, że najpierw zostaje wywołana funkcja
"GET_PLAYER_ID", a dopiero później przekazujemy wynik tej funkcji do zmiennej
PLAYER_ID. Następnie sprawdzamy, czy ID gracza jest większe lub równe zeru. Jeśli tak, to wywołujemy funkcję
"CONVERT_INT_TO_PLAYERINDEX". Warto zauważyć, że przed wywołaniem tej funkcji przekazujemy do niej parametr w postaci pobranego wcześniej ID gracza.
Dalej odczytujemy wynik wcześniejszej funkcji i mamy indeks gracza, który przekazujemy do kolejnej funkcji o nazwie
"GET_PLAYER_CHAR". Znowu pobieramy wynik funkcji i sprawdzamy, czy zmienna
PLAYER_CHAR jest mniejsza lub równa zeru. Kończymy funkcję tylko wtedy, gdy zmienna
PLAYER_CHAR będzie większa od zera. Będzie to oznaczać, że gracz został już poprawnie stworzony.
Na początku może wydawać się to trochę skomplikowane. Generalnie to wszystko opiera się na schemacie:
Kod:
Przekazujemy parametry -> wywołujemy funkcję -> odczytujemy wynik funkcji
Powyższy kod będziemy wykorzystywać na początku każdego skryptu, dlatego nie musimy zgłębiać się w jego znaczenie czy sens, aczkolwiek warto poznać jego działanie.
Kod:
function BulletTime()
if Time == 0 then
Time = 1
else
Time = 0
end
if Time == 1 then
PushFloat(0.2)
CallNative("SET_TIME_SCALE")
end
if Time == 0 then
PushFloat(1.0)
CallNative("SET_TIME_SCALE")
end
end
Tworzymy nową funkcję o nazwie "BulletTime". Będzie ona miała za zadanie odpowiednie ustawienie szybkości gry.
W pierwszej konstrukcji
if (jeśli) sprawdzamy, czy zmienna
Time jest równa "1". Jeśli wywołamy tą funkcję po raz pierwszy, zmienna
Time będzie miała wartość "0", gdyż tak ustawiliśmy na początku skryptu. W zależności od obecnego stanu tej zmiennej ustawiamy ją ponownie zmieniając wartości.
Dalej mamy kolejną funkcję
if, w której znów sprawdzamy stan zmiennej
Time. Jeśli ma wartość "1", to zwalniamy czas. Funkcja
"SET_TIME_SCALE" przyjmuje tylko 1 parametr typu FLOAT (liczba po przecinku) oznaczającego współczynnik prędkości czasu. Ustawiamy go na
0.2 i wywołujemy wspomnianą funkcję.
Dalej tworzymy kolejny warunek, tym razem dla
Time równego zeru. W takim przypadku ustawiamy współczynnik prędkości czasu na
1.0, czyli normę. Na koniec zamykamy konstrukcję
if i całą funkcję słówami kluczowymi
end.
Kod:
function main()
InitScript()
while true do
if (IsKeyPressed(9) == 1) then
WaitForPlayerPoolCreation()
WaitForValidPlayer()
BulletTime()
Wait(1000)
end
Wait(100)
end
end
No i mamy naszą główną funkcję o nazwie
"main". Tutaj "sklejamy" wszystko, co stworzyliśmy wcześniej. Odwołujemy się do funkcji
InitScript(), następnie zapętlamy sprawdzanie, czy gracz wcisnął klawisz "TAB". Jeśli tak, to sprawdzamy, czy gracz został poprawnie stworzony (tj. gra już się zaczęła). Dalej wykonujemy funkcję
BulletTime(), która odpowiada za zmianę prędkości gry. Po jej wykonaniu odczekujemy sekundę (1000 ms = 1 sek.), aby skrypt nie wykonał nam kilka razy tej funkcji, gdy np. przytrzymam klawisz.
Pierwszy słowem kluczowym
end zamykamy konstrukcję
if. Po tym odczekujemy 100 ms. Gdybyśmy to pominęli, gra bardzo straciłaby na płynności, gdyż za szybko odbywałoby się sprawdzanie wciśnięcia klawisza.
Drugim
end zamykamy pętlę, a ostatnim
end całą funkcję
main().
Kod:
main();
I wreszcie wywołujemy funkcję
main(), aby skrypt zaczął działać.
Jeśli czegoś nie rozumiecie, coś jest nie jasne, zapytajcie na Naszym
FORUM.
Tutaj można ściągnąć kod źródłowy tego skryptu.
Posting comments to this article is disabled.