Войти на сайт Регистрация Лента форума Пользователи Правила сайта Поиск по форуму
Модератор форума: 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 по ссылке из шапки и соседнюю тему "Курс молодого бойца",
возможно Ваш вопрос уже рассматривался.


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


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
sergej5500Дата: Сб, 12.05.2012, 23:27 | Сообщение # 46
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Спасибо denis2000 за подсказки. После того, как вернул в диалог строку
sgm_dialogs.esc_rasvet_001_quests_1, квест заработал.

Добавлено (12.05.2012, 23:27)
---------------------------------------------
Добрый Вечер!
Хочу задать вопрос по квесту Тесака на поиск еды. Многими игроками отмечалось, что игра после взятия этого квеста и до его сдачи притормаживает. Я делал свой квест на основе квеста Тесака и тоже заметил эту особенность. Каждые 3-4 секунды игра замирает на доли секунды, потом продолжается. Как часто по этому скрипту проверяется инвентарь главного героя? Можно ли подправить его как нибудь, чтобы он меньше нагружал систему?
[cut=Скрипт квеста]function esc_rasvet_astronom_artefact_quests()
task_manager.get_task_manager():give_task("esc_rasvet_astronom_artefact_quests")
end
function esc_rasvet_astronom_artefact_quests_actor(first_speaker, second_speaker)
local item_sections = {
[1] = "af_baloon",
[2] = "af_gravi",
[3] = "af_ice",
[4] = "af_glass",
[5] = "af_fuzz_kolobok",
[6] = "af_gold_fish",
[7] = "af_fire"

}
local needed = 12
local count = 0
local item_section

local function calc(temp, item)
if item:section() == item_section then
count = count + 1
end
end

for k,v in pairs(item_sections) do
item_section = v
get_story_object("actor"):iterate_inventory(calc, actor)
-- printf("?esc_rasvet_astronom_artefact_quests_actor? : section [%s] count [%s]", tostring(v), tostring(count))
end

return count >= needed
end
function esc_rasvet_astronom_artefact_quests_otdat(first_speaker, second_speaker)
local npc = dialogs.who_is_npc(first_speaker, second_speaker)
local actor = dialogs.who_is_actor(first_speaker, second_speaker)
local i = 12
local j = 0
local section
local item_sections = {
[1] = "af_baloon",
[2] = "af_gravi",
[3] = "af_ice",
[4] = "af_glass",
[5] = "af_fuzz_kolobok",
[6] = "af_gold_fish",
[7] = "af_fire"
}

local function transfer_object_item(temp, item)
if (item:section() == section and i ~= 0) then
actor:transfer_item(item, npc)
i = i - 1
end
end

for k,v in pairs(item_sections) do
section = v
j = i
actor:iterate_inventory(transfer_object_item, nil)
if ((j - i) ~= 0) then
news_manager.relocate_item(actor, "out", section, j - i)
end
-- printf("?esc_rasvet_astronom_artefact_quests_otdat? : section [%s] lasts [%s] from 12", tostring(v), tostring(i))
end
end
function esc_rasvet_astronom_artefact_quests_nagrada_actor(first_speaker, second_speaker)
dialogs.relocate_money_to_actor(first_speaker, second_speaker, 50000)
end[/cut] Заранее благодарен за советы.
 
denis2000Дата: Вс, 13.05.2012, 11:34 | Сообщение # 47
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

sergej5500, Есть два пути оптимизации данного квеста.
[cut]1. Оптимизация функции проверки и подсчета предметов
2. Оптимизация вызова функции проверки и подсчета.
Возможно применение обоих вариантов.
Для первого варианта, посмотри код у тебя для каждого артефакта будет вызывать итерация инвентаря (сам по себе не быстрый процесс), то есть семь раз! Это крайне не рационально, нужно сделать все в один проход, например так:
Code
function ***(***)
    local item_sections = {
     [1] = "af_baloon",
     [2] = "af_gravi",
     [3] = "af_ice",
     [4] = "af_glass",
     [5] = "af_fuzz_kolobok",
     [6] = "af_gold_fish",
     [7] = "af_fire" }
    local needed = 12
    local count = 0

    local function calc(temp, item)
     for k,v in pairs(item_sections) do
      if item:section() == v then
       count = count + 1
      end
     end
    end
       
    get_story_object("actor"):iterate_inventory(calc, actor)
       
    return count >= needed
end

