Autosave - Страница 2 - Мастерская ТЧ - AMK Team
Перейти к контенту

Autosave


utak3r

Рекомендуемые сообщения

Если вы не скриптер, то лучше и не лезть ))

amk.g_start_timer("<Имя таймера>",<дни>,<часы>,<минуты>,<передаваемые данные>)

В функцию amk.__do_timer_action вставить:

if select_string=="<Имя таймера>" then
    --Тут вставляем функцию, которая должна вызываться по окончании таймера. 
    --Функции передаем 'params_string', который в свою очередь равен <передаваемым данным>
end

 

 

DimOriN, у меня немного другой вариант :)

Отвечаю на вопрос V92

...можешь сделать чтобы сохранка делалась с этой самой задержкой?

В

amk.script в конце таблички local func_by_string = {} дописываем:

    func_by_string["autosave"] = function (params_string)
        u3_utils.savegame(params_string)
    end

И в news_manager.script вот этот кусок

    if type == "new" or type == "update" then
        u3_utils.savegame(news_text)        
    end
    if type == "complete" then
        u3_utils.savegame(news_text.." - completed")        
    end

меняем на

    if type == "new" or type == "update" then
        amk.start_timer("autosave", 3, news_text)
    end
    if type == "complete" then
        amk.start_timer("autosave", 3, news_text.." - completed")
    end

Теперь сейв делается с задержкой в 3 сек (в параметрах запуска таймера можно вместо 3 сек поставить сколько нужно, если у кого не успевает срабатывать спавн за 3 сек).

 

 

ЗЫ: То, что я привел - это для текущей версии Солянки (таблица func_by_string = {} была введена Сапсаном в Соль от 22.01, кажется...)

Т.е. если таковой у вас не имеется - делать как предложил DimOriN :)

Тут нужна короткая задержка - всего несколько секунд: видимо, задавать нужно десятичной дробью в параметре <минуты>

 

И еще небольшое дополнение. Я так понимаю, что имя сейва не должно превышать 64 символа.

Поэтому в скрипте u3_utils.script ф-цию savegame(save_name)

(см. постом ниже, там еще правка по некорректным символам с имени сейва)

 

Пока до конца не понял, в чем проблема, но при попытках автосохраниться в некоторых случаях в логе появляется строчка "Invalid filename", после чего неминуемо следует либо вылет, либо зависание. Сейв с именем ровно в 64 символа у меня есть, сделанный этим самым автосейвом - значит, проблема не здесь. А вот где - х.з.

 

The ReapeR, правку по задержке ставить обязательно, иначе часть сейвов будет кривыми. А вот с именами файлов - непонятно, что не нравится в имени.

Может, отладку какую поставить, чтобы видеть точно, что же там было за имя движку не нравится, что ли...

Изменено пользователем Shadowman

У меня иногда пишет в консоли "Invalid filename" и не сохраняет. НО и не вылетает и не виснет...Я не пользовался твоей правкой....Попробую может :)

Еще один глючок нашёл: "Invalid filename" в лог выдаётся если то сообщение, которое используется для имени файла, содержит кавычки (Например: Поговорить с поваром на базе "Свободы").

Естественно, перед попыткой сохранения с таким именем нужно удалять предварительно кавычки скриптом. Чуть позже выложу правку.

 

в скрипте u3_utils.script ф-цию savegame(save_name)

function savegame(save_name)
    if save_name == nil then
        printf("Trying to save a game without any name!")
        return false
    end
    if isGameOn() then
        local save_param = user_name().."-"..save_name
        save_param = string.gsub(save_param,"[><|?*/\\:\"%b/n]",".")
        save_param = string.gsub(save_param,"[%%][c][\[][%a%d%p%s]*[\]]","")
        save_param = string.gsub(save_param,"Задание выполнено","Выполнено ")
        if string.len(save_param)>64 then
            save_param = string.sub(save_param,1,64)
        end
        get_console():execute("save "..save_param)
    end
end

 

 

sapsan-у отдельное спасибо за помощь по регэкспам :good:

 

The ReapeR, :)

Символы "__" в имени сейва означают, что раньше сейв этот не сохранялся вовсе и выдавал матюк "Invalid filename" из-за недопустимого имени файла, а теперь - сохраняется, т.к. я недопустимые символы заменил на подчеркивание. Видимо, сообщение с цветовыми тэгами - вот и пишет, как есть (мы ведь не проверяем ничего кроме > < | ? * / \ : ").

А я еще удивлялся, чего же не сохраняет, когда задание выполнено, хотя в коде вроде видно, что должен. Теперь понятно.

Плохо, что цифры банить нельзя. Придется шаблон какой-то еще выдумывать для таких тэгов.

Тут плохо еще то, что собственно какое задание-то выполнено и не видно из-за того, что длина строки обрезана (даже если и не обрезать, все одно в окне с сейвами не видно будет).

 

Код выше обновил, пробуйте.

Теперь сохранение правильно делается и после заданий, цветовой код отрезал камрад sapsan, высказав своё "фэ" такой фразой: string.gsub(save_param,"[%%][c][\[][%a%d%p%s]*[\]]","") :rolleyes:

 

The ReapeR, последний вариант точно рабочий!

alexey-Выполнено ...Добыть часть тела монстра. - completed

(начальная строка примерно такая:

%c[255,160,160,160]Задание выполнено:/n%c[default]Добыть часть тела монстра)

Изменено пользователем Shadowman

Теперь "invalid filename" не появляется, но появляется другое..

Названия некоторых сейвов у меня в папке после игры на Кордоне:

Александр - %c[255,160,160,160]Задание выполнено__n%c[default]До.sav
Александр - Найти артефакт _Медуза_.sav
Александр - %c[255,160,160,160]Задание выполнено__n%c[default]Пр.sav

Такие глюки в основном в обычных, несюжетных кветах. Не неприятно все равно <_<

 

Сейчас-ка попробуем...

 

Блин

Александр - Уничтожить логово кабанов.sav
Александр - Вернуться за наградой..sav
Александр - %c[255,160,160,160]Вып. __n%c[default]Уничтожение ла.sav

Изменено пользователем The ReapeR

[пофиксил]

shadowman, можно поражаться вашей оперативности.

Да, очень схоже с форматами в Си.

Изменено пользователем AK-103

AK-103, http://www.wowwiki.com/Pattern_matching

Шаблоны в Луа - по ним и сделано и работает.

приведенный выше код превращает строку

%c[255,160,160,160]Задание выполнено:/n%c[default]Добыть часть тела монстра

в такую

<Username>-Выполнено ...Добыть часть тела монстра

 

Кстати, скорей всего ограничение длины строки можно и убрать: другое дело, что в игре окошко с сейвами узковато, чтоб показать даже 40 символов...

Хотя, и это, наверное, поправимо.

 

AK-103, просто было настроение ;)

Изменено пользователем Shadowman

Была схожая идея реализовать квиксейв в таком виде, чтобы при нажатии "горячей клавиши" квика выполнялось полноценное сохранение с именем <локация_дата|время>. Каждый "квик" в этом случае был бы с уникальным именем сортируемым по порядку сохранения. Может автор этого мода сможет реализовать такую систему. Ибо квиком все равно пользоваться (в виду порчи сейвов) желающих мало.

Здравствуйте! Решил и я поделиться своими экспериментами с автосейвом. Вроде удалось-таки добиться того, чтобы автосейв стал полностью безглючным. Другими словами, все сейвы рабочие и в них сохраняется ВСЯ информация (все нужные поршни, задания, переходы, спавн и прочее).

[spoiler=Как-то так: :) ]Выкинуто сохранение при обновлении задания. Сейвов и так полно - хватит на все случаи. Сейв делается при взятии и сдаче задания. Название файла состоит из заголовка задания, не из первого подзадания, как в оригинале. news_manager.script:

    local news_text_save = game.translate_string(task_title)
    if type == "new" then
        amk.start_timer("autosave", 3, news_text_save)
    elseif type == "complete" then
        amk.start_timer("autosave", 3, news_text_save.." - завершено")
    end

Автосейв перед переходом на локу сделать пока не удается, но похоже, это и не нужно - достаточно того, что есть. Сделан автосейв при использовании ручных телепортов. spawn_level_changer.script:

