[Lua] Od zera do skryptera, czyli LUA: PODSTAWY i Actions*
Witam, postanowiłem napisać poradnik tak, by ułatwić wszystkim zrozumienie LUA.
LUA jest językiem skryptowym powstałym po to, by ułatwić pracę na OTS. Zamiast grzebać w C++ można grzebać w LUA co znaaaacznie przyspiesza i ułatwia całą robotę :)
Do rzeczy!
Na OTS jest kilka rodzajów 'zdarzeń':
Cytuj:
ACTIONS: Tutaj dzieje się wszystko, na co dasz USE, czyli klikniesz z controlem (o ile ktoś ma classic control wyłączone).
Cytuj:
MOVEMENTS - Tutaj dzieje się wszystko, co ma związek z wejściem na jakąś kratkę, zejściem, położeniem itemu gdzieś, zdjęciem go z miejsca, założeniem na siebie itemu itd.
Cytuj:
CREATURESCRIPTS - Uwaga! Na starszych OTS tego nie ma! CreatureScripts to zdarzenia związane z logowaniem gracza, wylogowaniem, śmiercią gracza, śmiercią potwora, zabiciem potwora.
Cytuj:
NPC - Nazwa mówi sama za siebie.
Cytuj:
SPELLS - Czary na naszym OTS.
Cytuj:
TALKACTIONS - Wszystko, co jest związane ze słowami. Można też dodać parametr słowa " i to, co jest po nim
To chyba na tyle.
Najłatwiej będzie na początek zrobić coś w actions.
W folderze tym jest plik actions.xml
Cytuj:
Pliki XML to coś w rodzaju pojemników informacji, które pierw czyta OTS. W przypadku actions i innych, możesz napchać tysiące plików skryptów a Twój serwer i tak ich nie odczyta, jeśli nie dodasz stosownej linijki do actions.xml
No ok, stwórzmy pierwszy skrypt. Niech to będzie dźwignia. Załóżmy, że gdy ją pociągniemy, otrzymamy jabłko.
Cytuj:
Polecam program Notepad++ do pisania skryptów.
Wobec tego otwieramy actions.xml prawym przyciskiem myszki i 'edit with notepad++'.
http://sourceforge.net/projects/notepad-plus/
Aby dodać swój skrypt wystarczy linijka:
Cytuj:
<action itemid="1945" event="script" value="skrypt.lua"/>
itemid określa id, co widać w cudzysłowiu. event nie zmieniamy a w value mamy ścieżkę do danego skryptu. Prościutkie.
No ale chwila. Załóżmy, że mamy dwie dźwignie na OTS. Jak rózróżnić wówczas, o którą nam chodzi?
Action ID jest czymś w rodzaju zmiennej, którą może posiadać KAŻDY item na OTS. Możesz jej ustalić 0, 100, 15123, ile chcesz.
Gdy damy dźwigni action ID np. 2566 będzie to wyglądać wówczas tak:
Cytuj:
<action actionid="2566" event="script" value="skrypt.lua"/>
No ok, jeśli nasza dźwignia ma taki action id już w edytorze map, dodaliśmy tę linijkę (musi być dodana powyżej '</actions>'), to czas na skrypt.
Wchodzimy do foldera 'scripts' i tworzymy nowy plik tekstowy. Zmieniamy nazwę i wpisujemy 'skrypt.lua'.
Uwaga! Musisz mieć ustawioną możliwość widzenia rozszerzenia pliku, tzn. dla skryptow .lua, dla dokumentów tekstowych .txt, inaczej skrypt ci się nie załaduje, bo będzie txt!
Cytuj:
By włączyć wyświetlanie rozszerzeń, w Eksploratorze Windows wybierz Narzędzia | Opcje folderów | Widok. Następnie odznacz opcję Ukryj rozszerzenia plików znanych typów.
Ok, prawym na nasz skrypt i edit with notepad++.
Cóż, na razie jest pusty :) No bo jaki ma być? Czas go zapełnić.
Po pierwsze: Musimy go zabezpieczyć, jeśli by nam odbiło i pomyłkowo dalibyśmy innemu itemowi ten sam action ID. Załóżmy miecz jakiś by był z tym samym action id i gracz, który dawałby na niego 'use' dostawałby jabłko o.O. No ale to zaraz.
Wszystkie skrypty actions skupiają się w środku funkcji onUse:
Cytuj:
function onUse(cid, item, fromPosition, itemEx, toPosition)
end
To, co widzisz w nawiasie to parametry funkcji, tzn. dane, którymi możemy operować.
- cid oznacza gracza, który tę funkcję wywołuje, najprościej mówiąc CID = ja.
- item to najprościej ujmując przedmiot, którego dotyczy cała akcja. W tym przypadku dźwignia.
- fromPosition - pozycja w postaci tablicy, z której dano use
- itemEx - w przypadku np. kilofu (pick), gdzie use zamiast na niego, dajemy np. na ziemię, wykorzystując owy kilof.
- toPosition - pozycja w postaci tablicy, miejsca docelowego, na które dano use
No ok, to chyba było banalne na razie. Zatem teraz pora na owe zabezpieczenie. Musimy przekazać OTSowi, że nam w tym przypadku chodzi tylko i wyłącznie o dźwignię. Odrzuci to wszystkie inne przedmioty i weźmie tylko pod uwagę dźwignie, które będą miały action id 2566.
Kod:
function onUse(cid, item, fromPosition, itemEx, toPosition)
if item.itemid == 1945 then
end
end
Mamy już najprostszy skrypt, co prawda nic nie robi, ale mamy :) Każdy IF musi mieć jeden end dla siebie, funkcja również, co widać. znaczek 'równa się', czyli '=' jest napisany podwójnie, to nie błąd, podwójne równa się oznacza przyrównywanie, pojedyncze oznacza nadpisanie wartości.
X == Y <- sprawdza, czy X jest równy Y
X = Y < - nadpisuje X wartością Y
No dobra, teraz wprowadźmy coś do środka. ID jabłka to 2674.
Funkcja dająca item... to doPlayerGiveItem(uid, item, count)
Ok, teraz znowu widzimy nawias a w nim parametry. uid to id gracza, czyli wpiszemy... cid :), item to jabłko, czyli 2674 a count to ilość, dajmy 1: doPlayerGiveItem(cid, 2674, 1)
Kod:
function onUse(cid, item, fromPosition, itemEx, toPosition)
if item.itemid == 1945 then
doPlayerGiveItem(cid, 2674, 1)
end
end
Wyjaśnię to najprościej z możliwych: jeśli pociągniesz za dźwignię z action id 2566, ots zauważy to i otworzy nasz skrypt, dalej jest filtrowanie, JEŚLI ID PRZEDMIOTU TO 1945, daj graczowi jabłko.
Zapisujemy, wchodzimy na OTS, idziemy do naszej dźwigni i pociągamy :)
if oznacza jeżeli, ale istnieją też inne operatory:
Cytuj:
if - jeśli
elseif - przeciwnie, jeśli
else - w przeciwnym wypadku
To są podstawowe, o innych może napiszę :)
Ok, przeróbmy nasz skrypt tak, by sprawdzał lvl gracza.
Kod:
function onUse(cid, item, fromPosition, itemEx, toPosition)
if item.itemid == 1945 then -- jeśli id przedmiotu to 1945...
if getPlayerLevel(cid) >= 20 then -- jeśli gracz ma poziom wyzszy niz 20 albo rowny 20...
doPlayerGiveItem(cid, 2674, 1) -- daj graczowi jablko
else -- w przeciwnym wypadku
doPlayerSendTextMessage(cid,22,"NOOBOWI NIE DAJE JABLEK!") -- daj komunikat
end
end
end
Od razu zaznaczam, że wszystko, co jest napisane po -- jest komentarzem i nie jest brane pod uwagę przez nasz OTS.
Myślę, że ten skrypt jest zrozumiały.
Przedstawię teraz zmienne i powiem mniej więcej, po co są.
Cytuj:
LOCAL - zmienna lokalna, wywołuje się podczas wykonywania kodu, skryptu i ginie po jego zakończeniu. Jest to szybka, tymczasowa zmienna wewnętrzna, niekolidująca z niczym. Wywołuje się ją poprzez napisanie
local nazwazmiennej
Cytuj:
GLOBAL - zmienna globalna, różni się tylko tym, że wywołuje się ją nie pisząc po prostu local i wywołuje się podczas startu OTSa. Jesli masz dwie takie same zmienne globalne o różnych wartościach, może nastąpić konflikt.
Po co jest zmienna? Przykładowo mamy skrypt, w którym jest dwadzieścia miejsc, w których musimy podać np. id naszego jabłuszka :) Zamiast podawać 20x 2674 możemy wyżej dać i wszędzie zamiast 2674 wpisac po prostu... jablko :) Jakież to banalne.
No ok, ale teraz co, gdy mamy więcej warunków, nie tylko level 20 i każdy inny przypadek?
Z pomocą przychodzi else if :)
Kod:
function onUse(cid, item, fromPosition, itemEx, toPosition)
local oplata = 1000 -- tworze zmienna oplata
if item.itemid == 1945 then -- jesli ID przedmiotu to 1945...
if getPlayerLevel(cid) == 20 then -- ...jesli poziom jest rowny 20...
doPlayerGiveItem(cid, 2674, 1) -- ... gracz dostaje jablko
elseif getPlayerLevel(cid) >= 30 then -- ... jesli poziom jest wiekszy lub rowny 30...
if doPlayerRemoveMoney(cid, oplata) == TRUE then --- ... jesli udalo sie pobrac od gracza oplate, ktora wczesniej zadeklarowalismy na 1000 gp...
doPlayerSendTextMessage(cid,22,"HAHAHA OKRADLEM CIE!") -- ... dzwignia go okrada :(
end -- zakonczmy teraz to
else -- w przeciwnym wypadku...
doPlayerSendTextMessage(cid,22,"NOOBOWI NIE DAJE JABLEK!") -- ... gracz ma zly poziom na dostanie jablka
end -- zakonczmy teraz to
end -- zakonczmy teraz to
end -- zakonczmy teraz to
Mam nadzieję, że to nie było trudne.
To są podstawy podstaw LUA
Jak ktoś chce WSZYSTKIE funkcje LUA to polecam np.
http://forum..pl/showthread.php?t=504
http://otland.net/f55/lua-functions-list-14039/
W następnym poradniku opiszę MOVEMENTS