Войти на сайт Регистрация Лента форума Пользователи Правила сайта Поиск по форуму
Модератор форума: denis2000, FantomICW  
Модостроение. Создание и редактирование квестов
denis2000Дата: Пн, 10.10.2011, 21:25 | Сообщение # 1
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Создание и редактирование квестов

Создание новых квестов и редактирование существующих

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


Много интересного материала здесь (wiki), Lua_help.script, Help из SDK 0.7

Сборник модостроения ЗП v10.10.11 (автор: XOBAH): *.CHM, *.HTML
[cut noguest=Если у вас не открывается файл CHM]Если у вас не открывается файл:
1. Запустите [Пуск]=>[Выполнить] (либо хот-кей [WIN]+[R])
2. Введите команду (без кавычек) "regsvr32 %windir%\system32\hhctrl.ocx"
3. Если вылезло окно об успешном завершении вы все сделали правильно и можете перезагружать компьютер (а может и не надо)
Также: файлы МОГУТ не открываться если в пути к файлу есть: символы кириллицы, "_", "#"
Также: есть не стандартные программы-просмоторщики CHM файлов. Например: FBReader[/cut]

[cut=Где найти лог игры после вылета]Что такое LOG ошибки, и как мне его найти?
Это система отладки происходивших вылетов, которая подается игрой в форме текста, хотя не всегда.
Для того чтоб найти LOG необходимо зайти вот сюда:

В Win хр лог находится:

C:\Documents and Settings\All Users\Документы\S.T.A.L.K.E.R. - Зов Припяти\logs

Затем открываете первый файл в формате TXT, и в нем отбираете с низу 25 строчек. После кидаете эти 25 строчек в сообщение на форум.

В Win7 лог находится C:\Users\Public\Documents\S.T.A.L.K.E.R. - Зов Припяти\logs

Путь к папке с логом можно найти открыв файл fsgame.ltx который находится в корневой директории ЗП, за это отвечает строка:
...
$app_data_root$ = true | false| $fs_root$| users\
(тут мы указываем что папка пользователя, будет хранится рядом с Fsgame.ltx)
...
$logs$ = true| false| $app_data_root$| logs\
(а тут мы указываем что в папке пользователя, в подпапке Logs будут храниться наши логи)
...
[/cut][cut=Получение более подробной информации о вылете (ХОВАН)]
Открываем файл _g.script и ищем такую функцию: function abort(fmt, ...)
Там есть заккомментированная строчка "--error_log(reason)", ее и надо расскомментировать, должно получиться вот так:
Code
function abort(fmt, ...)
                       local reason = string.format(fmt, ...)
                       error_log(reason)
end

Вот для примера два одинаковых вылета, первый с функцией по умолчанию, второй - с поправленной функцией

Первый:
Code
Expression    : !m_error_code
Function      : raii_guard::~raii_guard
File          : D:\prog_repository\sources\trunk\xrServerEntities\script_storage.cpp
Line          : 748
Description   : ....a.l.k.e.r. - Зов Припяти\gamedata\scripts\_g.script:478: bad argument #2 to 'format' (string expected, got nil)

Второй:
Code
Expression    : 0
Function      : ErrorLog
File          : D:\prog_repository\sources\trunk\xrServerEntities\script_engine_script.cpp
Line          : 49
Description   : 'Attempt to read a non-existant string field 'path_walk' in section 'walker@mechanic'

[/cut]


Перед тем, как задать вопрос в этой теме, прочтите все предыдущие страницы,
статьи в wiki по ссылке из шапки и соседнюю тему "Курс молодого бойца",
возможно Ваш вопрос уже рассматривался.


Если произошел вылет - выкладываем лог! Вопрос ставим четко, не забываем указывать версию игры, установленные моды их версии, установленные фиксы модов и подробно ваши правки.
Помните чем подробнее вопрос, тем точнее ответ.


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
FantomICWДата: Пн, 07.10.2013, 21:21 | Сообщение # 151
Лидер «Свободы»
Свобода
Сообщений: 4438
Награды: 44
Репутация: [ 1340 ]

NIV, да, есть там некий апдейт таймера. Тебя должна интересовать, в таком случае, строчка
Код
sgm_timers.timers_main()

Скажем так, вероятно, чтобы не впихивать в апдейт bind_stalker.script все SGM-скрипты, Николай вынес их в отдельный файл - sgm_loader.script. Строчки из bind_stalker.script:
Код
--/ SGM in
          if mod_update() then
             sgm_loader.sigerous_mod_main()
          end
          --/ SGM out

А там уже через функцию sigerous_mod_main запускается функция SGM-апдейта.
Выходит, вызов апдейта таймера можно вызвать просто через bind_stalker.script. Логично?
А теперь к самому таймеру. Итак, вызывается функция timers_main из sgm_timers.script, там уже и timers_update. Если важен только армейский таймер, все сокращается:
[cut=Код]
Код
function timers_main()
     timers_update()   
end
function timers_update()   
     --//Таймер армейских часов//-->
     if ui_mod_elements.army_timer_active==true then
        ui_mod_elements.army_timer_value=string.format(math.floor(time_global()/1000))-ui_mod_elements.army_timer_deprive
     else
        if ui_mod_elements.army_timer_value>0 then
           ui_mod_elements.army_timer_value=0
        end
     end
end   
[/cut]
Как-то так. Вроде не сложно?





Сообщение отредактировал FantomICW - Пн, 07.10.2013, 21:22
 
NIVДата: Вт, 08.10.2013, 18:10 | Сообщение # 152
Полевой исследователь
Ученые сталкеры
Сообщений: 167
Награды: 4
Репутация: [ 180 ]

Я почти перенес армейский таймер. Там важно использовать еще и менеджер худа (sgm_huds.scripts)(в нем есть такие строки: [cut]
Код
function CHudManager:hud_utils()

if timer.army_timer_active==true then
local data_timer=timer.army_timer_value
add_hud("hud_timer_wnd",data_timer)
else
-- if check_seconds(2) then
release_hud("hud_timer_wnd")
--end
end

(закомментировал уже я)[/cut] Пишу "почти перенес", потому что в SGM многое сделано через флаги , а чтобы перенести их обработку, нужно переносить слишком много функций. Например [cut] в (sgm_huds.scripts) есть переменнаяlocal hud_elements_precond=precond_hud(1). А в _g.script :
Код
function precond_hud(type)
         if type==nil or type==1 then
           return (not db.actor:is_talking()) and object_alive(db.actor) and check_ui_worked(true) and dont_has_alife_info("inventory_wnd_opened") and dont_has_alife_info("sleep_active") and dont_has_alife_info("actor_in_sleep") and dont_has_alife_info("screenshot_mode")

- а это проверки на функциях SGM и инфо оттуда же.
[/cut] Пришлось в тестовых целях убрать эти проверки.

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

P.S. Только что понял - армейский таймер показывает реальное время, а не игровое! Используется time_global(). А мне надо игровое - как перевести?


Изменяем реальность S.T.A.L.K.E.R. CoP: "Цена Новых Исследований" / "New Investigations' Value"

Сообщение отредактировал NIV - Вт, 08.10.2013, 20:42
 
FantomICWДата: Вт, 08.10.2013, 18:52 | Сообщение # 153
Лидер «Свободы»
Свобода
Сообщений: 4438
Награды: 44
Репутация: [ 1340 ]

NIV, попробуй еще это (на АМК нашел):
Код
local iTimer
local last
function start_timer_minutes_test(seconds)  
     if last~= nil  then
         iTimer = time_global()+last  --/ взводим таймер на остаток времени last
     else  
         iTimer = time_global() + 7*1000 --/ взводим таймер например 7 сек.
     end  
end

function timer_n_minutes_test() --/ вызывается из ':update' сталкер-биндера
     if iTimer then
         last=iTimer-time_global() -- присваиваем переменной остаток времени до конца работы таймера
         if iTimer < time_global() then  
             iTimer = nil --/ выключаем таймер
             last=nil
             СКРИПТ.ФУНКЦИЯ--/ выполняем действие
         end
     end
end  

-- выводим  значение таймера в обратном отсчете  на худ
function hud_static()  --/ вызывается из ':update' сталкер-биндера
local hud = get_hud()
local st
     if iTimer then  
     st = hud:GetCustomStatic("hud_timer")
         if st==nil then  
             hud:AddCustomStatic("hud_timer", true)  
             st = hud:GetCustomStatic("hud_timer")
         end
         if last~=nil then
             local hours = math.floor(last/3600000)
             local minutes = math.floor(last/60000 - hours*60)
             local seconds = math.floor(last/1000 - hours*3600 - minutes*60)
             local text = string.format("%02d:%02d:%02d",hours,minutes,seconds) -- выводим время в формате 00:00:00
             --local text=string.format("%.f",last/1000)
             st:wnd():SetTextST(text)   
         end  
     else  
         if hud:GetCustomStatic("hud_timer")~=nil then  
             hud:RemoveCustomStatic("hud_timer")
         end
     end
end



 
NIVДата: Сб, 12.10.2013, 15:26 | Сообщение # 154
Полевой исследователь
Ученые сталкеры
Сообщений: 167
Награды: 4
Репутация: [ 180 ]

Возвращаясь к таймерам: Реализовал убывающий таймер на основе армейского из SGM. Отсчёт времени происходит на основе переменных:
Код
niv_quest_timer_start_value=string.format(math.floor(time_global()/1000))  
и
  niv_quest_timer_value=niv_quest_timer_limit_timer_value-(string.format(math.floor(time_global()/1000))-niv_quest_timer_start_value)*11

Таймер работает от реального времени. На 11 умножаем для того, чтобы подогнать это время под игровое. При загрузке сейва, использовании спальника или перехода на другую локацию, таймер продолжает отсчёт, здесь всё нормально.

Но потом возникает проблема с перемоткой времени: например, при переходе между локациями, таймер меняется только на то время, которое проходит по часам компьютера*11, а не на 4 часа, как сдвигается игровое время.

Попробовал вместо time_global() использовать game.time(). При этом получается такой эффект: если ничего не трогать, таймер идёт нормально, но при переходе на другую локацию, от таймера отнимается 4 часа (как и нужно), а когда загружается другая локация, таймер показывает отрицательное время, порядка -11 тыс часов. Либо при сохранении и последующей загрузке таймер также показывает такое отрицательное время.

Я полагаю, что в этом случае либо неправильно сохраняются переменные, либо у них неправильный формат? Если пробовать поменять функцию на game.get_game_time() - то сразу вылет (неправильное использование???)

Требуется помощь: либо как ввести перемотку времени при использовании time_global(), либо как правильно использовать game.time() - подскажите, пожалуйста!


Изменяем реальность S.T.A.L.K.E.R. CoP: "Цена Новых Исследований" / "New Investigations' Value"
 
denis2000Дата: Сб, 12.10.2013, 16:35 | Сообщение # 155
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

NIV, Перемотка или установка времени в игре происходит при помощи функций из xr_effects.script (set_game_time и forward_game_time), используйте их для корректировки своего таймера.

"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
NIVДата: Сб, 12.10.2013, 17:17 | Сообщение # 156
Полевой исследователь
Ученые сталкеры
Сообщений: 167
Награды: 4
Репутация: [ 180 ]

denis2000, да, forward_game_time используется в рестрикторе левел-чейнджера. Но она меняет только игровое время, а не time_global(). Или я что-то не допонял?

Изменяем реальность S.T.A.L.K.E.R. CoP: "Цена Новых Исследований" / "New Investigations' Value"

Сообщение отредактировал NIV - Сб, 12.10.2013, 17:18
 
denis2000Дата: Сб, 12.10.2013, 18:54 | Сообщение # 157
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

NIV,
Если ваш таймер считает реальное время, то не понятно это заявление:
Цитата NIV ()
таймер меняется только на то время, которое проходит по часам компьютера*11, а не на 4 часа, как сдвигается игровое время.

Если ваш таймер считает игровое время, то в моем посте написан ответ на ваш вопрос! Компенсируйте значение вашего таймера в соответствии с игровым временем, измененным указанными функциями.


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
NIVДата: Сб, 12.10.2013, 19:39 | Сообщение # 158
Полевой исследователь
Ученые сталкеры
Сообщений: 167
Награды: 4
Репутация: [ 180 ]

denis2000, когда в функции таймера используется time_global(), он считает реальное время (т.е. медленно). Чтобы компенсировать это, умножаем разность времени на 11, тогда время, отсчитываемое таймером, почти совпадает с игровым (то, которое показывают часы). Когда происходит переход на другую локацию, игровое время проматывается на 4 ч вперед функцией forward_game_time в спейс-рестрикторе, а таймер успевает уйти только на время, потраченное на загрузку игры (~15-20 минут игровых, 1-2 мин реальных). Вот эту разницу и надо как-то компенсировать.
Если же использовать в таймере функцию game.time() (игровое время), то при смене уровня таймер сначала реагирует на forward_game_time и время переводит, но после загрузки локации показывает сильно отрицательное время. Аналогично и при save/load (см. выше, #159). Так что, по большому счёту, мне не удалось добиться работоспособности таймера на игровом времени.

Добавлено (12.10.2013, 19:39)
---------------------------------------------

Цитата denis2000
нужно изменить окончательно и бесповоротно параметр time_global() или на худой конец game.time()?
Даже не знаю, не будешь же часы у компьютера переводить? Может, лучше из niv_quest_timer_limit_timer_value вычесть поправку?
Идеально было бы заставить работать таймер через game.time() или что-то наподобие. Не пойму, почему там не получается.


Изменяем реальность S.T.A.L.K.E.R. CoP: "Цена Новых Исследований" / "New Investigations' Value"

Сообщение отредактировал NIV - Сб, 12.10.2013, 19:16
 
denis2000Дата: Сб, 12.10.2013, 19:47 | Сообщение # 159
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Цитата NIV ()
Может, лучше из niv_quest_timer_limit_timer_value вычесть поправку?

Вот это я и хотел от вас услышать! Что-то типа такого:
Код
niv_quest_timer_limit_timer_value = niv_quest_timer_limit_timer_value - поправка вычисленная из аргументов функции forward_game_time

Вот так например рассчитывается разница в секундах реального времени на основе игрового времени:
Код
local diff_sec = math.ceil(game.get_game_time():diffSec(inited_time)/level.get_time_factor())

где game.get_game_time() - текущее время, inited_time - время начала отсчета, level.get_time_factor() - коэффициент ускорения игрового времени относительно реального (11), :diffSec - функция рассчитывающая разницу времени в секундах, math.ceil - округление до ближайшего большего целого.


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
NIVДата: Сб, 12.10.2013, 20:05 | Сообщение # 160
Полевой исследователь
Ученые сталкеры
Сообщений: 167
Награды: 4
Репутация: [ 180 ]

Ещё уточню - game.get_game_time() возвращает время в виде (Y, M, D, h, m и т.д.)? Может там можно делать арифметику типа time:set (Y, M, D, h + 4, m, s, ms)?

Да именно так - это матрица или массив временных параметров. И можно задать функцией :set(Y, M, D, h + delta, m, s, ms). denis2000


Изменяем реальность S.T.A.L.K.E.R. CoP: "Цена Новых Исследований" / "New Investigations' Value"

Сообщение отредактировал NIV - Сб, 12.10.2013, 20:07
 
LazurДата: Вс, 13.10.2013, 12:22 | Сообщение # 161
Новичок
Пользователи
Сообщений: 82
Награды: 3
Репутация: [ 96 ]

NIV, вбей в Яндекс "энциклопедия для ПДА в ЗП" и поищи на первой странице - я на одном сайте выкладывал в "свободное плавание"рабочую Энциклопедию в ПДА для ЗП. Единственное, что я "нашему брату" не вручил - выдача статей в ПДА при обыске трупов, например. Но полазив по сайту можно найти мои посты, как я это сделал...

На пыльных тропинках аномальных полей
Заспавнятся наши следы...
 
NIVДата: Вс, 13.10.2013, 12:38 | Сообщение # 162
Полевой исследователь
Ученые сталкеры
Сообщений: 167
Награды: 4
Репутация: [ 180 ]

[off]Вопрос с таймером решён! Основная проблема была в том, что пришлось писать менеджер сохранений. По-моему, это достойно урока в КМБ.[/off]

Добавлено (13.10.2013, 12:38)
---------------------------------------------
[off] Lazur, спасибо! Согласно твоему указанию, на АМК нашел что-то по этой теме.[/off]


Изменяем реальность S.T.A.L.K.E.R. CoP: "Цена Новых Исследований" / "New Investigations' Value"

Сообщение отредактировал NIV - Пн, 14.10.2013, 20:36
 
LazurДата: Вс, 13.10.2013, 14:13 | Сообщение # 163
Новичок
Пользователи
Сообщений: 82
Награды: 3
Репутация: [ 96 ]

NIV, да, кстати, в Bind_stalker нужно добавить в функции actor_binder:update(delta) строку:
gui_callbacks.on_info() --Вызов нашего "Ловчего поршней"
А не то, что написано в посте - там у меня опечатка.


На пыльных тропинках аномальных полей
Заспавнятся наши следы...
 
VenedictДата: Сб, 30.11.2013, 22:06 | Сообщение # 164
Гражданский
Пользователи
Сообщений: 19
Награды: 0
Репутация: [ 0 ]

Всем привет! Хочу сделать сюжетный мод, с созданием квестов вопросов нет... но не нашёл как можно нормально вырезать оригинальный сюжет из ЗП. И наводится другой вопрос - если вырезать сюжет и побочные задания, то что делать с квестовыми предметами, персонажами и т.д.? Удалять и редактировать диалоги и спавн? Может кто знает урок или статью как вырезать сюжет

▒▒▒彡✘a-✘a-✘a彡 ▒▒▒ ✓

Сообщение отредактировал Venedict - Сб, 30.11.2013, 22:09
 
FantomICWДата: Сб, 30.11.2013, 22:15 | Сообщение # 165
Лидер «Свободы»
Свобода
Сообщений: 4438
Награды: 44
Репутация: [ 1340 ]

Venedict, вот и вот.


 
Поиск: