Skriptování: Porovnání verzí
(→Vyhodnocování podmínek) |
|||
(Nejsou zobrazeny 3 mezilehlé verze od stejného uživatele.) | |||
Řádka 30: | Řádka 30: | ||
=== Pořadí vyhodnocení === | === Pořadí vyhodnocení === | ||
− | Sphere vyhodnocuje argumenty podmínek zleva. Výraz | + | Sphere vyhodnocuje argumenty podmínek zleva. Výraz <code>IF (f_one && f_two)</code> tedy nejprve vyhodnotí <code>f_one</code> a poté <code>f_two</code> |
=== Eval - magické slovo === | === Eval - magické slovo === | ||
− | Ve spoustě podmínek a vyhodnocení výpočtů se používá klíčové slovo | + | Ve spoustě podmínek a vyhodnocení výpočtů se používá klíčové slovo <code>eval</code>. Co ale znamená a kdy ho (ne)použít? |
− | + | <code>Eval</code> je zkrácením anglického evaluate = vyhodnotit/ohodnotit. Výsledkem operace eval je '''vždycky''' decimální '''neprázdná''' hodnota. Použití tohoto klíčového slova je tedy vhodné na místech, kde sphere | |
# sama nedokáže rozhodnout, že se má zadaný výraz vyhodnotit jako číslo | # sama nedokáže rozhodnout, že se má zadaný výraz vyhodnotit jako číslo | ||
Řádka 42: | Řádka 42: | ||
<pre> | <pre> | ||
if (<eval src.qtag(q001_borek)> == 0) | if (<eval src.qtag(q001_borek)> == 0) | ||
− | </pre> Tento kód by byl '''bez''' použití volání | + | </pre> Tento kód by byl '''bez''' použití volání <code>eval</code> nekorektní, protože volání <code><src.qtag(q001_borek)></code> nad hráčem, který daný tag vůbec nemá, vrátí prázdný string, tedy žádnou hodnotu. Sphere by tím pádem po vyhodnocení levé strany rovnosti porovnávala kód: |
+ | <pre> | ||
if ("" == 0) | if ("" == 0) | ||
− | </pre> což je zcela nevalidní podmínka a takový běh vyhodí ERROR. Volání funkce | + | </pre> |
− | if (0 == 0) | + | což je zcela nevalidní podmínka a takový běh vyhodí ERROR. Volání funkce <code>eval</code> na prázdný string ovšem vrátí nulu, což je již korektní podmínkou. Takto bude sphere postupovat ve vyhodnocování výrazu s <code>eval</code>em: |
+ | <pre> | ||
+ | 1. if (<eval ""> == 0) | ||
+ | 2. if (0 == 0) | ||
+ | </pre> | ||
+ | |||
+ | === Magická nula v podmínkách === | ||
+ | |||
+ | Ve skriptech se můžete setkat s podivnou podmínkou, která vypadá nějak takhle | ||
+ | <pre> | ||
+ | if (0<src.qtag(q001_borek)> == 1) | ||
+ | </pre> | ||
+ | Tato syntaxe řeší stejný problém, který je popsaný v sekci pro Eval. V případě, že <code>src.qtag(q001_borek)</code> není vůbec definovaný, vyhodnocení podmínky bez přidané nuly by způsobilo chybu. Oproti tomu dodatečná nula na začátku podmínky způsobí, že test bude vždy vyhodnocovat porovnání čísel. | ||
+ | |||
+ | '''Ovšem pozor!!''' Není pravda, že by platilo následující | ||
+ | <pre> | ||
+ | if (010 == 10) | ||
+ | </pre> | ||
+ | Tato podmínka bude vyhodnocena jako nepravda. Čísla začínající nulou jsou ve sphere interpretována jako šestnáctková, ne desítková. Šestnáctková soustava má tedy v každém řádu šestnáctinásobek. Číslo 010 je tedy ve skutečnosti 16 v desítkové, 011 == 17, 012 == 18, 0A je 11, 0B je 12 atd. Proto pro ošetření testu podmínek na hodnotu tagu, který nemusí existovat, musíte buďto ošetřit očekávánou hodnotu na její šestnáctkový equivalent: | ||
+ | <pre> | ||
+ | if (0<src.qtag(q001_borek)> == 010) // 010 namisto očekávaných 10 -> transformace očekávané hodnoty do 16 soustavy na obou stranách podmínky | ||
+ | </pre> | ||
+ | nebo můžete využít funkci <code>eval</code>, jak bylo zmíněno v předchozí sekci. | ||
+ | <pre> | ||
+ | if (<eval src.qtag(q001_borek)> == 10) | ||
</pre> | </pre> | ||
Řádka 75: | Řádka 100: | ||
name=nove jmeno | name=nove jmeno | ||
</pre> | </pre> | ||
+ | |||
+ | === Kontrola Syntaxe === | ||
+ | |||
+ | Pro kontrolu syntaxe máme k dispozici vlastní [[Analyzer skriptů]], který provede statickou analýzu. |
Aktuální verze z 3. 1. 2022, 15:02
Na této stránce naleznete nějaká doporučení a informace o skriptování, která se snažíme dodržovat. Pokud se chystáte provádět nějaké změny, ujistěte se, že znáte i Scripting standard.
Doporučuji si projít stránku Skripty - názvosloví, kde jsou uvedeny některé běžně používané termíny.
Obsah
Na co si dát pozor
Linkování
Ukládání UID předmětu do proměnné LINK pevně sváže existenci cílového předmětu s předmětem, který má LINK uložený. To znamená, že pokud cílový předmět zmizí (je na hráči a ten si smaže postavu, smaže se chybným scriptováním při timeru nebo jiné akci), pak objekt s LINK proměnnou na toto UID se smaže také!
Best practice
- Pro linkování objektů používejte raději tagy vhodného jména, aby bylo jasné, za jakým účelem a co se v dané proměnné drží.
- Vždý, když vytváříte odkaz (ať už tagem, nebo linkem), ujistěte se, že linkee vždýcky smaže z linkeru referenci na sebe. V žádném případě nesmí nikdy nic odkazovat na UID, které se již smazalo! Toto UID může ve velmi krátkém sledu dostat naprosto jiný objekt a tím zcela randomizovat chování (kontrola na type nebo ID odkazovaného předmětu není dostatečnou náhradu za nedůsledné odmazávání odkazů)
- Pro odkazování skupiny předmětů používejte funkce:
f_customLink_add f_customLink_remove f_customLink_target
, případně pro dialogy:
f_item_linkAdder f_item_LinkRemover f_dialog_LinkWriter
Vyhodnocování podmínek
Pořadí vyhodnocení
Sphere vyhodnocuje argumenty podmínek zleva. Výraz IF (f_one && f_two)
tedy nejprve vyhodnotí f_one
a poté f_two
Eval - magické slovo
Ve spoustě podmínek a vyhodnocení výpočtů se používá klíčové slovo eval
. Co ale znamená a kdy ho (ne)použít?
Eval
je zkrácením anglického evaluate = vyhodnotit/ohodnotit. Výsledkem operace eval je vždycky decimální neprázdná hodnota. Použití tohoto klíčového slova je tedy vhodné na místech, kde sphere
- sama nedokáže rozhodnout, že se má zadaný výraz vyhodnotit jako číslo
- vyhodnocení výrazu může vést k prázdnému stringu, který by v testech vedl k chybě (ERROR). Příklad:
if (<eval src.qtag(q001_borek)> == 0)Tento kód by byl bez použití volání
eval
nekorektní, protože volání <src.qtag(q001_borek)>
nad hráčem, který daný tag vůbec nemá, vrátí prázdný string, tedy žádnou hodnotu. Sphere by tím pádem po vyhodnocení levé strany rovnosti porovnávala kód:
if ("" == 0)
což je zcela nevalidní podmínka a takový běh vyhodí ERROR. Volání funkce eval
na prázdný string ovšem vrátí nulu, což je již korektní podmínkou. Takto bude sphere postupovat ve vyhodnocování výrazu s eval
em:
1. if (<eval ""> == 0) 2. if (0 == 0)
Magická nula v podmínkách
Ve skriptech se můžete setkat s podivnou podmínkou, která vypadá nějak takhle
if (0<src.qtag(q001_borek)> == 1)
Tato syntaxe řeší stejný problém, který je popsaný v sekci pro Eval. V případě, že src.qtag(q001_borek)
není vůbec definovaný, vyhodnocení podmínky bez přidané nuly by způsobilo chybu. Oproti tomu dodatečná nula na začátku podmínky způsobí, že test bude vždy vyhodnocovat porovnání čísel.
Ovšem pozor!! Není pravda, že by platilo následující
if (010 == 10)
Tato podmínka bude vyhodnocena jako nepravda. Čísla začínající nulou jsou ve sphere interpretována jako šestnáctková, ne desítková. Šestnáctková soustava má tedy v každém řádu šestnáctinásobek. Číslo 010 je tedy ve skutečnosti 16 v desítkové, 011 == 17, 012 == 18, 0A je 11, 0B je 12 atd. Proto pro ošetření testu podmínek na hodnotu tagu, který nemusí existovat, musíte buďto ošetřit očekávánou hodnotu na její šestnáctkový equivalent:
if (0<src.qtag(q001_borek)> == 010) // 010 namisto očekávaných 10 -> transformace očekávané hodnoty do 16 soustavy na obou stranách podmínky
nebo můžete využít funkci eval
, jak bylo zmíněno v předchozí sekci.
if (<eval src.qtag(q001_borek)> == 10)
OR Operátor @||@
Vyhodnotí se, pokud je alespoň jedna strana operátoru pravdivá. Vzhledem k pořadí vyhodnocení, použití tohoto operátoru svádí ke klasickému využití línému vyhodnocování. ANI HOVNO přátelé. Sphere vždy vyhodnotí funkce na obou stranách operátoru, a až když má výsledky, vyhodnotí výsledek OR operátoru.
Z výše zmíněného, následující nelze použít:
if (!act || act.isitem) // pokud je act 0 vyhodi ERROR kvuli nemoznosti vyhodnotit 'isitem' nad null objektem act.color=012 act.name=nove jmeno endif
Podmínku je tedy nutné vyřešit nadmíru hnusně a perverzně, jako správné kodérské prase! Ale protože jsme vzdělaná prasata, stejný kód v podmínce alespoň zabalíme do funkce:
... if (!act) // pokud je act 0 vleze do podminky act.f_manipulateAct elseif (act.isitem) // uz vime, ze act neni 0, takze volani je bezpecne act.f_manipulateAct endif // the function is called upon the ACT // takes NO arguments [function f_manipulateAct] color=012 name=nove jmeno
Kontrola Syntaxe
Pro kontrolu syntaxe máme k dispozici vlastní Analyzer skriptů, který provede statickou analýzu.