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