1 (edited by Vorov2 2013-11-18 11:06:39)

Topic: Пример реализации фонаря

function tcall(f,s)
  if f == nil then
    return f;
  elseif type(f) == "function" then
    return tcall(f(s),s);
  else
    return f;
  end
end

flash = obj {
   _on          = false
  ,nam          = function(s)
                    return "Фонарь ("..s:statefun()..")";
                  end
  ,statefun     = function(s)
                    if s._on then
                      return "включён";
                    else
                      return "выключен";
                    end
                  end
  ,inv          = function(s)
                    s._on = not s._on;
                    return "Фонарь "..s:statefun()..".";
                  end
}

function flash_on()
  return have(flash) and flash._on;
end

function darkroom(tab)
  local dsc = tab.dsc;
  tab.dsc = function(s)
    if flash_on() then
      return tcall(dsc,s);
    else
      return "В комнате темно. Ничего не видно.";
    end
  end
  return room(tab);
end

function darkobj(tab)
  local dsc = tab.dsc;
  tab.dsc = function(s)
    if flash_on() then
      return tcall(dsc,s);
    else
      return tcall(s.darkdsc,s);
    end
  end
  return obj(tab);
end

Пример использования:

scene1 = darkroom {
   nam          = "Подвал"
  ,obj          = { "scene1_box" }
  ,dsc          = "Слабый луч фонаря едва освещает грязные стены."
}

scene1_box = darkobj {
   nam          = "Коробка"
  ,dsc          = "На полу лежит лежит фанерная {коробка}."
  ,act          = "Коробка пуста."
}

Т.е. пишите как обычно, просто с другими конструкторами - так, как будто свет всегда есть. Темнота разруливается автоматически. Если темно, то все объекты, созданные через darkobj, будут невидимы. Можно добавлять отдельное описание объектов для случая темноты:

scene1_box = darkobj {
   nam          = "Коробка"
  ,dsc          = "На полу лежит лежит фанерная {коробка}."
  ,darkdsc      = "Под моими ногами что-то лежит, но я никак не могу разобрать что."
  ,act          = "Коробка пуста."
}