Topic: сохранение игр когда room не в глобальном пространстве имен

Есть вот такой вот код (который я уже раньше постил):

function npc(name, data)
        local cp = charstats[name]
        local r = obj {
                nam = cp.name,
                _data = cp,
                _dlg = cp.dlg,
                dsc = function(s)
                        local kdsc
                        local ukdsc

                        if s._data.knowndsc then
                                kdsc = s._data.knowndsc
                        else
                                kdsc = "Я вижу {"..s.nam.."}"
                        end
                        if s._data.unknowndsc then
                                ukdsc = s._data.unknowndsc
                        else
                                if s._data.class == "female" then
                                        ukdsc = "Я вижу незнакомую {девушку}."
                                elseif  s._data.class == "male" then
                                        ukdsc = "Я вижу {незнакомца}."
                                end
                        end


                        if s._data.known then
                                ldsc = kdsc
                        else
                                ldsc = ukdsc
                        end
                        p(ldsc)
                        if s._data.firsttime then
                                p(s._data.firsttext)
                                s._data.firsttime = false
                        end
                end,
                act = function(s)
                        if s._data.acttext then
                                p(s._data.acttext)
                        end
                        walkin(s._dlg)
                end,
                life = function(s)
                        if player_moved() and where(s) ~= s._data.where then
                                move(s, s._data.where, where(s))
                        end
                end,
        }
        local k, v
        for k, v in pairs(data) do
                r[k] = v
        end
        return r
end
...
global {
        charstats = {
                alice = {
                        name = "Алиса",
                        strength = 100,
                        health = 100,
                        class = "female",
                        known = false,
                        knowndsc = [[Я вижу {Алису}, сидящую в кресле]],
                        unknowndsc = [[Я вижу худую {девушку} с каштановыми волосами,
                                     сидящую в кресле]],
                        firsttime = true,
                        firsttext = [[Ее худоба, ее взъерошенные волосы, темные, почти черные глаза, в этом адском освещении
                        создавали ощущение, что передо мной не девушка, изможденная, но за невзгодами не утратившая еще
                        своей природной красоты, а существо с другой планеты, или чудовище, сошедшее со страниц каких-нибудь
                        страшных сказок]],
                        where = 'dorm1_ent_chairs',
                        dlg = dlg {
                                nam = "Алиса",
                                hideinv = true,
                                phr = {
                                        {
                                                "Привет!", "Здравствуй.", [[pon('hi');]],
                                        },
                                        {
                                                 tag = 'hi', false, "Меня зовут Яков. А как тебя зовут?", "Алиса",
                                                [[charstats.alice.known = true;pon('intro');]],
                                        },
                                        {
                                                 tag = 'intro', false, always = true, "Я здесь новенький. Может расскажешь мне что здесь и как?",
                                                "Ты разберешься. Повзрослеешь и поумнеешь. Если выживешь.", [[pon('survive');]],
                                        },
...
                                }
                        },
                },
...
        }
}
...
dorm1_ent_chairs = room {
        nam = [[Стол и кресла]],
        dsc = [[Стол и кресла представляют с собой образчик старой мебели, классифицируемой как рухлядь.
                Цвет обивки стульев навозможно разобрать, а поверхность стола выщерблена, как будто
                на нем рубили дрова. Но видно, что мебель еще прочная, и используется -- на стульях
                видны следы ремонта.]],
        way = {
                'dorm1_enterance',
        },
}
place(alice1, alice1._data.where)

Оно работает, но состояние не сохраняется.
так можно вообще делять? Что я деляю не так?

Re: сохранение игр когда room не в глобальном пространстве имен

код не смотрел, но любые объекты могут быть созданы:
или статически в глоб пространстве a = room …

или через new

во всех остальных случаях нужно писать свои функции сохранения и/или восстановления

Re: сохранение игр когда room не в глобальном пространстве имен

Тааак, понял.
А как мне сделать сохранение комнаты (которая диалог) которая создается при создании объекта?
Вро де ж должна быть возможность дернуть стандартные функции сохранения правильно в этом случае?

Re: сохранение игр когда room не в глобальном пространстве имен

А, я так понял не работает deref, и если я сделал walk/walkin в такой диалог, я получаю Error: /usr/share/games/instead/stead//stead.lua:1483: attempt to concatenate a table value

stead.player_save = function(self, name, h)
        h:write(tostring(name)..".where = '"..stead.deref(self.where).."';\n");
        stead.savemembers(h, self, name, false);
end

Re: сохранение игр когда room не в глобальном пространстве имен

я ж выше написал smile см new.
единственный штатный способ динамически создавать объекты (комната - тоже объект)

Re: сохранение игр когда room не в глобальном пространстве имен

Дык оно вроде как требует позвать конструктор, который должен быть в глобальном неймспейсе. Не хотеть...

Re: сохранение игр когда room не в глобальном пространстве имен

функцию в глобальном контексте то чего не хотеть? :вон npc уже создана. чем от конструктора отличается?

Re: сохранение игр когда room не в глобальном пространстве имен