Второй вариант использовать инфопорции для индикации наличия нужного списка предметов или его отсутствия. Устанавливать или сбрасывать инфопорции придется используя колбеки на состояние ГГ, тоесть не периодически проверяя инвентарь, а обрабатывать события изменения инвентаря (зачем каждую секунду перепроверять инвентарь если его содержимое не меняется). Но тут сложнее колбеки вызываются из скрипта bind_stalker.script, там сейчас есть две подходящие функции on_item_take, on_item_drop - на получение и потерю предмета (не проверенно, что эти события работают именно так как тебе нужно, например срабатывает on_item_take при покупке предмета или on_item_drop при сдаче предмета как квестового и т.п., все придется проверять). Используя вызов проверки инвентаря при наступлении этих событий можно контролировать инвентарь именно в те моменты когда это нужно.[/cut]


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
sergej5500Дата: Вс, 13.05.2012, 21:44 | Сообщение # 48
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Добрый День!
Сделал квест на поиск 7 артефактов 7 разных видов, по штуке каждого вида.
[cut=Скрипт квеста]function esc_rasvet_astronom_artefact_quests()
task_manager.get_task_manager():give_task("esc_rasvet_astronom_artefact_quests")
end
function esc_rasvet_astronom_artefact_quests_actor(first_speaker, second_speaker)
return db.actor:object("af_baloon") ~= nil and
db.actor:object("af_gravi") ~= nil and
db.actor:object("af_ice") ~= nil and
db.actor:object("af_glass") ~= nil and
db.actor:object("af_fuzz_kolobok") ~= nil and
db.actor:object("af_gold_fish") ~= nil and
db.actor:object("af_fire") ~= nil
end

function esc_rasvet_astronom_artefact_quests_otdat(first_speaker, second_speaker)
dialogs.relocate_item_section_from_actor(first_speaker, second_speaker, "af_baloon")
dialogs.relocate_item_section_from_actor(first_speaker, second_speaker, "af_gravi")
dialogs.relocate_item_section_from_actor(first_speaker, second_speaker, "af_ice")
dialogs.relocate_item_section_from_actor(first_speaker, second_speaker, "af_glass")
dialogs.relocate_item_section_from_actor(first_speaker, second_speaker, "af_fuzz_kolobok")
dialogs.relocate_item_section_from_actor(first_speaker, second_speaker, "af_gold_fish")
dialogs.relocate_item_section_from_actor(first_speaker, second_speaker, "af_fire")

end
function esc_rasvet_astronom_artefact_quests_nagrada_actor(first_speaker, second_speaker)
dialogs.relocate_money_to_actor(first_speaker, second_speaker, 60000)
end[/cut]
Если прописать эти артефакты в стартовый набор, то квест проходим. Скрипты работают. Но если сохраниться после взятия квеста, и до его сдачи, то сохранения вылетают с логом
[cut=Лог]FATAL ERROR

[error]Expression : !m_error_code
[error]Function : raii_guard::~raii_guard
[error]File : D:\prog_repository\sources\trunk\xrServerEntities\script_storage.cpp
[error]Line : 748
[error]Description : ...es 1\Зов Припяти\gamedata\scripts\sgm_dialogs.script:5462: attempt to index field 'actor' (a nil value)
[/cut] Предполагаю, что где-то ошибка скрипта, но не вижу где. Заранее благодарен за советы.

Обрати внимание на строку скрипта на который ссылается лог. denis2000

Добавлено (13.05.2012, 21:44)
---------------------------------------------
Добрый Вечер! Хочу вернуться к вылету, о котором писал в предыдущем посту.
В строке 5462 находится функция return db.actor:object("af_baloon") ~= nil. Вроде в ней нет ничего необычного.
В сборнике модостроения Хована про такой вылет написано, что скрипт пытается обратится к параметру, но его не существует. Добавить в конфиг необходимый параметр. Как я понял, скрипт должен проверять наличие артефактов у ГГ, и при наличии всех 7 штук обновить задание квеста. Если не перезагружаться, то все работает.
Насчет совета добавить в конфиг необходимый параметр. Как это сделать? Заранее благодарен за советы?

 
XOBAHДата: Вс, 13.05.2012, 22:11 | Сообщение # 49
Техник Вольных
Вольные сталкеры
Сообщений: 912
Награды: 21
Репутация: [ 991 ]

sergej5500, Не, не угадал. Нужно проверять наличие самого ГГ...
Переделай проверку, таким образом
[cut]if db.actor ~= nil then
return db.actor:object("af_baloon") ~= nil and
db.actor:object("af_gravi") ~= nil and
db.actor:object("af_ice") ~= nil and
db.actor:object("af_glass") ~= nil and
db.actor:object("af_fuzz_kolobok") ~= nil and
db.actor:object("af_gold_fish") ~= nil and
db.actor:object("af_fire") ~= nil
else return false
end[/cut]
PS: Могу ошибаться в синтаксисе, ибо в голове висят экзамены и синтаксис другого языка...


 
sergej5500Дата: Вс, 20.05.2012, 22:09 | Сообщение # 50
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Добрый Вечер!
Начал делать цепочку квестов для сталкеров Петрухи и Шило. Так как оригинальные Петруха и Шило ребята немногословные, (после спасения они говорят только: "Спасибо, что спас"), сделал для них поправку логики вида:
on_info = {+zat_b53_thanks_dialog_end =dist_to_actor_ge(65)} nil %=release_npc%.
После помощи Петрухе и получения награды, при удалении ГГ на 65 метров оба персонажа исчезают.
Для реализации квестов создал 2 новых НПС с визуалами и именами Петрухи и Шила, спавн которых происходит по [cut=функции]if has_alife_info("zat_b53_thanks_dialog_end") and dont_has_alife_info("zaton_petrusha_spawn") then
create("zaton_petrusha",120.94340515137,-7.3475394248962,190.58274841309,1174506,316)
give_info("zaton_petrusha_spawn")
end
if has_alife_info("zat_b53_thanks_dialog_end") and dont_has_alife_info("zaton_shilo_spawn") then
create("zaton_shilo",113.15841674805,-3.9360427856445,190.3991394043,1160053,316)
give_info("zaton_shilo_spawn")
end[/cut]В результате 2 НПС спавнятся на Скадовске и для них можно делать квесты.
После получения награды от оригинального Петрухи из котла и до удаления ГГ на 65 метров Петруха и Шило существуют в двух экземплярах. То есть можно их пристрелить и затем на Скадовске встретить живыми и здоровыми. Вопрос, есть ли какая-нибудь инфопорция, выдаваемая в случае атаки главным героем или мутантами, бандитами этого конкретного сквада, которую можно прописать в логику уже заспавнившихся на Скадовске Петрухи и Шила и обеспечить их исчезновение. Заранее благодарен за советы.


Сообщение отредактировал sergej5500 - Вс, 20.05.2012, 22:33
 
denis2000Дата: Пн, 21.05.2012, 12:44 | Сообщение # 51
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

sergej5500, Абсолютно ничего не мешает выдать инфопорцию при удалении НПС и спавнить новых при наличии ее. Тогда не будет никаких "дубликатов".

"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
sergej5500Дата: Пн, 21.05.2012, 23:08 | Сообщение # 52
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Добрый вечер!
Проблему с дубликатами Петрухи и Шила отчасти решил, прописав им в логику строку
on_info = {+zat_b53_actor_enemy} nil %=release_npc%. Инфопорцию взял из логики оригинальных Петрухи и Шила.
Касательно совета denis2000: Абсолютно ничего не мешает выдать инфопорцию при удалении НПС и спавнить новых при наличии ее. Тогда не будет никаких "дубликатов".
Как это сделать технически? Функция release_npc используется в логике Меча и Петьки Размандяя. Вроде никаких инфопорций из нее не выводится. Как по срабатыванию этой функции прописать инфопорцию, пригодную для скрипта спавна "дубликатов"? В сборнике Хована есть функции проверки: жив НПС или мертв. После удаления Петруха не жив, не мертв. Заранее благодарен за советы.
 
denis2000Дата: Пн, 21.05.2012, 23:56 | Сообщение # 53
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

sergej5500, Ну так вот же:
Code
on_info = {+zat_b53_thanks_dialog_end =dist_to_actor_ge(65)} nil %=release_npc +zat_b53_release_nps%.

где - zat_b53_release_nps выдаваемая инфопорция. Стем же успехом заспавнить нпс можно прямо здесь или телепортировать существующих!


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
sergej5500Дата: Чт, 24.05.2012, 15:08 | Сообщение # 54
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Добрый день!
Возник вопрос, можно ли запретить спавн сквада сталкеров на Шевченко до получения определенной инфопорции.
Дописывание в конфиг сквада строки вида online_cond = {+metsh_keys_1_naiden} true прекрасно работало на Кордоне,
но не работает на Затоне. Заранее благодарен за советы.


Сообщение отредактировал sergej5500 - Чт, 24.05.2012, 18:55
 
denis2000Дата: Чт, 24.05.2012, 20:48 | Сообщение # 55
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Quote (sergej5500)
online_cond

Это работать не будет, нужно спавнить сквады по условию.


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
sergej5500Дата: Пт, 25.05.2012, 23:38 | Сообщение # 56
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Добрый Вечер!
Попробовал спавн сталкеров из оригинальной игры по условию. Проверял на сквадах Спартака и Кастета.
[cut=Что изменил]Из конфигов сквадов убрал строки

spawn_point = zat_b7_stalkers_raiders_spawn и spawn_point = zat_b7_stalkers_victims_spawn_1

Из файла simulation.ltx убрал строки
zat_b7_stalkers_raiders = zat_stalker_base_smart и zat_b7_stalkers_victims_1 = zat_b7

В файл sgm.tasks добавил функцию спавна

if db.actor:object("af_quest_b14_twisted") and dont_has_alife_info("zat_b7_stalkers_raiders_spawn") then
create_force("zat_b7_stalkers_raiders","zat_stalker_base_smart")
give_info("zat_b7_stalkers_raiders_spawn")
end
if db.actor:object("af_quest_b14_twisted") and dont_has_alife_info("zat_b7_stalkers_victims_1_spawn") then
create_force("zat_b7_stalkers_victims_1","zat_b7")
give_info("zat_b7_stalkers_victims_1_spawn")
end

Спавн происходит при взятии артефакта на земснаряде[/cut]
Функция спавна работает. У Спартака вроде все нормально, а у Кастета проблема. Султан не хочет давать квест на Шевченко. Сответствующие фразы просто не появляются в диалоге. Диалоги и логику сталкеров я не трогал. В чем может быть проблема. Заранее благодарен за советы.


Сообщение отредактировал sergej5500 - Пт, 25.05.2012, 23:39
 
denis2000Дата: Сб, 26.05.2012, 00:36 | Сообщение # 57
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

sergej5500, Исправляй квест "Наезд", его состояние зависит от наличия этих сквадов.

"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
sergej5500Дата: Вс, 17.06.2012, 14:22 | Сообщение # 58
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Добрый День!
Делаю квест по защите Юпитера от Ренегатов.
[cut=Сделал сквад][jup_renegade_quests_squad_1]:online_offline_group
faction = renegade
npc = sim_default_renegade_4, sim_default_renegade_4, sim_default_renegade_4, sim_default_renegade_4, sim_default_renegade_4, sim_default_renegade_4, sim_default_renegade_4, sim_default_renegade_4, sim_default_renegade_4, sim_default_renegade_4, sim_default_renegade_4, sim_default_renegade_4, sim_default_renegade_4, sim_default_renegade_4, sim_default_renegade_4, sim_default_renegade_4
story_id = jup_renegade_quests_squad_1
target_smart = jup_b208
on_death = %+jup_renegade_quests_squad_1_death%[/cut]
При входе этого сквада в зону alife
[cut=получаю вылет]FATAL ERROR
[error]Expression : !m_error_code
[error]Function : raii_guard::~raii_guard
[error]File : D:\prog_repository\sources\trunk\xrServerEntities\script_storage.cpp
[error]Line : 748
[error]Description : ... 1\Зов Припяти\gamedata\scripts\xr_reach_task.script:117: attempt to index field '?' (a nil value)
stack trace:[/cut]Вылет происходит не в момент спавна, а именно в момент появления сквада в зоне видимости игрока. Что нужно сделать для исправления ошибки. Заранее благодарен за советы.


Сообщение отредактировал sergej5500 - Вс, 17.06.2012, 14:24
 
denis2000Дата: Вс, 17.06.2012, 16:36 | Сообщение # 59
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

sergej5500, Попробуй убавить количество НПС до 6.

"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
FREEM@NДата: Вс, 22.07.2012, 20:33 | Сообщение # 60
Легенда Зоны
Свобода
Сообщений: 1031
Награды: 8
Репутация: [ 271 ]

А как создать такой квест типа принеси/подай на ЗП (хочю учёным прописать квест на поиск гаусс-пушки)
У меня ЗП версии 1.6.2 (если надо)

Читай КМБ. denis2000
 
Поиск: