# Lua w RGXbot: kurs od pierwszego skryptu

Poznasz trzy miejsca używania Lua, napiszesz pierwszy warunek, przygotujesz
formularz opcji i połączysz go z trasą. Pod kursem znajdziesz pełny katalog
funkcji, aliasów, zmiennych i ścieżek ustawień dostępnych w RGXbot.
Stan treści: 12 listopada 2026. To własny podzbiór Lua, więc gotowe skrypty
z innych botów wymagają dostosowania.

## 1. Wybierz miejsce wykonania

**Action** służy do zadań cyklicznych. W karcie Action kliknij **Dodaj**,
nadaj nazwę, zaznacz włączenie i ustaw odstęp w milisekundach, np. 1000.
Wklej kod, użyj **Test Lua**, potem **Zapisz** w Action. Przycisk **Start**
uruchamia moduł. **Plik → Zapisz** utrwala konfigurację w XML.
Zapisanie kodu i uruchomienie modułu to osobne czynności.

**Waypoint Action** wykonuje kod w danym miejscu trasy. W edytorze waypointu
wybierz typ Action i wpisz kod. Używaj go do sprawdzania zapasów,
przełączania zakładek lub pojedynczej sekwencji u NPC. Przygotuj etykiety
przed wywołaniem skoku. Sam Action cykliczny nie ma pozycji waypointu.

**Konfiguracja skryptu → Definicja Lua / JSON** tworzy formularz ustawień.
W tym edytorze deklarujesz kontrolki; nie sterujesz grą. Użyj **Zastosuj**,
a potem **Plik → Zapisz**. Kod formularza jest oddzielony od kodu Action.

Nie wklejaj całego kursu do jednego pola. Każdy blok to osobny przykład;
blok oznaczony „Formularz” trafia wyłącznie do definicji formularza.

## 2. Pierwszy skrypt bez poleceń gry

Ten przykład tylko oblicza wartości. Wklej go do nowej akcji i wybierz
**Test Lua** przy załadowanej postaci. Brak zaplanowanych poleceń jest tutaj
poprawnym wynikiem. Nie używaj `print()`: interpreter go nie obsługuje.

```lua
-- $... to odczyty RGXbot. local to własna zmienna.
local minimumCap = 150
local lowCapacity = $cap < minimumCap
local healthPercent = $hppc
local missingMana = max(0, $maxmp - $mp)
```

`local` przechowuje wartość tylko podczas bieżącego wywołania. Po kolejnym
cyklu Action kod zaczyna od nowa. `$hp` jest liczbą punktów zdrowia, a `$hppc`
procentem. Zapisanie własnej wartości do zmiennej nie leczy postaci.
Odczyty w Test Lua wymagają odpowiedniego kontekstu klienta.

## 3. Warunki, nil i jednostki

`if` rozpoczyna warunek, `elseif` sprawdza kolejną możliwość, a `else`
obsługuje pozostałe przypadki. Każdy blok kończy `end`. Porównuj przez `==`,
przypisuj przez `=`, a nierówność zapisuj `~=`. Łącz warunki przez `and`,
`or`, `not`. Tylko `false` i `nil` są fałszem; `0` jest prawdą.

```lua
local state = "gotowy"
if $stamina == nil then
    state = "brak odczytu staminy"
elseif $stamina < 1200 then
    state = "stamina ponizej 20 godzin"
else
    state = "stamina wystarcza"
end
```

Stamina ma jednostkę minut: 1200 to 20 godzin. `wait(1000)` oznacza jedną
sekundę, a `spellcooldown()` zwraca sekundy. Nigdy nie porównuj nieznanego
odczytu `nil` z liczbą. Statusy `$poisoned` i podobne również mogą być `nil`.
Brak danych oznacza brak wiedzy, a nie stan bezpieczny ani saldo zero.

## 4. Pierwsza reguła cykliczna

Poniższy kod planuje zatrzymanie modułów po śmierci lub przy staminie
poniżej przykładowego limitu. Najpierw obejrzyj plan w Test Lua, potem dobierz
próg do własnej sesji. Wbudowane warunki zatrzymania panelu nadal obowiązują;
nie zastępuj ich samym skryptem. `stopbot()` kończy bieżący skrypt.

```lua
if $dead then
    stopbot("Smierc postaci")
end
if $stamina ~= nil and $stamina < 1200 then
    stopbot("Limit staminy: ponizej 20 godzin")
end
```

**Test Lua pokazuje plan i nie wykonuje poleceń w kliencie.** Nie dowodzi
skutecznego zatrzymania, rzutu czaru ani zakupu. Dopiero po sprawdzeniu
planu uruchom właściwy moduł i potwierdź wynik w panelu i grze.
Przy braku staminy przykład nie podejmuje decyzji na podstawie tego odczytu.

## 5. Czar z kontrolą zasobów

Dobierz znaną formułę, profesję i koszt many swojej postaci. Poniżej
przykładowy warunek dla postaci znającej `exura`. Próg 70% i koszt 20 many
są ustawieniami przykładu. Nie uruchamiaj równocześnie konkurencyjnych reguł
leczenia bez sprawdzenia ich konfiguracji.

```lua
if not $dead and not $pz and $hppc < 70 and $mp >= 20 then
    if spellcooldown("exura") == 0 then
        spell("exura")
    end
end
```

`spell()` jest poleceniem i zwraca `nil`; nie pisz `if spell(...) then`.
Oceń HP i manę po wykonaniu. Odczyty odświeżają się po poleceniu, ale lokalna
zmienna zachowuje wcześniej obliczoną wartość. Dla mikstur używaj `useself()`
oraz `itemcooldown()`, a dla run na celu sprawdzaj także `$target ~= 0`.

## 6. Formularz dla wielu postaci

Wklej poniższy blok **do definicji formularza**, użyj Zastosuj i sprawdź
pola w Konfiguracji skryptu. ID 268 jest przykładowym zapasem; dopasuj ID,
liczby i nazwę etykiety do własnej trasy. Formularz sam nie kupuje mikstur.

```lua-setup
addmenu("return", "Powrot i zapasy")
addcheckbox("return_enabled", "Kontroluj powrot", true)
addspinbox("min_cap", "Minimalny cap", 150, 0, 10000)
addtextbox("return_label", "Etykieta powrotu", "refill")
addsupply("mana", "Mana potion", 268, 50, 300)
```

Następnie utwórz na trasie etykietę **refill** i dodaj waypoint Action
z poniższym kodem. `needsrefill()` uwzględnia włączenie powrotu, minimalny
cap i minima włączonych zapasów. `supplyneed()` liczy brak do celu, a nie
do minimum. Liczniki obejmują wyposażenie i otwarte kontenery.

```lua
if needsrefill() then
    gotolabel(getuseroption("return_label"))
end
```

`gotolabel()` kończy skrypt: dalsze linie nie są wykonywane. Ustaw opcje
**Ze skryptu** lub **Własne dla postaci**, aby wspólny XML miał różne progi
dla różnych postaci. Zapisz profil i XML, potem sprawdź ponowne wczytanie.

## 7. Kolejność, oczekiwanie i pętle

Polecenia idą po kolei. `wait()` zatrzymuje bieżący skrypt; `pausewalking()`
pauzuje chodzenie. W obsługiwanym opcjonalnym wejściu wspólny Healer może
pracować podczas oczekiwania. Nie zapisuj długich nieskończonych pętli:
do regularnego sprawdzania służy odstęp Action. Pętla ma limit 10 000
iteracji, a zagnieżdżenie limit 32 poziomów.

```lua
local attempt = 0
while attempt < 3 do
    attempt = attempt + 1
    if $target ~= 0 then
        break
    end
    wait(200)
end
```

Nie ponawiaj automatycznie zakupu lub transferu po nieznanym wyniku.
`submitted` oznacza wysłanie wejścia, a `confirmed` potwierdzenie przez
obserwatora efektu. Zapamiętaj `inputactionid()` przed `wait()`, jeżeli
śledzisz konkretną operację: leczenie może zmienić ostatni rekord.

## 8. NPC, bank i depozyt

Najpierw doprowadź postać do właściwego NPC na tym samym piętrze.
`npcsay("hi")` rozpoczyna rozmowę; przed kolejnymi czynnościami sprawdź
`npcisopen()`, `npcname()` i odpowiedź `npcmessage()`. Handel potrzebuje
otwartej oferty, pieniędzy, miejsca i właściwej nazwy przedmiotu.
Kupno i sprzedaż obsługują najwyżej 100 sztuk na wywołanie.

`checkbank()` pyta o saldo, a `bankbalance()` je odczytuje. Nie dokładaj
`npcyes()` po `bankwithdraw()`: funkcja sama obsługuje potwierdzenie.
`depositall()` wpłaca monety do banku. `depositer()` odkłada loot do
depozytu, a `deposititems()` odkłada wszystkie stosy podanych ID.
`stashcount()` potrzebuje odczytu otwartego Supply Stash.

W katalogu poniżej znajdziesz pełne sygnatury i oddzielne przykłady banku,
handlu, amunicji, przenoszenia, depozytu i Stash. Numery kontenerów są
aktualnymi identyfikatorami okien; nie zapisuj ich na stałe między sesjami.
Sloty przedmiotów w kontenerze zaczynają się od 0.

## 9. Reconnect i kontrola wykonania

`reconnect()` musi być pierwszą instrukcją cyklicznego Action, jeśli ma działać
bez odczytu PLAYER. Używa ustawień reconnectu i tej samej postaci wybranej
w panelu. Nie omija śmierci, 2FA ani limitów; błąd zatrzymuje dalszy kod.
W waypoincie wywołanie działa dopiero, gdy silnik wykonuje ten punkt.
Nie uruchamia trasy samoczynnie po rozłączeniu.

```lua
reconnect()
local character = $character
local currentHealth = $hp
```

Po każdym nowym skrypcie sprawdź składnię przez Test Lua, przeczytaj plan,
wykonaj jedną kontrolowaną próbę i obserwuj skutek. W razie błędu użyj logu
Action i Diagnostyki. Zachowaj nazwę funkcji, argumenty i komunikat błędu.
Nieznana funkcja zwykle oznacza literówkę, inną wielkość liter lub fragment
pełnego Lua, którego ten interpreter nie obsługuje.

## 10. Co umiesz i gdzie szukać dalej

Potrafisz wybrać kontekst, czytać `$...`, sprawdzać `nil`, tworzyć warunki,
kontrolować jednostki, budować formularz i kierować trasą. Katalog API niżej
obejmuje wszystkie nazwy funkcji wykonawczych, aliasy matematyczne,
deklaracje formularza i zmienne. Wyszukuj np. `$stamina`, `buyitems`,
`addspinbox` lub `priority.targeting`. Przy każdej grupie przeczytaj też
wymagania i ograniczenia, nie tylko samą sygnaturę.

Interpreter nie obsługuje `function`, `for`, `repeat`, tworzenia tabel,
`pairs`, `ipairs`, `print`, `require` ani bibliotek plików, sieci i systemu.
Wyjątkiem od braku tabel są gotowe wartości zakresów z formularza JSON:
ich pola `from` i `to` można odczytać. Używaj przykładów zgodnych z RGXbot.


# Lua w RGXbot — funkcje i przykłady

Pełny katalog API RGXbot. Dotyczy Action i waypointów Action; deklaracje formularza mają osobny kontekst.

## Jak wykonywane są skrypty

W uruchomionym skrypcie polecenia są wykonywane po kolei. Po poleceniu
silnik odświeża stan: kolejny `itemcount()` lub `$hp` korzysta z nowego
odczytu. Lokalne zmienne zachowują własne wartości do końca tego wywołania.
Nie przechowują stanu między kolejnymi uruchomieniami skryptu Action.

**Test Lua pokazuje plan, bez wykonywania poleceń w kliencie.** Nie symuluje
wyników zakupów ani leczenia. Warunek po planowanym zakupie może więc dać
inny wynik niż podczas rzeczywistego wykonania z odświeżaniem stanu.

Odczyty zwracają liczby, napisy lub wartości logiczne. Polecenia takie jak
`spell()`, `buyitems()` i `checkbank()` zwracają `nil` do kodu Lua; wynik
operacji sprawdza się następnym odczytem, a błędy trafiają do logów.
Nie pisz `if buyitems(...) then`: to nie jest funkcja zwracająca sukces.

Polecenia korzystają z wybranego wejścia. `memory` oznacza opcjonalną
symulację klawiatury i myszy; nie przełącza domyślnego backendu `native`.
Odczyty UI i część operacji okien potrzebują działającego klienta i
dostępnego kontrolera pamięci, niezależnie od miejsca użycia skryptu.

### Ponowne logowanie: `reconnect()`

```lua
reconnect()
```

Bez argumentów: ponownie loguje **tę samą postać**, wybraną w panelu.
Korzysta z istniejącego kontrolera logowania i systemowego sejfu kont.
Nie wylogowuje postaci, która już jest prawidłowo online, i nie restartuje
klienta gry. Dalsze instrukcje skryptu wykonują się dopiero po potwierdzeniu
żywej postaci o właściwej nazwie; odświeżają wtedy odczyty z nowej sesji.
Wynikiem dla Lua jest `nil`, jak przy innych poleceniach sterujących.

W module **Action** umieść `reconnect()` jako **pierwszą instrukcję** skryptu,
aby mogła zostać wykonana również podczas niedostępnego odczytu PLAYER.
Warunek używający `$hp` lub `$name` przed tą instrukcją nadal wymaga odczytu
postaci. W waypointach Action funkcja jest dostępna, gdy silnik wykonuje
ten waypoint; nie powoduje samoczynnego uruchomienia waypointu po rozłączeniu.

Funkcja respektuje ustawienia reconnectu panelu i ogranicza całe oczekiwanie
do maksymalnie 10 minut. Stop lub zmiana klienta, backendu albo wybranej
postaci przerywa operację. 2FA, śmierć, niezgodna postać, brak danych konta
lub przekroczony limit zatrzymują dalsze instrukcje; nie omijają zabezpieczeń
i nie zerują automatycznie licznika prób. Błąd Action wymaga jawnego ponowienia.
Statusy są widoczne w oknie **Reconnect…** i logu skryptu. Tryb native zachowuje
natywne sterowanie rozgrywką; wyłącznie logowanie używa istniejącego mostka UI.

## Składnia i jednostki

Obsługiwane są `local`, przypisania, `if/elseif/else/end`, `while/do/end`,
`break`, `return`, komentarze `--` i `--[[ ... ]]`, napisy w obu rodzajach
cudzysłowów, liczby, `true`, `false`, `nil`, działania `+ - * / % ^`,
porównania `== ~= < <= > >=`, konkatenacja `..` oraz `and/or/not`.
Średniki są opcjonalne. Nazwy funkcji rozróżniają wielkość liter.
Tylko `false` i `nil` są fałszem: liczba `0` jest prawdą.

Nie są obsługiwane własne definicje `function`, pętle `for/repeat`, tabele,
`pairs/ipairs`, `print`, `require`, biblioteki plików, sieci i systemu.
`local` nie zapewnia pełnej semantyki zasięgów znanej z kompletnego Lua.
Pętla ma limit 10 000 iteracji, a zagnieżdżenie limit 32 poziomów.

| Wartość | Jednostka / zakres |
|---|---|
| `wait`, `pausewalking`, `$hunt_time`, `$target_time`, `$stand_time` | milisekundy |
| `spellcooldown`, `itemcooldown`, `$food` | sekundy |
| HP / mana w procentach | 0–100 |
| ID przedmiotu | liczba całkowita 1–65535 |
| współrzędne x/y oraz piętro z | x/y 0–65535, z 0–15 |
| numer otwartego kontenera | aktualne ID okna, zwykle 0–255; nie pozycja na ekranie |
| slot w kontenerze | indeks od 0 |
| numer skrzynki depozytu | 1–21 |
| ilość w poleceniach przedmiotów | zwykle 1–100000; zakup/sprzedaż maksymalnie 100 na wywołanie |

W sygnaturach `[argument]` oznacza argument opcjonalny; nawiasów kwadratowych
nie wpisuje się do kodu. `nil` jako kontener w `moveitem()` oznacza wyposażenie.
Chronione odczyty, np. blessów, cooldownów i banku, zgłaszają błąd przy
nieznanym stanie. isitemontile() dotyczy tylko snapshotu: brak pola daje false.

Sloty wyposażenia: 1 głowa, 2 szyja, 3 plecak, 4 pancerz, 5 ręka/tarcza,
6 ręka/broń, 7 nogi, 8 buty, 9 pierścień, 10 slot dodatkowy, 11 Store Inbox.
Strzały i bełty uzupełnia się do kołczanu, nie bezpośrednio do slotu 10.

## Zmienne postaci

| Zmienne | Znaczenie |
|---|---|
| `$name`, `$level`, `$exp` | nazwa, poziom, doświadczenie |
| `$character` | postać rozpoznana i przypisana do panelu; tożsamość używana także przy relogu |
| `$hp`, `$maxhp`, `$hppc` | HP, maksymalne HP, procent HP |
| `$mp`, `$maxmp`, `$mppc` | mana, maksymalna mana, procent many |
| `$cap` | dostępna pojemność |
| `$x`, `$y`, `$z` | pozycja świata |
| `$posx`, `$posy`, `$posz` | aliasy pozycji |
| `$soul`, `$speed` | soul, prędkość klienta |
| `$stamina` | aktualna stamina w minutach: 0–2520; `nil` przy braku poprawnego odczytu |
| `$food`, `$hungry` | licznik jedzenia; hungry jest prawdą przy liczniku 0 |
| `$pz`, `$pzblock` | Protection Zone i blokada PZ |
| `$target`, `$followed` | ID atakowanego / śledzonego celu; 0 oznacza brak |
| `$attacked` | czy ustawione jest ID atakowanego celu, nie „czy ktoś mnie bije” |
| `$dead`, `$deathcount` | śmierć i licznik śmierci w bieżącej sesji polityki śmierci |
| `$route` | nazwa aktywnej zakładki trasy |
| `$statusknown`, `$statusflags` | dostępność odczytu i surowa maska stanów; maska jest `nil` przy braku danych |
| `$poisoned`, `$paralyzed`, `$burning`, `$hasted`, `$bleeding`, `$drunk`, `$mana_shield` | stan logiczny lub `nil`, gdy agent nie udostępnia maski |
| `$hunt_time`, `$target_time`, `$stand_time` | czas polowania, bieżącego celu i stania w miejscu |

`$stamina` działa w waypointach Cavebota i akcjach Lua. `1200` oznacza
20 godzin, a `2520` pełne 42 godziny. Wartość odświeża się wraz z kontekstem
skryptu, również po wykonaniu `wait()`. Brak odczytu nie oznacza zera.

```lua
if $stamina ~= nil and $stamina < 1200 then
  gotolabel("rest")
end
```

Nie każdy kontekst ma aktywny waypoint, cel lub licznik polowania.
Niedostępne czasy początkowe dają 0. Zmienne `$...` opisują odczyt;
przypisanie własnej wartości nie zmienia stanu postaci w grze.

## Odczyty i obliczenia

### Przedmioty, mapa i pozycja

`inputstatus([id])`, `inputaction([id])` i `inputactionid([id])` odczytują
stan, nazwę i identyfikator operacji opcjonalnego wejścia. Bez argumentu
dotyczą ostatniej operacji. Brak rekordu (także w native) daje `nil`.
Historia ma maksymalnie 64 wpisy, osobno dla kontrolera; rekord nie zawiera
argumentów, wpisywanego tekstu ani szczegółów błędu.

Stany to `started`, `submitted`, `completed`, `confirmed`, `failed`,
`cancelled`, `uncertain`. `submitted` oznacza wysłanie wejścia; `completed`
zakończenie funkcji bez odrębnego potwierdzenia efektu. `failed` i `cancelled`
opisują zakończenie wykonania, nie cofnięcie wcześniejszych zdarzeń.
`confirmed` wymaga jawnego obserwatora efektu. ListedLoot i transfery
wewnątrz `Game.deposit_all` nadają ten stan dopiero po dokładnych deltach
i sprawdzeniu tej samej sesji postaci. Seria w depo ma osobny rekord dla
każdego transferu, nie jeden rekord potwierdzający całą serię.
Bank i handel w opcjonalnym inputcie również nadają `confirmed`, gdy ich
obserwator sprawdzi odpowiednio saldo/gotówkę lub przedmioty/kwotę i
handler zakończy się w tej samej sesji. Sam komunikat zwrotny funkcji nie
promuje statusu.
Samo `moveitem()` nie uruchamia automatycznie takiego obserwatora.

```lua
local operation = inputactionid()
local status = inputstatus(operation)
local action = inputaction(operation)
```

Identyfikator pozwala sprawdzić starszy transfer po innej akcji. Wyniki są
spójne w obrębie snapshotu Lua i odświeżane po dispatch. Nie służą do
automatycznego powtarzania niepotwierdzonych zakupów lub przenoszenia.

`actionbarcount()` zwraca liczbę rozpoznanych, niepustych wpisów paska akcji.
`hasitemhotkey(id)` sprawdza, czy przedmiot ma przypisany skrót klawiaturowy,
a `hasspellhotkey("formuła")` robi to samo dla dokładnej formuły czaru
(bez rozróżniania wielkości liter i nadmiarowych spacji). Brak skrótu daje
`false`; brak lub błąd odczytu klienta jest błędem skryptu. Wpis bez skrótu
nadal może być aktywowany kliknięciem przez moduł wejścia. Sam skrót nie
potwierdza zapasu przedmiotów, dostępności czaru, celu ani cooldownu.

```lua
-- Te zapytania tylko czytają konfigurację bieżącego klienta.
local entries = actionbarcount()
local healthBound = hasitemhotkey(266)
local healBound = hasspellhotkey("exura")
```

Do wykonania nadal używaj `useself()`, `usetarget()` lub `spell()`.
Zachowują kontrolę celu/cooldownu i pierwszeństwo rozpoznanych przycisków
przed wpisywaniem formuły. Odczyt paska jest współdzielony w obrębie
snapshotu Lua i odświeżany po wykonanej akcji; nazwy ani skróty nie są
zapamiętywane globalnie pomiędzy klientami.

| Funkcja | Wynik i działanie |
|---|---|
| `itemcount(id [, lokalizacja])` | liczba w wyposażeniu i otwartych kontenerach; filtr lokalizacji dopasowuje fragment nazwy bez wielkości liter |
| `groundcount(id, x, y, z)` | suma potwierdzonych liczności fizycznych przedmiotów na odczytanym polu |
| `isitemontile(id, x, y, z)` | obecność ID w bieżącym snapshotcie mapy; nie oznacza zasięgu użycia ani możliwości podniesienia |
| `canshoot(x, y, z)` | `true/false` dla znanej lokalnej linii strzału; nieznany stan zgłasza błąd |
| `getfacing()` | `"north"`, `"east"`, `"south"` albo `"west"` |
| `islocation([zakres])` | czy postać jest przy bieżącym waypoincie Action, na tym samym piętrze; domyślny zakres 0; poza takim waypointem zwraca false |
| `getlurelocation(nazwa)` | czy nazwana lokalizacja istnieje; zwraca bool, nie współrzędne |
| `getoption(nazwa)` | wartość opcji skryptowej lub nil, gdy brak |

`itemcount()` nie przeszukuje zamkniętych plecaków ani banku. Otwarte okna
zwłok lub depozytu mogą wejść do ogólnej sumy; użyj filtra nazwy, gdy
potrzebujesz konkretnego źródła. Numery kontenerów mogą zostać ponownie
użyte po zamknięciu: nie zapisuj ich na stałe między sesjami.

### Cooldowny, okna, NPC, bank i Stash

| Funkcja | Wynik i wymagania |
|---|---|
| `spellcooldown(formuła)` | pozostały cooldown własny i grup czaru, w sekundach |
| `itemcooldown()` | pozostały wspólny cooldown multi-use, w sekundach |
| `windowcount()` | liczba widocznych korzeni dialogów/menu, nie liczba wszystkich sidebarów |
| `windowexists(tytuł)` | czy widoczne jest okno o dokładnie podanym tytule |
| `npcisopen()` | czy rozmowa NPC jest widoczna |
| `npcname()` | nazwa z otwartej rozmowy lub pusty napis |
| `npcmessage()` | ostatnia rozpoznana odpowiedź NPC, bez prefiksu czasu/nazwy; pusty napis, gdy brak |
| `npccontains(tekst)` | czy ostatnia odpowiedź zawiera tekst, bez rozróżnienia wielkości liter |
| `bankbalance()` | ostatnie potwierdzone saldo w kontekście wejścia; wcześniej wykonaj checkbank() |
| `stashcount(id)` | ilość w dostępnym odczycie otwartego Supply Stash; zamknięty Stash oznacza stan nieznany |

`bankbalance()` samo nie wysyła pytania do bankiera. Stan nieznany nie
jest równoważny saldu 0. Wiadomości gracza nie są odpowiedziami NPC.
`canshoot()` jest zachowawczą oceną lokalnej mapy, nie gwarancją trafienia.

### Śmierć i błogosławieństwa

| Funkcja | Wynik |
|---|---|
| `isdead()` | bool: poprawne max HP i aktualne HP ≤ 0 |
| `deathcount()` | licznik śmierci sesji, jak `$deathcount` |
| `hasblessing(nazwa_lub_id)` | czy postać ma wskazane błogosławieństwo |
| `hasblessings()` | czy ma przynajmniej jedno z siedmiu zwykłych błogosławieństw |
| `hasallblessings()` | czy ma wszystkie siedem zwykłych błogosławieństw |
| `blessingscount()` | liczba zwykłych błogosławieństw, bez Adventurer i Twist |
| `blessings()` / `blessingnames()` | nazwy posiadanych błogosławieństw jako jeden napis rozdzielony przecinkami |

| ID klienta | Nazwa przyjmowana przez hasblessing |
|---|---|
| 1 | Adventurer's Blessing |
| 2 | Twist of Fate |
| 4 | Wisdom of Solitude |
| 8 | Spark of the Phoenix |
| 16 | Fire of the Suns |
| 32 | Spiritual Shielding |
| 64 | Embrace of Tibia |
| 128 | Heart of the Mountain |
| 256 | Blood of the Mountain |

Nazwa może być podana bez prefiksu `The`, niezależnie od wielkości liter.
Nie są to kolejne indeksy 1–9: używaj nazw lub dokładnych ID z tabeli.
Brak dostępu do odczytu blessów zgłasza błąd; nie zwraca fałszywego „brak”.

### Stany postaci

| Funkcja | Wynik |
|---|---|
| `statusknown()` | bool: czy snapshot zawiera poprawną maskę stanów |
| `statusflags()` | liczba: surowa maska 32-bitowa, także z nierozpoznanymi bitami |
| `hascondition("poisoned")` | bool: czy wskazany stan jest aktywny |
| `conditions()` | tekst: aktywne nazwy oddzielone przecinkami; pusty tekst przy braku stanów |
| `ispoisoned()`, `isparalyzed()`, `isburning()` | skróty zatrucia, paraliżu i podpalenia |
| `ishasted()`, `isbleeding()`, `isdrunk()` | skróty przyspieszenia, krwawienia i upojenia |
| `iselectrified()`, `iscursed()`, `ismanashielded()` | skróty elektryzacji, klątwy i magicznej tarczy |

Nazwy do `hascondition`: `poisoned`, `burning`, `electrified`, `drunk`,
`mana_shield`, `paralyzed`, `hasted`, `in_fight`, `drowning`, `freezing`,
`dazzled`, `cursed`, `party_buff`, `pz_block`, `protection_zone`, `bleeding`,
`hungry`. Przyjmowane aliasy: `poison`, `burn`, `fire`, `energy`, `paralyze`,
`paralysed`, `haste`, `manashield`, `pz`, `pzblock`.

Funkcje oprócz `statusknown()` zgłaszają błąd przy nieznanym odczycie.
Nieobsługiwana nazwa też jest błędem. Brak pola `status` w starym agencie
oznacza stan nieznany, a jawne `status=0` oznacza brak aktywnych stanów.
`$hungry` nadal korzysta z licznika jedzenia; ikonę głodu sprawdza
`hascondition("hungry")`. Nieznane wysokie bity są zachowane wyłącznie
w `statusflags()`. Mapa bitów pochodzi z enum PlayerStates w
[kodzie OTClient](https://github.com/edubart/otclient/blob/master/src/client/const.h).
Pełne potwierdzenie wszystkich efektów w bieżącej wersji klienta wymaga
obserwacji każdego z nich na żywo.

```lua
if statusknown() and ispoisoned() and $level >= 10 and $mp >= 30 then
    if spellcooldown("exana pox") == 0 then
        spell("exana pox")
    end
end
```

```lua
if statusknown() and hascondition("paralyzed") and $mp >= 10 then
    if spellcooldown("exura infir ico") == 0 then
        spell("exura infir ico")
    end
end
```

Takie skrypty planują zwykłe czary przez wybrane wejście. Samo wysłanie
czaru nie dowodzi usunięcia efektu. Wbudowany Condition Healer potwierdza
zniknięcie flagi w tej samej sesji, korzysta ze wspólnych cooldownów
i kolejki priorytetów. Nie dodaje domyślnie żadnej aktywnej reguły.

### Matematyka i losowanie

| Funkcja | Wynik |
|---|---|
| `min(a, ...)` / `math.min(a, ...)` | minimum z 1–32 liczb |
| `max(a, ...)` / `math.max(a, ...)` | maksimum z 1–32 liczb |
| `abs(x)` / `math.abs(x)` | wartość bezwzględna |
| `floor(x)` / `math.floor(x)` | zaokrąglenie w dół |
| `ceil(x)` / `math.ceil(x)` | zaokrąglenie w górę |
| `random()` / `math.random()` | liczba od 0 włącznie do 1 wyłącznie |
| `random(maximum)` / `math.random(maximum)` | całkowita liczba od 1 do maximum, oba końce włącznie |
| `random(minimum, maximum)` / `math.random(minimum, maximum)` | całkowita liczba w domkniętym zakresie |

## Polecenia sterujące

### Ruch, walka, czary i przedmioty

| Funkcja | Działanie |
|---|---|
| `move(kierunek)` | ruch zgodny z wybranym trybem inputu |
| `turn(kierunek)` | obrót bez chodzenia; tylko north/east/south/west |
| `facetarget(id)` | obrót do aktywnego celu |
| `attack(id)` | wybór atakowanego celu; 0 anuluje własne targetowanie |
| `follow(id)` | podążanie za celem; 0 anuluje |
| `stop()` | zatrzymanie przez obsługiwany skrót/Esc w trybie klawiatury i myszy; nie klika przycisku Stop |
| `cancel()` | anulowanie bieżącej czynności |
| `loot()` | skonfigurowany quick loot przez wybrane wejście |
| `hotkey(skrót)` | np. `"F1"` lub `"Ctrl+F2"`; używa bieżącego przypisania klienta |
| `spell(formuła)` | czar, z kontrolą cooldownu i preferowaniem rozpoznanego paska akcji |
| `spelltarget(formuła, id [, zasięg])` | czar na aktywny cel; zasięg domyślnie 3, zakres 1–7 |
| `useitem(id)` | użycie przedmiotu |
| `useself(id)` | użycie na własnej postaci |
| `ensureaol([maksymalna_cena])` | zachowuje założony AoL albo pozyskuje i zakłada brakujący; limit 1–70000 gp, domyślnie 70000 |
| `usetarget(id, cel)` | użycie runy/przedmiotu na aktywnie atakowanym celu na mapie |
| `useinventory(slot, id)` | użycie przedmiotu z wyposażenia |
| `usecontainer(kontener, slot, id)` | użycie przedmiotu z otwartego kontenera |
| `useworld(x, y, z, id)` | użycie obiektu na polu świata |
| `moveitem(id [, ilość, źródło, slot_źródła, cel, slot_celu])` | przenoszenie; nil oznacza wyposażenie; podawaj pełne źródło i cel |
| `pickupitem(id, x, y, z, kontener [, ilość, slot])` | podniesienie do plecaka; domyślnie maksymalny dostępny stos, slot wybierany automatycznie |
| `refillammo(id [, minimum, ilość, kołczan])` | uzupełnienie poniżej minimum do zadanej ilości; domyślnie 50/100 i jedyny otwarty kołczan |

Kierunki ruchu: `north`, `east`, `south`, `west`, `ne`, `se`, `sw`, `nw`.
`move()` nie jest poleceniem przejścia do dowolnych współrzędnych; trasę
wyznaczają waypointy. Po ustawieniu celu stan sprawdza się przez `$target`.

`spelltarget`, `facetarget` i `usetarget` wymagają właściwego aktywnego celu.
Brak zasięgu, zmiana celu lub zablokowana/nieznana linia strzału przerywają
odpowiednie użycie. Samo zużycie runy lub many nie dowodzi zadanych obrażeń.
Dobierz czar do profesji, poziomu i wyuczonych umiejętności postaci.

Domyślne `moveitem()` to ilość 1, źródło/cel nil i sloty 0. Nie oznacza to
automatycznego wyszukania źródła; najczęściej potrzebne jest wszystkich
sześć argumentów. Przy ilości większej niż źródłowy stos polecenie może
zostać odrzucone. Nie ponawiaj w pętli transferu o nieznanym wyniku.
Uzupełnianie amunicji wymaga otwartego kołczanu i zapasu w otwartych
plecakach. Przy kilku kołczanach podaj jego numer. Funkcja nie kupuje
amunicji, nie otwiera kołczanu i nie zakłada go do wyposażenia.

### Czat, NPC i handel

| Funkcja | Działanie |
|---|---|
| `chat_on()` / `chaton()` | włączenie pisania na czacie |
| `chat_off()` / `chatoff()` | wyłączenie pisania na czacie |
| `say(tekst)` | zwykła wiadomość lokalna |
| `npcsay(tekst)` | wiadomość do właściwego okna rozmowy NPC |
| `npcdialog(akcja)` | akcja `yes`, `no`, `bye`, `trade` lub `close` |
| `npcyes()` / `npcno()` | odpowiedź przyciskiem yes/no |
| `npctrade()` | otwarcie handlu |
| `npcbye()` / `npcclose()` | pożegnanie / zamknięcie okna |
| `buyitems(nazwa, ilość)` | zakup 1–100 sztuk; sprawdzenie ceny i obu zmian stanu |
| `sellitems(nazwa, ilość)` | sprzedaż 1–100 sztuk z potwierdzeniem przedmiotów i pieniędzy |

Do NPC używaj małych liter. `say("hi")` może rozpocząć rozmowę, ale dalsze
odpowiedzi wysyłaj przez `npcsay()`. Skrót `hotkey()` nie sprawdza zamiaru
konkretnego przypisania; do czarów i mikstur preferuj polecenia semantyczne.
`npcsay("hi")` i `npcsay("hello")` działają też na świeżym kliencie bez
zakładki NPCs: samo powitanie korzysta wtedy z Local Chat. Inne wiadomości
wymagają istniejącej rozmowy lub kanału NPCs. Wysłanie powitania nie dowodzi
odpowiedzi: sprawdzaj `npcisopen()`, `npcname()` i `npcmessage()` przed dalszą
operacją. NPC musi być w zasięgu rozmowy na tej samej kondygnacji.
Na kliencie 15.33.124f6c Native wysyła odpowiedzi przez typowaną metodę
kontrolera otwartego okna NPC. Wymaga aktualnej rozmowy i tego samego NPC
w zasięgu. Nie używa fokusu klawiatury ani starego settera protobuf.
Odpowiedź Gustavo na „goblins” została potwierdzona w grze.
W trybie klawiatury i myszy potrzebne przedmioty muszą być dostępne przez
rozpoznany pasek akcji, wyposażenie lub otwarte okna.

### Bank, depozyt i Supply Stash

| Funkcja | Działanie |
|---|---|
| `checkbank()` | pyta bankiera o saldo; następnie odczytaj bankbalance() |
| `bankdeposit([kwota])` | wpłata kwoty lub wszystkich dostępnych monet |
| `bankwithdraw(kwota)` | wypłata; moduł sam wysyła yes po właściwym pytaniu i potwierdza saldo/monety |
| `depositall()` | wpłata wszystkich monet do **banku**, alias zachowania bankdeposit() |
| `opendepot()` | otwarcie pobliskiego depozytu |
| `opendepotbox([numer])` | otwarcie skrzynki depozytu; domyślnie 1 |
| `deposit(id [, skrzynka, ilość])` | odłożenie przedmiotu; domyślnie skrzynka 1, ilość 1 |
| `withdraw(id [, skrzynka, ilość])` | wyjęcie do plecaka; domyślnie 1 i 1 |
| `depositer([nazwa, depot(x,y,z), box(n)])` | odłożenie lootu określonego w konfiguracji Looting, ze wszystkich stosów |
| `findfreedepot([depot(x,y,z)])` | wybór wolnego, osiągalnego pola przed lockerem i otwarcie własnego depozytu |
| `reachnpc(nazwa [, dystans])` | podejście do aktualnej pozycji NPC o dokładnej nazwie, domyślnie na 3 pola; dystans 1–3 |
| `deposititems(id, ... [, nazwa, depot(x,y,z), box(n)])` | odłożenie wszystkich stosów wskazanych ID |
| `box(n)` | znacznik skrzynki dla depositer/deposititems, n=1–21 |
| `depot(x,y,z)` | znacznik pozycji dla wysokopoziomowego odkładania |
| `openstash()` / `closestash()` | otwarcie / zamknięcie Supply Stash |
| `retrievestash(id [, ilość])` | pobranie; domyślna ilość 1 |
| `stowitem(id [, ilość])` | odłożenie do Stash; domyślnie 1 |
| `stash(nazwa_plecaka)` | wysokopoziomowa obsługa Stash dla wskazanego otwartego plecaka |

`depositall()` to bank, `depositer()` to loot do depozytu — to różne funkcje.
Nie dopisuj ręcznie `npcyes()` po `bankwithdraw()`: potwierdzenie jest już
obsługiwane i sprawdzane. Duża ilość w `deposit/withdraw` nie oznacza
automatycznej pętli przez wszystkie kontenery; do wszystkich stosów służą
`depositer` i `deposititems`. Te operacje potrzebują dostępu do depozytu
oraz właściwych otwartych plecaków. Podawanie samych współrzędnych nie
omija ścian, odległości i wymagań interakcji.

`findfreedepot()` sprawdza świeżą mapę i postacie, podchodzi dokładnie na
pole dostępu, po czym ponownie sprawdza zajętość i otwiera depozyt.
Opcjonalna pozycja ogranicza wyszukiwanie do sąsiedztwa danego depozytu.
Przy braku wolnego stanowiska ponawia odczyty do 30 sekund, a następnie
wstrzymuje sekwencję. Nie potwierdza depozytu ani zakupów bez powodzenia.
W skrypcie wykonywanym na żywo można po nim wywołać `depositer(box(1))`.

### Okna i Look

| Funkcja tutorialu Native | Działanie |
|---|---|
| `buttonexists(napis)` | obserwacja jednoznacznych przycisków dialogu |
| `clientbutton(napis [, tytuł_okna])` | kliknięcie przycisku wybranego po napisie i opcjonalnym tytule okna |
| `tutorialhint()` | aktualna wskazówka tutorialu; pusty tekst oznacza brak wskazówki |
| `tutorialhintcontains(tekst)` | dopasowanie do aktualnej wskazówki, bez rozróżnienia wielkości liter |
| `tutorialclick(oczekiwana_wskazówka [, przycisk])` | kliknięcie aktualnego podświetlenia tutorialu; przycisk left/right |
| `tutorialdrag(oczekiwana_wskazówka)` | przeciągnięcie jedynego widocznego przedmiotu do pustego celu wskazanego przez tutorial |
| `tutorialuse(oczekiwana_wskazówka)` | kliknięcie podświetlonego narzędzia, następnie drugiego celu tutorialu, np. użycie liny |
| `classiccontrols()` | ustawienie Classic Controls w kliencie, Apply i ponowne otwarcie opcji w celu sprawdzenia zapisu; wymaga Native, zamkniętych dialogów i braku potworów na ekranie |
| `choosevocation(nazwa)` | wybór i potwierdzenie profesji w oknie tutorialu; przycisk Confirm musi należeć do karty tej profesji |

Przeciąganie wybiera źródło według odczytanego przedmiotu w slocie, nie po
miejscu wyświetlenia napisu wskazówki. Kilka celów, dwa pełne sloty lub brak
przedmiotu przerywają operację. Zwolnienie myszy jest wykonywane również po
błędzie. Te funkcje używają istniejącego mostka Qt agenta i nie przenoszą
systemowego kursora ani nie przełączają wejścia na memory.

W trybie Native `buttonexists("Start")` odczytuje widoczne przyciski dialogów
klienta, a `clientbutton("Start")` wybiera jeden jednoznaczny przycisk po jego
napisie. Nie wybiera elementów paska akcji ani nie klika stałych współrzędnych.
Brak odczytu, kilka pasujących przycisków, śmierć lub zmiana sesji przerywają
operację. Samo wysłanie kliknięcia nie potwierdza przejścia tutorialu; odczytaj
następny ekran/pozycję przed kolejną akcją. Tryb memory nie przełącza się
automatycznie na tę operację Native.

| Funkcja | Działanie |
|---|---|
| `opencontainer(id)` | otwarcie wyposażonego plecaka z domyślnego slotu 3; do wyszukiwania w środku użyj openitem() |
| `openitem(id_lub_nazwa [, źródło, nowe_okno, indeks])` | wyszukiwanie i otwieranie; domyślnie nowe okno=true, indeks=1; źródło to nazwa lub ground(x,y,z) |
| `ground(x,y,z)` | znacznik położenia dla openitem() |
| `closecontainer(numer)` | zamknięcie wskazanego otwartego kontenera |
| `containerup(numer)` | przejście do nadrzędnego kontenera w tym oknie |
| `minimizecontainer(numer)` / `maximizecontainer(numer)` | ustawienie stanu okna; powtórne ustawienie nie przełącza go z powrotem |
| `closewindows([limit])` | Esc dla dialogów/menu, domyślnie 6, maksymalnie 8; nie zamyka automatycznie okna śmierci |
| `lookinventory(slot, id)` | Look na przedmiocie wyposażenia |
| `lookcontainer(numer, slot, id)` | Look w konkretnym kontenerze |
| `lookworld(x,y,z)` | Look na wierzchu pola świata |
| `lookcreature(id)` | Look na wskazanej postaci/NPC/potworze |
| `deathdialog([akcja])` | domyślnie revive; character_list przechodzi do listy postaci |

Look czeka na nową odpowiedź klienta; w Lua nie zwraca tekstu opisu.
Brak świeżego wyniku jest błędem bez ponawiania. Zamknięcie/up/zwinięcie
kontenera sprawdza rzeczywistą tożsamość okna. `containerup()` bez dostępnego
rodzica nie jest automatycznie traktowane jako sukces.

### Aliasy poleceń

Oprócz nazw z tabel działają `npc_dialog()`, `use_item()`, `use_self()`,
`use_inventory()`, `use_container()`, `use_world()`, `move_item()` i
`open_container()`, z takimi samymi argumentami jak ich zwarte odpowiedniki.

## Trasa i konfiguracja

### Konfiguracja skryptu i profile postaci

Karta **Konfiguracja skryptu** zawiera opcje i zapasy, jedyny edytor reguł
plecaków oraz osobny edytor definicji Lua. Po zmianach kliknij **Zastosuj**.
Cavebot i Action korzystają z tych samych wartości przy
następnym odczycie; nie trzeba restartować trasy. **Plik → Zapisz** utrwala
pełną konfigurację w XML: definicję formularza (`setup_code`) i domyślne
wartości opcji (`script_api.options`). Przy każdej opcji można wybrać
**Ze skryptu** albo **Własne dla postaci**. Tylko jawnie wybrane nadpisania
trafiają do wybranego profilu postaci, zachowując domyślne wartości w XML.
**Zapisz jako…** tworzy kopię bez modyfikowania poprzedniego skryptu.
`setsettings()` i **Zastosuj** zmieniają bieżącą konfigurację; zapis XML
wymaga **Zapisz** albo włączenia automatycznego zapisu w menu Plik.
Wybór innego skryptu nie przenosi opcji poprzedniego skryptu.

Definicję formularza wykonuje się offline. Dozwolone są poniższe deklaracje,
zmienne lokalne, warunki, pętle z limitem i podstawowe obliczenia. Polecenia
gry, odczyty klienta, `wait()` i zmiany ustawień są w tym edytorze odrzucane.
Deklaracje kontrolek nie są przeznaczone do waypointów ani cyklicznych Action.

Edytor **Definicja Lua / JSON** przyjmuje też formularz JSON w stylu
WindBot User Options: pojedynczą grupę, tablicę grup lub grupy rozdzielone
przecinkami. Obsługiwane typy to `group`, `lineedit`, `checkbox`, `combobox`,
`spinbox`, `doublespinbox` i `rangespinbox`. Grupy mają `children`,
`column` (1 lub 2) i opcjonalne `checkable`. Opisy `description` są
podpowiedziami; pola tekstowe obsługują `placeholder`, a liczbowe `prefix`
i `suffix`. Checkbox grupy wyłącza edycję jej dzieci; skrypt powinien sam
sprawdzać wartość grupy przed wykonaniem związanych z nią czynności.
Nie jest to importer całych skryptów WindBota.

`rangespinbox` zapisuje dwie granice jako `[od, do]`; pojedyncze `value`
ustawia obie granice jednakowo. `getuseroption("wait_spawn")` zwraca tabelę
z polami `from` i `to`, np.:

```lua
if getuseroption("wait_spawn") then
  local bounds = getuseroption("wait_spawn")
  wait(random(bounds.from, bounds.to))
end
```

Przycisk **Wstaw przykładowy JSON** zawiera komplet podstawowych kontrolek.
Formularz JSON i jego wartości zapisują się w tym samym XML i profilach co
formularz Lua. Zmiana formatu nie uruchamia żadnych poleceń gry.

| Deklaracja w edytorze formularza | Działanie |
|---|---|
| `addmenu(klucz, tytuł)` | tworzy lub wybiera grupę/menu dla kolejnych kontrolek |
| `addcheckbox(klucz, etykieta, domyślna)` | checkbox z wartością true/false |
| `addspinbox(klucz, etykieta, domyślna, minimum, maksimum [, krok])` | pole liczbowe, domyślny krok 1; dla ułamków podaj krok mniejszy od 1 |
| `addtextbox(klucz, etykieta, domyślna)` | pole tekstowe |
| `addcombobox(klucz, etykieta, domyślna, wybory)` | lista; wybory to tekst np. `"safe\|normal"` |
| `addlabel(tekst)` | opis w bieżącym menu |
| `addsupply(klucz, etykieta, id, minimum, cel)` | cztery pola `supplies.KLUCZ.enabled/id/minimum/target`; minimum nie może przekroczyć celu |
| `addbackpack(nazwa, id [, rodzic, przeznaczenie])` | dodaje brakującą regułę do istniejącego menedżera plecaków; nie nadpisuje zapisanej reguły o tej samej nazwie; przeznaczenie: loot/gold/supplies/other |

Domyślne reguły plecaków są dodawane raz w danej konfiguracji postaci.
Późniejsza zmiana nazwy lub usunięcie reguły w profilu nie tworzy ponownie
starej reguły z szablonu.

Klucze kontrolek muszą być unikalne; dozwolone są litery ASCII, cyfry,
podkreślenie, kropka i myślnik. Maksymalnie 200 kontrolek, 30 menu i 50 reguł
plecaków na definicję. Przykład definicji (wklej do **Definicja Lua**):

```lua-setup
addmenu("return", "Powrót i zapasy")
addcheckbox("return_enabled", "Kontroluj powrót", true)
addspinbox("min_cap", "Minimalny cap", 150, 0, 10000)
addtextbox("return_label", "Etykieta powrotu", "refill")
addsupply("mana", "Mana potion", 268, 50, 300)
addmenu("hunt", "Polowanie")
addcombobox("hunt_mode", "Tryb", "normal", "safe|normal")
addlabel("Dostosuj zapasy i nazwy plecaków do postaci.")
addbackpack("Backpack", 2854, "", "supplies")
```

| Funkcja dostępna w Cavebocie i Action | Wynik / działanie |
|---|---|
| `getuseroption(klucz)` | alias getoption(); zwraca zapisaną wartość albo domyślną z formularza |
| `setuseroption(klucz, wartość)` | alias setoption(); waliduje typ i zakres zadeklarowanej kontrolki |
| `getsettings(ścieżka)` | odczyt opcji formularza lub rzeczywistych ustawień z tabeli poniżej |
| `setsettings(ścieżka, wartość)` | zapis wartości; wykonanie odświeża kontekst przed kolejnym poleceniem |
| `getsetting(ścieżka)` / `setsetting(ścieżka, wartość)` | aliasy getsettings/setsettings |
| `caplow()` | czy `$cap` jest mniejsze niż opcja min_cap; brak progu oznacza 0 |
| `supplycount(klucz)` | liczba przedmiotów dla ID z addsupply(); wyposażenie i otwarte kontenery |
| `supplyneed(klucz)` | ile brakuje do ilości docelowej, nie mniej niż 0 |
| `supplieslow()` | czy dowolny włączony zapas jest poniżej minimum |
| `needsrefill()` | return_enabled i (caplow lub supplieslow); brak return_enabled oznacza true |

| Ścieżka getsettings/setsettings | Wartość |
|---|---|
| `setup.min_cap`, `setup.return_label`, `setup.supplies.mana.target` | opcje formularza; prefiksy options/useroptions są równoważne; sam klucz też jest dozwolony |
| `navigation.pass_players_outside_pz`, `navigation.ignore_players_path`, `navigation.enter_echo_raids` | true/false, rzeczywista konfiguracja nawigacji |
| `looting.enabled`, `looting.quick_loot`, `looting.eat_food`, `looting.auto_echo_loot`, `looting.own_kills_only` | true/false, istniejący LootConfig |
| `containers.Backpack.keep_open`, `containers.Backpack.item_id`, `containers.Backpack.parent`, `containers.Backpack.purpose` | właściwości istniejącej reguły o nazwie Backpack; także pozostałe pola ContainerRule oprócz name |
| `priority.targeting`, `priority.looting`, `priority.cavebot` | priorytet 1–10, niższy wygrywa |

Można używać separatora `/` zamiast `.`. Nieznana ścieżka modułu, brakująca
reguła plecaka lub niewłaściwy typ są błędem. Nie jest to pełna zgodność
z dowolnymi historycznymi ścieżkami WindBota. Funkcje nie zmieniają
konfiguracji wejścia, danych logowania ani nie uruchamiają modułów GUI.
`looting.enabled` zmienia konfigurację modułu, nie przełącznik uruchomienia.
Podobnie odczyt zapasów nie kupuje przedmiotów i nie przeszukuje zamkniętych
plecaków. Zakupy/pobieranie należy wykonać jawnym kodem Lua na trasie.

Przykład waypointu Action korzystającego z formularza:

```lua
if needsrefill() then
    gotolabel(getuseroption("return_label"))
end
```

Przykład zmiany ustawień podczas wykonania:

```lua
setsettings("setup.min_cap", 200)
setsettings("navigation.enter_echo_raids", false)
setuseroption("hunt_mode", "safe")
```

W Test Lua zmiany ustawień są jedynie planem; rzeczywiste wartości zostają
bez zmian. Zapis profilu i zastosowanie formularza nie wykonują akcji gry.

Wzorzec formularzy został oparty na opisanym przez producenta mechanizmie
[WindBot Cavebot User Options](https://www.tibiawindbot.com/features.html).
RGXbot używa własnej składni deklaracji i własnych ścieżek ustawień.

### Sterowanie trasą i opcjami

| Funkcja | Działanie |
|---|---|
| `gotolabel(etykieta [, sekcja])` | skok do waypointu z etykietą; kończy bieżący skrypt |
| `gototab(nazwa)` | przełączenie zakładki trasy; kończy bieżący skrypt |
| `reachgrounditem(id [, dystans])` | podejście do widocznego obiektu; dystans domyślnie 1, zakres 0–18; kończy skrypt |
| `wait(ms)` | czekanie bieżącego skryptu, 0–3600000 ms |
| `stopbot([powód])` | zatrzymuje wszystkie moduły i kończy skrypt; opcjonalny powód do 200 znaków |
| `pausewalking(ms)` | pauza samego chodzenia, 0–3600000 ms |
| `setoption(nazwa, wartość)` | zapis opcji skryptowej; nie jest dowolnym wywołaniem ustawień GUI |
| `setlocation(nazwa, x,y,z)` | zapis nazwanej lokalizacji |
| `setlurelocation(nazwa, x,y,z)` | alias zapisu lokalizacji |
| `addspecialarea(nazwa, x,y,z)` | dodanie nazwanego pola wykluczonego z trasy |
| `removespecialarea(nazwa)` | usunięcie takiego pola |
| `setpriority(moduł, priorytet)` | priorytet targeting/looting/cavebot, liczba 1–10; niższa wygrywa |

W trybie opcjonalnego sterowania `wait` pozostawia klienta dostępnego dla
leczenia. Podczas pauzy scheduler sprawdza tę samą sesję postaci i obsługuje
włączony wspólny Healer; następna instrukcja nadal czeka na koniec pauzy.
Anulowanie, śmierć lub zmiana sesji przerywa dalsze instrukcje tego skryptu.
Leczenie może zmienić ostatnią operację wejścia podczas `wait`: do śledzenia
wcześniejszego transferu zachowaj jego `inputactionid()` przed pauzą.

Klucz techniczny `cavebot` oznacza moduł trasy. Lokalizacje i opcje
obsługuje runtime skryptów; nie są lokalnymi zmiennymi Lua. Funkcje skoku
wymagają istniejącej trasy/etykiety. `getlurelocation()` sprawdza tylko
obecność nazwy. `openitem()` i `stash()` również kończą bieżący skrypt.
W planie Test Lua operacje `findfreedepot/depositer/deposititems` kończą plan, natomiast
w wykonaniu na żywo mogą być kontynuowane po potwierdzonej operacji.

## Przykłady

Każdy blok poniżej jest oddzielnym przykładem. Dostosuj ID przedmiotów,
numery kontenerów, czary, etykiety i współrzędne do swojej postaci.

### Leczenie Knighta z kontrolą many i cooldownu

```lua
if not $dead and $hppc < 70 and $mp >= 10 then
  if spellcooldown("exura infir ico") == 0 then
    spell("exura infir ico")
  end
end
```

Do stałego leczenia używaj przede wszystkim reguł Healing. Przykład pokazuje
wywołanie funkcji; czar musi być dostępny dla tej postaci.

### Mikstura i uzupełnienie many

```lua
if $mppc < 40 and itemcount(268, "bag") > 0 then
  if itemcooldown() == 0 then
    useself(268)
  end
end
```

### Runa na aktywny cel

```lua
if $target > 0 and not $pz then
  if itemcount(21352) > 0 and itemcooldown() == 0 then
    usetarget(21352, $target)
  end
end
```

ID 21352 oznacza Lightest Missile Rune w bieżącym katalogu. Dla innej runy
sprawdź ID i wymagania. Pozycja i linia strzału są sprawdzane przez akcję.

### Jedzenie i jawny tryb czatu

```lua
if $hungry and itemcount(3578) > 0 then
  useitem(3578)
end
chat_off()
```

### Bank: sprawdzenie i bezpieczna wypłata

```lua
checkbank()
if bankbalance() >= 100 then
  bankwithdraw(100)
end
npcclose()
```

Stań przy bankierze. Wypłata sama potwierdza `yes`; nie dodawaj drugiego
potwierdzenia. `bankdeposit()` bez argumentu wpłaca wszystkie monety.

### Zakup brakujących mikstur

```lua
local brakuje = 5 - itemcount(266, "bag")
if brakuje > 0 then
  buyitems("health potion", min(brakuje, 100))
end
```

Stań przy właściwym sprzedawcy z dostępną ofertą, pieniędzmi i miejscem.
Zakup nie jest automatyczną wyprawą do sklepu. Poniższy osobny przykład
sprzedaje jedną fiolkę dopiero, gdy odczyt potwierdza jej posiadanie:

```lua
if itemcount(285, "bag") > 0 then
  sellitems("empty potion flask", 1)
end
```

### Rozmowa NPC

```lua
say("hi")
if npcisopen() and npcname() == "Aurelia" then
  npctrade()
end
```

Nie zastępuj `npcsay()` zwykłym `say()` przy dalszych odpowiedziach.
`npccontains("balance")` sprawdza odpowiedź, a nie historię własnych wypowiedzi.

### Uzupełnienie kołczanu

```lua
refillammo(3447, 50, 100)
```

Wymaga dokładnie jednego otwartego kołczanu. Przy kilku wybierz aktualne ID:

```lua
refillammo(3447, 50, 100, 2)
```

### Przeniesienie jednego przedmiotu do wyposażenia

```lua
moveitem(3338, 1, 0, 2, nil, 6)
```

Przykład zakłada Bone Sword w kontenerze 0, slocie 2. Slot 6 jest ręką
broni. Stan źródła i faktyczny numer okna trzeba ustalić przed uruchomieniem.
Nie uruchamiaj tego cyklicznie, gdy wyniku pierwszej operacji nie potwierdzono.

### Odkładanie lootu i pobieranie ze Stash

```lua
opendepotbox(2)
deposititems(3031, 3272, box(2))
```

```lua
openstash()
local brakuje = 5 - itemcount(266, "bag")
if brakuje > 0 and stashcount(266) >= brakuje then
  retrievestash(266, brakuje)
end
closestash()
```

### Kontenery i Look

```lua
maximizecontainer(0)
lookinventory(6, 3338)
lookcontainer(0, 0, 285)
minimizecontainer(0)
```

Przykład wymaga fiolki w slocie 0 kontenera 0. Możesz osobno użyć
`containerup(0)`, `closecontainer(0)`, `lookworld($x, $y, $z)` lub
`lookcreature($target)` przy dodatnim i widocznym ID.

### Powrót do etykiety przy małym zapasie

```lua
if itemcount(266, "bag") < 2 or $cap < 40 then
  gotolabel("depo")
end
```

Trasa musi mieć etykietę `depo`. To przełączenie trasy, nie niezależny
system ucieczki przed walką i nie gwarancja bezpiecznej drogi.

### Sprawdzenie blessów i śmierci

```lua
local liczba = blessingscount()
local twist = hasblessing("Twist of Fate")
local komplet = hasallblessings()
local nazwy = blessings()
```

```lua
if isdead() then
  deathdialog("revive")
  return
end
```

Do automatycznej reakcji po śmierci preferuj ustawienia polityki śmierci.
Skrypt nie zmienia jej limitu śmierci ani decyzji o wznowieniu.

### Opcje, blokada pola i losowa przerwa

```lua
setoption("tryb_testowy", true)
setlocation("baza", $x, $y, $z)
addspecialarea("pole_do_ominiecia", $x + 1, $y, $z)
setpriority("targeting", 1)
pausewalking(random(200, 400))
```

Usuń blokadę później przez `removespecialarea("pole_do_ominiecia")`.
Losowanie w tym przykładzie dotyczy czasu; ruch myszy i sposób chodzenia
konfiguruje osobno opcjonalny moduł wejścia.

### Pętla z jawnym ograniczeniem

```lua
local i = 0
while i < 3 do
  i = i + 1
  if $dead then
    break
  end
  wait(100)
end
```

Nie twórz nieograniczonej pętli leczenia albo handlu. Skrypt Action może
być wywoływany okresowo przez moduł, a stan między akcjami jest odświeżany.

## Błędy i ograniczenia

- Nieznany cooldown, blessy, saldo lub Stash są błędem odczytu, nie zerem.
- Zła liczba argumentów, ID 0, niecałkowita ilość i nieznana nazwa funkcji
  są odrzucane. Wyjątki takie jak `attack(0)` są opisane osobno.
- Zmienione okno, brak przedmiotu, niepotwierdzony transfer lub zakup
  wymagają sprawdzenia stanu. Nie powtarzaj operacji na ślepo.
- Test Lua nie sprawdza dostępności towaru, wyuczenia czaru ani rezultatu
  serwera. Ostateczny wynik potwierdzają odczyty podczas wykonania na żywo.
- Otwieranie plecaków, handel i Look mogą wymagać widocznych kontrolek
  wewnątrz klienta, również gdy sam klient działa na ukrytym wirtualnym ekranie.

Powiązane opisy: [walka dystansowa](RANGED_INPUT.md),
[scheduler leczenia](HEALING_SCHEDULER.md), [moduł wejścia](INPUT_EXTENSIONS.md).
