Перейти к контенту

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

Железо: Intel Core i5 9400F / 16Gb DDR4 2400MHz / SSD NVMe M.2 Samsung 970 EVO Plus 256Gb / GF GTX 1050Ti 4Gb Ось: Win10x64

Ссылка на комментарий

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

New Level Changer 5.08: Раритеты

ReapeR build 3: Раритеты

 

Я на YouTube: Vincent Vega

Ссылка на комментарий

Еще один глючок нашёл: "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

Железо: Intel Core i5 9400F / 16Gb DDR4 2400MHz / SSD NVMe M.2 Samsung 970 EVO Plus 256Gb / GF GTX 1050Ti 4Gb Ось: Win10x64

Ссылка на комментарий

Теперь "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

New Level Changer 5.08: Раритеты

ReapeR build 3: Раритеты

 

Я на YouTube: Vincent Vega

Ссылка на комментарий

[пофиксил]

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

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

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

Intel Centrino Mobile (Dual-core) T2700 2,328 GHz, Intel GMA 945GM, 2x1024 MB DDR2-667, WD Scorpio 1200BEVS

Microsoft Windows 7 Professional N + Novell Linux 11.2 (OpenSUSE) Dual boot

S.T.A.L.K.E.R. SHOC 1.0004 + AMK 1.4.1 + NS3 + NLC3 + Arsenal + Arsenal beta +New weapons

 

Опытный американский дробовик XM1014 =O

Хозяйке на заметку: Не спешите выбрасывать чеку от использованной гранаты Ф-1 или РГД-5 - с её помощью можно легко и удобно прикрепить игрушечного пингвинчика к своему рюкзаку. © not me

Ссылка на комментарий

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

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

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

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

в такую

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

 

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

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

 

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

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

Железо: Intel Core i5 9400F / 16Gb DDR4 2400MHz / SSD NVMe M.2 Samsung 970 EVO Plus 256Gb / GF GTX 1050Ti 4Gb Ось: Win10x64

Ссылка на комментарий

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

Ссылка на комментарий

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

[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 и для Народной Солянки. Ссылка на чистую игру работоспособна, сам только что проверил.
Ссылка на комментарий

Вот залил на яндекс.

Изменено пользователем HellRatz
Добавлено  HellRatz,

Предупреждение по пункту 2.5 правил форума.

Устно.

Про заглавные и знаки препинания не забываем.

Ссылка на комментарий

Переделал  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 пользователей

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