можно попробовать  вот что.
в глоб контексте просто определить
axxx = charstats.alice.dlg;
после всего что выше
если сработает можно будет думать дальше над автоматическим энумератором твоего неймспейса

Re: сохранение игр когда room не в глобальном пространстве имен

Дык не хочется еще одну неотделимую, но отдельную сущность плодить - необъектненько как-то... да и много их будет...

Re: сохранение игр когда room не в глобальном пространстве имен

в общем я подумаю еще - пока не было времени. может найду элегантный способ. может достаточно будет простозапустить на старте энумератор на твое пространство

Re: сохранение игр когда room не в глобальном пространстве имен

Не имею возможности проверить. Но если просто написать в dlg

dlg = {
    key_name = 'charstats.alice.dlg';
...

Будет работать?
Если да - то сделать энумератор будет несложно.

Re: сохранение игр когда room не в глобальном пространстве имен

Да, с выставлением в глобальный спейс работает, если передать параметром ссылку и делать walkin в неё.

Re: сохранение игр когда room не в глобальном пространстве имен

А с key_name?
Если поможет - можно написать элегантный модуль namespace

хотя надежней все же написать энумератор с пробросом в глоб пространство. могу набросать, но не сегодня.

14 (edited by slapin 2013-11-12 23:35:09)

Re: сохранение игр когда room не в глобальном пространстве имен

так, я не доконца понял что делать...
Короче, чтобы не бороться с автосейвом, который принимал
charstats.*.dlg за комнату (и ругался, что не может ее сохранить, даже если там не было dlg { а было просто {
я привел код к такому виду:

function npc(name, data, ddlg)
        local cp = charstats[name]
        local r = obj {
                nam = cp.name,
                _data = {},
                _dlg = dlg(cp.dlg),
                ddlg = ddlg,

                dsc = function(s)
                        local kdsc
                        local ukdsc

                        if s._data.knowndsc then
                                kdsc = s._data.knowndsc
                        else
                                kdsc = "Я вижу {"..s.nam.."}"
                        end
                        if s._data.unknowndsc then
                                ukdsc = s._data.unknowndsc
                        else
                                if s._data.class == "female" then
                                        ukdsc = "Я вижу незнакомую {девушку}."
                                elseif  s._data.class == "male" then
                                        ukdsc = "Я вижу {незнакомца}."
                                end
                        end


                        if s._data.known then
                                ldsc = kdsc
                        else
                                ldsc = ukdsc
                        end
                        p(ldsc)
                        if s._data.firsttime then
                                p(s._data.firsttext)
                                s._data.firsttime = false
                        end
                end,
                act = function(s)
                        if s._data.acttext then
                                p(s._data.acttext)
                        end
                        walkin(stead.deref(s.ddlg))
                end,
                life = function(s)
                        if player_moved() and where(s) ~= s._data.where then
                                move(s, s._data.where, where(s))
                        end
                end,
                save = function(s, name, h, need)
                        if need then
                                h:write(stead.string.format("%s = npc(%s, {})\n",
                                        name, stead.tostring(s.nam)))
                        end
                        stead.savemembers(h, s, name, false)
                end

        }
        local k, v
        r._dlg.save = function(s, name, h, need)
                local dsc;
                if need then
                        h:write(stead.string.format("%s = dlg {charstats."..s.chnam..".dlg}\n",
                                name))
                end
                stead.savemembers(h, s, name, need);
        end
        r._dlg.chnam = name
        for k, v in pairs(cp) do
                r._data[k] = v
        end
        r._data.dlg = nil
        for k, v in pairs(data) do
                r[k] = v
        end
        return r
end

Использование:

global {
        charstats = {
                alice = {
                        name = "Алиса",
                        strength = 100,
                        health = 100,
                        class = "female",
                        known = false,
                        knowndsc = [[Я вижу {Алису}, сидящую в кресле]],
                        unknowndsc = [[Я вижу худую {девушку} с каштановыми волосами,
                                     сидящую в кресле]],
                        firsttime = true,
                        firsttext = [[Ее худоба, ее взъерошенные волосы, темные, почти черные глаза, в этом адском освещении
                        создавали ощущение, что передо мной не девушка, изможденная, но за невзгодами не утратившая еще
                        своей природной красоты, а существо с другой планеты, или чудовище, сошедшее со страниц каких-нибудь
                        страшных сказок]],
                        where = 'dorm1_ent_chairs',
...
                        dlg = {
                                nam = "Алиса",
                                phr = {
                                        {
                                                "Привет!", "Здравствуй.", [[pon('hi');]],
                                        },
                                        {
                                                 tag = 'hi', false, "Меня зовут Яков. А как тебя зовут?", "Алиса",
                                                [[charstats.alice.known = true;pon('intro');]],
                                        },
...
                                                Конечно, если хочешь проснуться утром.]],
                                        },
                                }
                        },
                },
                harry = {
                        name = "Гарри",
                        strength = 100,
                        health = 100,
                        class = "male",
                        known = false,
                        knowndsc = [[Я вижу охранника {Гарри}.]],
...
                        where = 'lobby',
                        dlg = {
                                nam = "Гарри",
                                phr = {
                                        { "Здравствуйте.", [[Добро пожаловать,
                                        приятель. Представься, мне нужно
                                        сделать запись.]],[[pon("intro");]]},
...
                                },
                        }
                },
...
}
...
harry = npc("harry", {}, 'harry_dlg')
harry_dlg = harry._dlg
alice1 = npc("alice", {}, 'alice_dlg')
alice_dlg = alice1._dlg
...
lobby = room {
        forcedsc = true,
        nam = "Холл",
        dsc = [[Огромный, плохо освещенный зал, обставленный старой
                мебелью.]],
        way = {
                'ladder',
                'elevator',
                'corridor',
        },
}
...
dorm1_ent_chairs = room {
        nam = [[Стол и кресла]],
        dsc = [[Стол и кресла представляют с собой образчик старой мебели, классифицируемой как рухлядь.
                Цвет обивки стульев навозможно разобрать, а поверхность стола выщерблена, как будто 
                на нем рубили дрова. Но видно, что мебель еще прочная, и используется -- на стульях
                видны следы ремонта.]],
        way = {
                'dorm1_enterance',
        },
}

Re: сохранение игр когда room не в глобальном пространстве имен

key_name - это куда засунуть - при вызове dlg?

Re: сохранение игр когда room не в глобальном пространстве имен

так, осознал что такое key_name, пробую...

Re: сохранение игр когда room не в глобальном пространстве имен

короче самое простое наверное сделать модуль namespace, который будет проходить своих членов и пробрасовать в глоб пространство с  именами вида имяnamespace_blablabla, что сделает и автора и инстед счастливыми.

делать?
с key_name менее надежно

Re: сохранение игр когда room не в глобальном пространстве имен

Да, c key_name все работает.

Re: сохранение игр когда room не в глобальном пространстве имен

а чем плох key_name?
Хотя наверное так правильнее.
Сейчас использование такое (ссылку ddlg убрал)

harry = npc("harry", {})
harry._dlg.key_name = 'harry._dlg'
alice1 = npc("alice", {})
alice1._dlg.key_name = 'alice1._dlg'

вот если бы эти вторые строчки сами получались...
А нельзя такие объекты таки в свой собственный неймспейс увести,
чтобы не мешались? Это если модуль писать?

Re: сохранение игр когда room не в глобальном пространстве имен

Короче, встречайте новый модуль. Если понравится - выложу его на вики:
http://sourceforge.net/p/instead/code/H … format=raw

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

instead_version "1.9.1"

require "namespace"

ob = namespace {
    ob2 = namespace {
        var { gg = false };
        apple = obj {
            var { x = false };
            _xx = false;
            nam = 'яблоко';
            dsc = [[На полу лежит {яблоко}.]];
            tak = [[Оно!!!]];
        }
    }
}
main = room {
    nam = 'a';
    obj = { 'ob.ob2.apple' };
}

Т.е. по сути - это просто нэймспейсы, которые позволяют оформлять код более структурно.
Внимание - в namespace использование global означает, что переменная выходит из namespace. используйте var.

global { namespace или var { namespace  использовать нельзя
обрамляйте в var и global только объекты сохранения, а не все подряд

Re: сохранение игр когда room не в глобальном пространстве имен

а room'ы и dlg можно в неймспейс?

Буду с ним играться.

Re: сохранение игр когда room не в глобальном пространстве имен

А, еще было бы неплохо иметь какой-нибудь this или self для namespace...
чтобы правило инкапсуляции до конца работало...

Re: сохранение игр когда room не в глобальном пространстве имен

dlg/room те же объекты - можно

про this, могу дать всем объектам в namespace свойство какое то
типа ns
if s.ns... что то там?

Re: сохранение игр когда room не в глобальном пространстве имен

ну просто если допустим так:

library = namespace {
      function dsc_const(s)
...
      end
      table = obj {
             dsc = deref(this).dsc_const
...
      }
      mirror = obj {
...
      }
      room_normal = room {
...
          obj = {
               this..'.table',
               this..'.mirror',
          },
      }
      room_twisted = room {
...
          obj = {
               this..'.table',
               this..'.mirror',
          },
      }
}

ну то есть чтобы использовать как референс.
Это полезно, например, в функциях-фабриках ("конструкторах"), чего у меня будет много.
Ну вот какая-то конструкция надобна... по минимуму, чтобы имена объектов строить, по максимуму - чтобы даже
к ним иметь возможность обратиться, как вверху заполняется .dsc.
Вроде кто-то делал полную объектную систему для lua с this/self'ами, мож там есть что вытянуть можно...

Re: сохранение игр когда room не в глобальном пространстве имен

к сожалению в таком случае ничего кроме как:

this = 'library'

library = namespace {
      function dsc_const(s)
...
      end
      table = obj {
             dsc = stead.ref(this).dsc_const
...
      }
      mirror = obj {
...
      }
      room_normal = room {
...
          obj = {
               this..'.table',
               this..'.mirror',
          },
      }
      room_twisted = room {
...
          obj = {
               this..'.table',
               this..'.mirror',
          },
      }
}

предложить не могу

обновил модуль немного