Siema, nudzi mi się to sobie napiszę proradnika, którego będę updatował, na początku może wyglądać trochę skromnie, ale z czasem się rozrośnie.
*Będę używał wyrazów tabela/tablica jako to samo.
Zapraszam na serię poradników od Seminari ;]
Jak ma finalnie wyglądać?
- Proste przykłady wykorzystania Lua do skryptowania na OTS
- Struktura tabel, odczytywanie z nich wartości, operacje na nich, tworzenie własnych tablic poprzez table.insert itd., segregowanie itp.
- Różne metody rozwiązania tego samego problemu (poprzez pętle zamiast wielu ifów itp)
zaczynamy
Pierwsze co to musimy określić co chcemy zrobić, możemy wypisać sobie to na kartce, ja tak zaczynałem skryptować ;p
Przykład 1:
I teraz myślimy, skrypt uaktywni się po naciśnieciu na dźwignie, więc jest to ACTION, w którym używamy dźwigni, więc:
pierwszą linijką w skrypcie będzie onUse
zamiast itemEx może być item2, ale ja preferuje itemEx bo jest łatwiejsze do zrozumienia;p
fromPosition to pobiera pozycje, od której zaczynamy, to toPosition to na tej, której kończymy (to się przydaje np. jeśli używamy jednego itemka na drugim, o tym później)
w naszym skrypcie istotne będą:
-cid
-item
Ponieważ chcemy by ta dźwignia była unikalna, (czyli tylko 1 dźwignia na mapie działa do tego skryptu, to musimy dać w map edytorze actionid jej)
Damy actionid, o liczbie 8500 (upewnijcie się wciskając w map edytorze find action, czy nie ma już takiego actiona zajętego)
i dajemy do actions.xml taką o to linijke:
<action actionid="nasz actionid" event="script" value="sciezka do naszego pliku i nazwa pliku i rozszerzenie (.lua)" />
przechodzimy do naszego skryptu Lua, musimy teraz dać warunek sprawdzający itemid dźwigni (bo są 2 dźwignie, nie przekręcona 1945 i przekręcona 1946)
robimy coś takiego, zostawiając puste luki między oboma warunkami
teraz chcemy by po pierwszej dźwigni niszczylo kamień, a przy drugiej go stawiało, dajemy sobie komentarz by o tym pamiętac
teraz damy warunki, ktore sprawdzaja czy kamien juz na danej pozycji, oraz musimy podac tą pozycje, jako lokalną zmienną
pozycja_kamienia <- to jest nazwa naszej zmiennej, rownie dobrze mozemy sobie nazwac ją zbyszek, albo kamyczke, dowolnie jak chcemy
{x= ,y= ,z=} <-- to jest pozycja naszego kamienia, założmy, że stawiliśmy go na pozycji x = 1050, y=5000, z = 7
id_kamienia = 1354 <-- to jest ID naszego kamienia, ktorego chcemy usuwac
w tej chwili, a właściwie powinno się to zrobić zawsze po umieszczeniu 1 linijki w skrypcie, ostatnimi naszymi linijkami mają być:
W obecnej chwilii nasz skrypt powinien wyglądać tak:
to zaczynamy usuwać nasz kamień, wykorzystamy do tego funkcję, która znajduje kamień o danym ID na danej pozycji, czyli:
znaleziony_kamien = getTileItemById(pozycja gdzie ma szukac przedmiotu, id przedmiotu szukanego)
znaleziony_kamien to nazwa localna, w naszym przypadku będzie to wyglądać tak:
kazdy item ma swoije unikalne id, czyli UID, oprocz tego dawanego w remere jest takie UID normalne, ktory ma kazdy item
jesli nasza funkcja znajdzie kamien na tej pozycji, to wtedy UID bedzie napewno rozne od liczby 0, jesli jednak nie, to bedzie ono albo -1, albo 0 albo nil, zaleznie od silnika
więc żeby napewno nasz skrypt działał na każdym silniku robimy tak:
całość wygląda teraz tak:
zacznijmy od prostszego warunku, czyli od tego, co robic jesli kamienia nie ma na tej pozycji (po else)
wtedy chcemy by wyslalo graczowi wiadomosc "Kamien jest juz przesuniety", oraz by dzwignia sie przesunela do pozycji, w ktorej powinna byc, gdy kamien jest juz przesuniety czyli do 1946
funkcje, które wykorzystamy:
doCreatureSay(cid, text, TALKTYPE_MONSTER)
doTransformItem(tutaj UID itemu dziwigni, ID itemu, w ktory ma sie zamienic nasza dziwgnia)
otrzymamy coś takiego:
to teraz zajmiemy się trudniejszym warunkiem, czyli usuwaniem kamienia, wykorzystamy tą funkcję:
doRemoveThing(UID itemu który chcemy usunąć, liczba itemow do usuniecia)
i dajemy też ten sam warunek do przesunięcia dźwigni + nowy msg dla gracza
całośc wygląda teraz tak:
teraz zajemimy się stawianiem kamienia, dajemy podobne warunki jak poprzednio, uzyjemy funkcji tworzenia itemka
doCreateItem(id tworzonego itemka, pozycja tworzenia itemka)
całość wygląda teraz tak:
Ostatnia rzecz jaka została to kosmetyczna poprawka efektami oraz usunięcie zbędnych komentarzy, możecie je zostawić by wiedzieć o co chodzi w skrypcie, ja często zostawiam
użyjemy funkcji:
doSendMagicEffect(pozycja gdzie ma byc wyslany efekt, numer efektu)
oraz dodamy sobie nowe fajne zmienne:
local efekt_przy_usuwaniu_kamienia = 13
local efekt_przy_tworzeniu_kamienia = 25
Cały nasz skrypt powinien wyglądać tak:
*Będę używał wyrazów tabela/tablica jako to samo.
Zapraszam na serię poradników od Seminari ;]
Jak ma finalnie wyglądać?
- Proste przykłady wykorzystania Lua do skryptowania na OTS
- Struktura tabel, odczytywanie z nich wartości, operacje na nich, tworzenie własnych tablic poprzez table.insert itd., segregowanie itp.
- Różne metody rozwiązania tego samego problemu (poprzez pętle zamiast wielu ifów itp)
zaczynamy
Pierwsze co to musimy określić co chcemy zrobić, możemy wypisać sobie to na kartce, ja tak zaczynałem skryptować ;p
Przykład 1:
- Chcemy zrobić dźwignie
- Dźwignia ma usuwać kamień na pewnej pozycji
- Przy usuwaniu kamienia ma wysłać efekt np. Ognistego Rozprysku
- Po usunięciu kamienia dźwignia ma się przekręcić
- Gdy przekręcimy spowrotem dźwignie to kamień się na nowo pojawi
- Przy usuwaniu kamienia do gracza wyśle na czerwono wiadomość
- Przy pojawieniu się kamienia wyśle inny msg
I teraz myślimy, skrypt uaktywni się po naciśnieciu na dźwignie, więc jest to ACTION, w którym używamy dźwigni, więc:
pierwszą linijką w skrypcie będzie onUse
Lua:
function onUse(cid, item, fromPosition, itemEx, toPosition)
zamiast itemEx może być item2, ale ja preferuje itemEx bo jest łatwiejsze do zrozumienia;p
fromPosition to pobiera pozycje, od której zaczynamy, to toPosition to na tej, której kończymy (to się przydaje np. jeśli używamy jednego itemka na drugim, o tym później)
w naszym skrypcie istotne będą:
-cid
-item
Ponieważ chcemy by ta dźwignia była unikalna, (czyli tylko 1 dźwignia na mapie działa do tego skryptu, to musimy dać w map edytorze actionid jej)
Damy actionid, o liczbie 8500 (upewnijcie się wciskając w map edytorze find action, czy nie ma już takiego actiona zajętego)
i dajemy do actions.xml taką o to linijke:
<action actionid="nasz actionid" event="script" value="sciezka do naszego pliku i nazwa pliku i rozszerzenie (.lua)" />
XML:
<action actionid="8500" event="script" value="quests/nasza_dzwignia.lua" /> <!-- w takie ptaszki robimy komentarz w XML -->
przechodzimy do naszego skryptu Lua, musimy teraz dać warunek sprawdzający itemid dźwigni (bo są 2 dźwignie, nie przekręcona 1945 i przekręcona 1946)
robimy coś takiego, zostawiając puste luki między oboma warunkami
Lua:
if item.itemid == 1945 then
elseif item.itemid == 1946 then
end
teraz chcemy by po pierwszej dźwigni niszczylo kamień, a przy drugiej go stawiało, dajemy sobie komentarz by o tym pamiętac
Lua:
if item.itemid == 1945 then
-- tutaj usuwamy kamien
elseif item.itemid == 1946 then
-- tutaj stawiamy kamien
end
teraz damy warunki, ktore sprawdzaja czy kamien juz na danej pozycji, oraz musimy podac tą pozycje, jako lokalną zmienną
Lua:
local pozycja_kamienia = {x= ,y= ,z= }
local id_kamienia = 1354
pozycja_kamienia <- to jest nazwa naszej zmiennej, rownie dobrze mozemy sobie nazwac ją zbyszek, albo kamyczke, dowolnie jak chcemy
{x= ,y= ,z=} <-- to jest pozycja naszego kamienia, założmy, że stawiliśmy go na pozycji x = 1050, y=5000, z = 7
id_kamienia = 1354 <-- to jest ID naszego kamienia, ktorego chcemy usuwac
w tej chwili, a właściwie powinno się to zrobić zawsze po umieszczeniu 1 linijki w skrypcie, ostatnimi naszymi linijkami mają być:
Lua:
return true
end
W obecnej chwilii nasz skrypt powinien wyglądać tak:
Lua:
function onUse(cid, item, fromPosition, itemEx, toPosition)
local pozycja_kamienia = {x=1050,y=5000,z=7}
local id_kamienia = 1354
if item.itemid == 1945 then
-- tutaj usuwamy kamien
elseif item.itemid == 1946 then
-- tutaj stawiamy kamien
end
return true
end
to zaczynamy usuwać nasz kamień, wykorzystamy do tego funkcję, która znajduje kamień o danym ID na danej pozycji, czyli:
znaleziony_kamien = getTileItemById(pozycja gdzie ma szukac przedmiotu, id przedmiotu szukanego)
znaleziony_kamien to nazwa localna, w naszym przypadku będzie to wyglądać tak:
Lua:
local znaleziony_kamien = getTileItemById(pozycja_kamienia, id_kamienia)
kazdy item ma swoije unikalne id, czyli UID, oprocz tego dawanego w remere jest takie UID normalne, ktory ma kazdy item
jesli nasza funkcja znajdzie kamien na tej pozycji, to wtedy UID bedzie napewno rozne od liczby 0, jesli jednak nie, to bedzie ono albo -1, albo 0 albo nil, zaleznie od silnika
więc żeby napewno nasz skrypt działał na każdym silniku robimy tak:
Lua:
if znaleziony_kamien.uid > 0 then
-- tutaj bedziemy go usuwac bo go znalazlo
else
-- tutaj napiszemy graczowi, ze kamien jest juz usuniety, bo kamienia nie znalazlo na tej pozycji
end
całość wygląda teraz tak:
Lua:
function onUse(cid, item, fromPosition, itemEx, toPosition)
local pozycja_kamienia = {x=1050,y=5000,z=7}
local id_kamienia = 1354
local znaleziony_kamien = getTileItemById(pozycja_kamienia, id_kamienia)
if item.itemid == 1945 then
-- tutaj usuwamy kamien
if znaleziony_kamien.uid > 0 then
-- tutaj bediemy go usuwac bo go znalazlo
else
-- tutaj napiszemy graczowi, ze kamien jest juz usuniety, bo kamienia nie znalazlo na tej pozycji
end
elseif item.itemid == 1946 then
-- tutaj stawiamy kamien
end
return true
end
zacznijmy od prostszego warunku, czyli od tego, co robic jesli kamienia nie ma na tej pozycji (po else)
wtedy chcemy by wyslalo graczowi wiadomosc "Kamien jest juz przesuniety", oraz by dzwignia sie przesunela do pozycji, w ktorej powinna byc, gdy kamien jest juz przesuniety czyli do 1946
funkcje, które wykorzystamy:
doCreatureSay(cid, text, TALKTYPE_MONSTER)
doTransformItem(tutaj UID itemu dziwigni, ID itemu, w ktory ma sie zamienic nasza dziwgnia)
otrzymamy coś takiego:
Lua:
function onUse(cid, item, fromPosition, itemEx, toPosition)
local pozycja_kamienia = {x=1050,y=5000,z=7}
local id_kamienia = 1354
local znaleziony_kamien = getTileItemById(pozycja_kamienia, id_kamienia)
if item.itemid == 1945 then
-- tutaj usuwamy kamien
if znaleziony_kamien.uid > 0 then
-- tutaj bediemy go usuwac bo go znalazlo
else
-- tutaj napiszemy graczowi, ze kamien jest juz usuniety, bo kamienia nie znalazlo na tej pozycji
doCreatureSay(cid, "Kamien jest juz przesuniety", TALKTYPE_MONSTER)
doTransformItem(item.uid, 1946)
end
elseif item.itemid == 1946 then
-- tutaj stawiamy kamien
end
return true
end
to teraz zajmiemy się trudniejszym warunkiem, czyli usuwaniem kamienia, wykorzystamy tą funkcję:
doRemoveThing(UID itemu który chcemy usunąć, liczba itemow do usuniecia)
i dajemy też ten sam warunek do przesunięcia dźwigni + nowy msg dla gracza
całośc wygląda teraz tak:
Lua:
function onUse(cid, item, fromPosition, itemEx, toPosition)
local pozycja_kamienia = {x=1050,y=5000,z=7}
local id_kamienia = 1354
local znaleziony_kamien = getTileItemById(pozycja_kamienia, id_kamienia)
if item.itemid == 1945 then
-- tutaj usuwamy kamien
if znaleziony_kamien.uid > 0 then
-- tutaj bediemy go usuwac bo go znalazlo
doRemoveThing(znaleziony_kamien.uid, 1)
doCreatureSay(cid, "Przesuwajac dzwignie usunales kamien", TALKTYPE_MONSTER)
doTransformItem(item.uid, 1946)
else
-- tutaj napiszemy graczowi, ze kamien jest juz usuniety, bo kamienia nie znalazlo na tej pozycji
doCreatureSay(cid, "Kamien jest juz przesuniety", TALKTYPE_MONSTER)
doTransformItem(item.uid, 1946)
end
elseif item.itemid == 1946 then
-- tutaj stawiamy kamien
end
return true
end
teraz zajemimy się stawianiem kamienia, dajemy podobne warunki jak poprzednio, uzyjemy funkcji tworzenia itemka
doCreateItem(id tworzonego itemka, pozycja tworzenia itemka)
całość wygląda teraz tak:
Lua:
function onUse(cid, item, fromPosition, itemEx, toPosition)
local pozycja_kamienia = {x=1050,y=5000,z=7}
local id_kamienia = 1354
local znaleziony_kamien = getTileItemById(pozycja_kamienia, id_kamienia)
if item.itemid == 1945 then
-- tutaj usuwamy kamien
if znaleziony_kamien.uid > 0 then
-- tutaj bediemy go usuwac bo go znalazlo
doRemoveThing(znaleziony_kamien.uid, 1)
doCreatureSay(cid, "Przesuwajac dzwignie usunales kamien", TALKTYPE_MONSTER)
doTransformItem(item.uid, 1946)
else
-- tutaj napiszemy graczowi, ze kamien jest juz usuniety, bo kamienia nie znalazlo na tej pozycji
doCreatureSay(cid, "Kamien jest juz przesuniety", TALKTYPE_MONSTER)
doTransformItem(item.uid, 1946)
end
elseif item.itemid == 1946 then
-- tutaj stawiamy kamien
if znaleziony_kamien.uid > 0 then
doCreatureSay(cid, "Kamien jest juz przesuniety", TALKTYPE_MONSTER)
doTransformItem(item.uid, 1945)
else
doCreateItem(id_kamienia, pozycja_kamienia)
doCreatureSay(cid, "Postawiles kamien!", TALKTYPE_MONSTER)
doTransformItem(item.uid, 1945)
end
end
return true
end
Ostatnia rzecz jaka została to kosmetyczna poprawka efektami oraz usunięcie zbędnych komentarzy, możecie je zostawić by wiedzieć o co chodzi w skrypcie, ja często zostawiam
użyjemy funkcji:
doSendMagicEffect(pozycja gdzie ma byc wyslany efekt, numer efektu)
oraz dodamy sobie nowe fajne zmienne:
local efekt_przy_usuwaniu_kamienia = 13
local efekt_przy_tworzeniu_kamienia = 25
Cały nasz skrypt powinien wyglądać tak:
Lua:
function onUse(cid, item, fromPosition, itemEx, toPosition)
local pozycja_kamienia = {x=1050,y=5000,z=7}
local id_kamienia = 1354
local znaleziony_kamien = getTileItemById(pozycja_kamienia, id_kamienia)
local efekt_przy_usuwaniu_kamienia = 13
local efekt_przy_tworzeniu_kamienia = 25
if item.itemid == 1945 then -- przy tym ustawieniu dzwigni usuwac bedzie kamien
if znaleziony_kamien.uid > 0 then -- znalazlo kamien, wiec go usunie
doRemoveThing(znaleziony_kamien.uid, 1)
doCreatureSay(cid, "Przesuwajac dzwignie usunales kamien", TALKTYPE_MONSTER)
doTransformItem(item.uid, 1946)
doSendMagicEffect(pozycja_kamienia, efekt_przy_usuwaniu_kamienia)
else -- jesli nie znajdzie kamienia na danej pozycji, to przesunie dzwignie w odpowiednie miejsce
doCreatureSay(cid, "Kamien jest juz przesuniety", TALKTYPE_MONSTER)
doTransformItem(item.uid, 1946)
end
elseif item.itemid == 1946 then -- przy tym ustawieniu dzwigni bedzie tworzyc kamien
if znaleziony_kamien.uid > 0 then -- kamien juz stoi, wiec przesuwamy dzwignie w odpowiednie miejsce
doCreatureSay(cid, "Kamien jest juz przesuniety", TALKTYPE_MONSTER)
doTransformItem(item.uid, 1945)
else -- kamienia jeszcze tam nie ma, wiec trzeba go stworzyc
doCreateItem(id_kamienia, pozycja_kamienia)
doCreatureSay(cid, "Postawiles kamien!", TALKTYPE_MONSTER)
doTransformItem(item.uid, 1945)
doSendMagicEffect(pozycja_kamienia, efekt_przy_tworzeniu_kamienia)
end
end
return true
end