в описание телепортов добавляем строку autosave с указанием локации, на которую телепортируемся (на примере телепорта Стрелка):

    ["arhara_obman"] = {
        keep = true,
        sjedobniy = true,
        pay = 20000,
        autosave = "l07_military",
        goto_func = {
            "exit_as2"
        }

далее, в функцию teleport_start:

function teleport_start(obj_sect, obj_id, sjeli)
    local sim = alife()
    local actor = db.actor

        -- autosave
        local to_level = teleports[obj_sect].autosave
        if to_level and to_level ~= level.name() then
            u3_utils.savegame_lc(to_level)
        end

........ остальной код

и спавн телепорта выносим в еще один таймер, чтобы сейв успел создаться:

        -- jumpTo(teleports[obj_sect].goto_func[math.random(#(teleports[obj_sect].goto_func))])
        amk.start_timer("teleport_jumpto", 0.2, teleports[obj_sect].goto_func[math.random(#(teleports[obj_sect].goto_func))])

в u3_utils.script пишем функцию:

function savegame_lc(to_level)
    savegame("Телепорт "..game.translate_string(level.name()).." - "..game.translate_string(to_level)..". День "..amk.game_days())
end

которая создает сейв с указанием, откуда и куда телепортировались. Например, если использовать телепорт Стрелка сразу по взятии, в Саркофаге, то будет создан сейв с именем "Телепорт Саркофаг - Армейские Склады. День 23" День - это игровой день нахождения ГГ в зоне.

 

И, наконец, в amk.script пишем наши таймеры:

    func_by_string["teleport_jumpto"] = function (params_string)
        spawn_level_changer.jumpTo(params_string)
    end
    func_by_string["autosave"] = function (params_string)
        if u3_utils.can_save() then
            u3_utils.savegame(params_string)
        else
            start_timer("autosave", 3, params_string)
        end
    end

Обратите внимание, что во второй функции таймер вызывает сам себя. Это нужно, чтобы обойти один редкий, но неприятный момент. В некоторых диалогах поршни и спавн идут после разных фраз. Достоверно известное место в НС - первый диалог с Клыком в пещере на НЗ. Там поршень на задание выдается после последней фразы клыка, когда он посылает гг в варлаб, а переходы спавнятся после ответа гг на эту фразу Клыка. и возникает рандомная пауза между выдачей задания (стартом таймера на автосейв) и спавном переходов. И если автосейв произойдет до того, как гг ответит на фразу Клыка, то, как вы понимаете, переходы еще не заспавнятся и в сейве их не будет. Чтобы обойти эту проблему - автосейв не выполнится, пока диалог не будет закончен. Для этого стоит вызов функции can_save, которая проверяет, можно ли сохраняться. Если нет - то сейв передвигается еще на 3 секунды. И так до тех пор, пока гг не закончит разговор.

В u3_utils.script функция can_save имеет следующий вид:

function can_save() -- не сохраняем во время открытых окон, когда нельзя сделать квиксейв
    return not (db.actor:is_talking() or has_alife_info("ui_car_body") or has_alife_info("ui_inventory") or has_alife_info("ui_pda"))
end

тут на всякий случай отсечены все возможные открытые окна: диалог/торговля/инвентарь/нычка/пда. т.е. те места, где и квиксейв не сделаешь. В этом случае получается гарантия, что в сейв попадет весь нужный спавн и вся нужная инфа. Получается полная эмуляция, как будго гг закончил диалог и нажал квиксейв. Единственный момент здесь - это когда игрок за один диалог берет/сдает несколько заданий. тогда в очередь становятся несколько автосейвов, и по окончании диалога они будут все одинаковые, т.е. содержать все выданные за время диалога поршни и спавн. Это, конечно, лишнее, но лучше, пусть будет лишнее, чем будет чего-то не хватать))

Вот вроде и все. По аналогии можно сделать сейв преед/после любого события, в частности, в ОП-2 я сделал сейв после выброса, перед сном и ЧУ.

 

ЗЫ: да, еще один момент: функция формирования списка сейвов в окне загрузки почему-то не любит запятую в имени файла. Она вполне допустима в виндоус, а вот в Сталкере - нет) причем сейв создается с запятой в названии, а вот в списке он обрабатывается криво, причем через раз) Я не стал с этим разбираться, просто нужно выкинуть запятую из имени сейва, и все. Поэтому команды отсева левых символов в u3_utils должны выглядеть так:

        save_param = string.gsub(save_param,"[><|?*/\\,:\"%b/n]","")
        save_param = string.gsub(save_param,"[%%][c][\[][%a%d%p%s]*[\]]","")

Вроде, ничего не забыл)

Надежных вам автосейвов!

  • Полезно 1
S.T.A.L.K.E.R-DOLG, а первый пост внимательно прочитать религия не позволяет? Там ссылки для чистой ТЧ 1.0004 и для Народной Солянки. Ссылка на чистую игру работоспособна, сам только что проверил.
6 часов назад, Mr. PelMen сказал:

на солянку 2016 можно ставить?

Если адаптируешь.

Переделал  u3_utils.script . Адаптировал для OGSR.

-----------------------------------------------------------------------------
-- u3_utils.script
-- Адаптировал к OGSR
-- Добрица О.П. (DiegoLidabo)
-- 
-- Last update: 13:54 25.06.2020
-----------------------------------------------------------------------------

--
-- Sprawdzenie, czy jest gra i czy aktor jest їywy
--
function isGameOn()
	if level.present() and db.actor ~= nil and db.actor:alive() then
		return true
	end
	return false
end

--
-- Формирование Имени Файла и запись
--
function savegame(save_name)
    if save_name == nil then
        return false
    end
    if isGameOn() then
        local save_param = user_name().."-"..save_name
        save_param = string.gsub(save_param,"\\n",".")
        save_param = string.gsub(save_param,"[><|?*/\\:\"%b]",".")
        --get_console():execute("load ~~~ "..save_param)
		--save_param = string.gsub(save_param,"[%%][c]","")
        save_param = string.gsub(save_param,"[%%][c][%[][%a%d%p%s]*[%]]","")
        --get_console():execute("load ~~~ "..save_param)
        --save_param = string.gsub(save_param,"Задание выполнено","Выполнено")
        save_param = string.gsub(save_param,"%.+",".")

        if string.len(save_param)>64 then
            save_param = string.sub(save_param,1,64)
        end
        get_console():execute("save "..save_param)
    end
end



 

  • Нравится 1
  • Полезно 2

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

    • Ни один зарегистрированный пользователь не просматривает эту страницу.
×
×
  • Создать...