Эта заметка предназначена начинающим авторам наInstead.
Во всех квестах конечно есть НПС с которыми можно общаться, получать задания и т.д. Исторически разработчики не заморачивались разнообразием реплик НПС-болванчиков. Один и тот же диалог запускался при каждом обращении. Я лично считаю это вполне нормальным поведением и данью классическим квестам и рпг, но некоторые считают иначе и ниже я приведу пару способов разнообразить поведение НПС.
Обычно НПС выглядит как-то так:
obj {
nam = 'Трактирщик';
dsc = 'За барной стойкой {трактирщик} протирает стаканы ветхим полотенцем.';
act = function()
walk 'Разговор с трактирщиком';
end;
};
Итак вариант №1: завести специальную квестовую переменную отвечающую за реплики трактирщика. Пишу:
global { -- определение глобальных переменных
q1 = 0;
};
Переписываю трактирщика:
obj {
nam = 'Трактирщик';
dsc = 'За барной стойкой {трактирщик} протирает стаканы ветхим полотенцем.';
act = function()
if q1 == 0 then
walk 'Разговор с трактирщиком';
q1 = 1;
else
walk 'Другой разговор с трактирщиком';
end;
end;
};
Ладно, но может есть способ попроще? Вариант №2: использование функции visits(). visits() возвращает количество посещений комнаты или диалога. Код тогда будет такой:
obj {
nam = 'Трактирщик';
dsc = 'За барной стойкой {трактирщик} протирает стаканы ветхим полотенцем.';
act = function()
if visits('Разговор с трактирщиком') == 0 then
walk 'Разговор с трактирщиком';
else
walk 'Другой разговор с трактирщиком';
end;
end;
};
Хорошо, а если трактирщик выдает какой-то предмет для выполнения квеста? Как например в Fallout 2 Мамаша в Дыре даёт обед для Смитти?
obj {
nam = 'Трактирщик';
dsc = 'За барной стойкой {трактирщик} протирает стаканы ветхим полотенцем.';
act = function()
if not have 'Обед для Смитти' then
walk 'Разговор с трактирщиком';
else
p 'Ты ещё не отнёс обед для Смитти? Поторопись, остынет же!';
end;
end;
};
Кстати реакцию по else я заменил просто кратким напоминанием о задании. Но вот герой отнёс обед, вернулся и опять получает диалог про обед? Нелогично, хотя во многих ММОРПГ обычное дело — дейлики всякие. Можно использовать переменную или опять visits().
obj {
nam = 'Трактирщик';
dsc = 'За барной стойкой {трактирщик} протирает стаканы ветхим полотенцем.';
act = function()
if not have 'Обед для Смитти' and visits('Разговор с трактирщиком') == 0 then
walk 'Разговор с трактирщиком';
elseif have 'Обед для Смитти' then
p 'Ты ещё не отнёс обед для Смитти? Поторопись, остынет же!';
else
walk 'Другой разговор с трактирщиком';
end;
end;
};
На самом деле тут получается небольшая нелогичность, если в диалоге например предусмотрена возможность отказаться от квеста с намерением вернуться к нему позже. Тогда остаётся только переменная:
obj {
nam = 'Трактирщик';
dsc = 'За барной стойкой {трактирщик} протирает стаканы ветхим полотенцем.';
act = function()
if q1 == 0 then
walk 'Разговор с трактирщиком';
elseif have 'Обед для Смитти' then
p 'Ты ещё не отнёс обед для Смитти? Поторопись, остынет же!';
else
walk 'Другой разговор с трактирщиком';
end;
end;
};
И уже в диалоге если герой согласился сделать задание, присвойте q1 = 1;
Заключение: Конечно можно всё это сделать в самом диалоге при помощи cond и тегов, но иногда в результате получается настолько запутанная конструкция, что реально проще раскидать всё это на несколько более простых диалогов, а логику оставить в самом объекте-НПС, как в примерах выше. Впрочем образцы диалогов я возможно опишу в отдельной заметке.
А ещё есть интересная функция seen(), которая тоже часто пригождается в условиях.
Ответьте на опрос ниже и конечно лайк, шер и ретвит! Вопросы пишите в комментариях.
Ссылка:
https://ifhub.club/2018/04/13/realizaciya-nps-v-instead.html