Události
Každá událost se vyznačuje svým jménem a parametry, příklad:
ON_ROOM_BEGIN ... end ON_MOVE_STOP guppy ... end
V příkladu ON_ROOM_BEGIN je událost bez parametrů, ve druhém je událost s jedním parametrem označujícím objekt, který vykonal událost (dokončil pohyb).
Tento zápis ale není klasický styl zápisu Lua, např. za událost ON_ROOM_BEGIN se ve skutečnosti nahradí toto:
OnEvent(Enums.OnStart, "OnStart_%0") function OnStart_%0(eventId)globals.brArray={} globals.br_time=0 __had_begin__ = true
Za %0 se nahradí číslo, po kolikáté byla událost použita, v příkladu bude použita poprvé:
OnEvent(Enums.OnStart, "OnStart_0") - Toto je zaregistrování funkce OnStart_0 pro událost OnStart. (Enums.OnStart je číselná hodnota = 24)
function OnStart_0(eventId) - Toto je samotné vytvoření funkce, obsahuje jeden parametr eventId, společný pro všechny události. Zde se eventId rovná 0.
globals.brArray={} globals.br_time=0 - Toto je zřejmě inicializace startovních proměnných.
__had_begin__ = true - Proměnné __had_begin__ se nastaví true, je možno ji použít třeba v případě, pokud potřebujeme zjistit, zda místnost odstartovala. (if __had_begin__ then ... end)
Celá náhrada za událost je na jednom řádku, aby chybové zprávy ukazovaly správný řádek. Zde budeme jednotlivé části události rozepisovat:
OnEvent(Enums.OnMoveStop, "OnMoveStop_0") function OnMoveStop_0(eventId, objectId, direction) assert(guppy ~= nil, "Object guppy does not exist.") if objectId ~= guppy then return end local posX = ObjectX(objectId) local posY = ObjectY(objectId)
Na začátku se zaregistruje funkce, funkci OnMoveStop se nyní předávají již tři parametry, číslo události, id objektu, který vykonal událost, a u pohybových událostí i směr pohybu. Zkontroluje se, zda objekt guppy existuje a jestli tuto událost skutečně vyvolal. Poté se vytvoří lokální proměnné posX a posY, které můžeme použít rychleji bez použití ObjectX a ObjectY.
Více funkcí pro jednu událost
Z předchozího příkladu jsme pochopili, čím se ve skutečnosti nahrazují události. Tento příklad můžeme využít a trochu si pozměníme jeho funkci.
OnEvent(Enums.OnMoveStop, "MojeUdalost") OnEvent(Enums.OnFallStop, "MojeUdalost") function MojeUdalost(eventId, objectId, direction) ...
Tímto jsme docílili zaregistrování jedné funkce MojeUdalost pro více událostí. Jelikož události OnMoveStop a OnFallStop mají stejné parametry, můžeme je jednoduše použít.
EventId
Proměnná eventId slouží k identifikování události nebo k jejímu vypnutí a zapnutí. Na to slouží funkce DISABLE a ENABLE (popř. GLOBAL_DISABLE a GLOBAL_ENABLE). Za DISABLE se ve skutečnosti nahradí Disable(eventId). Z toho již můžeme pochopit, jak třeba vypnout událost z jiného místa, viz příklad:
ON_MOVE_BEGIN flounder OnMoveBeginFlounderId = eventId ... end ON_MOVE_BEGIN guppy if OnMoveBeginFlounderId then Disable(OnMoveBeginFlounderId) end end
Tento příklad zařídí, že pokud se pohne dříve Guppyová než Flounder, už se jeho událost nezavolá. Bohužel pro funkčnost je potřeba, aby se Flounder pohnul první, jinak se nenastaví proměnná OnMoveBeginFlounderId. ☺
Vlastní událost
Na závěr si vytvoříme jednoduše pomocí ON_TIMER vlastní „pseudoudálost“ OnTurn, která se zavolá při otočení živočicha.
do local lookdirs = {} local OnTurnEvents = {} ON_TIMER 0.01 if not __had_begin__ then return end for objectId = 0, Room():GetObjectsCount()-1, 1 do obj = Object(objectId) if not obj then break end if obj:IsCritter() then local crit = obj:AsCritter() local critid = crit:GetId() local olddir = lookdirs[critid] local newdir = crit:GetLookDir() lookdirs[critid] = newdir if olddir ~= newdir and olddir then for k,v in pairs(OnTurnEvents) do _G[v](critid, newdir) end end end end end function AddTurnEvent(funcname) table.insert(OnTurnEvents, funcname) end function RemoveTurnEvent(funcname) for k,v in pairs(OnTurnEvents) do if v == funcname then OnTurnEvents[k] = nil end end end end AddTurnEvent("TestTurn") function TestTurn(objectId, dir) if objectId ~= guppy then return end ... end