Подготовка

Нам понадобятся эти файлы:

    * all.spawn (spawns)
    * npc_profile.xml (config\gameplay)
    * spawn_sections.ltx (config\creatures)
    * game_story_ids.ltx (config)
    * task_manager.script (scripts)
    * dialogs.xml (config\gameplay)
    * game_tasks_by_vendor.xml (config\gameplay)
    * stable_task_manager.xml (config\text\rus)

Создание NPC-работодателя
Работа с all.spawn

Распаковываем all.spawn с помощю ACDC.

Находим, например файл alife_l01_escape.ltx и вставляем в конец это:

[18240] ;это уникальный номер. Не должен повторятся
; cse_abstract properties
section_name = stalker ;секция того, что спавним
name = esc_kvestodatel ;имя может быть любое
position = -212.877227783203,-23.1829051971436,-122.68586730957 ;позиция
direction = 0.0285909995436668,0,-0.999590992927551 ;разворот

; cse_alife_trader_abstract properties
money = 6000 ;количество денег, с которым создастся этот NPC (файл профиля NPC перекроет это значение)
character_profile = kvestodatel ;профиль NPC

; cse_alife_object properties
game_vertex_id = 59 ;гейм вертекс можно узнать через скрипт
distance = 0 ;дистанция вокруг позиции, в которой спавним (если 0, то заспавнится точно в позиции, которую мы указали)
level_vertex_id = 40610 ;левел вертекс можно узнать через скрипт
object_flags = 0xffffffbf
custom_data = <<END

[logic]
cfg = scripts\kvestodatel.ltx ;ссылка на логику

[smart_terrains] ;настройки смартов
none = true ;к какому смарту относится NPC (если ''none'', то не берется под гулаг)

END
story_id = 93 ;уникальный story ID
; cse_visual properties
visual_name = actors\ecolog\stalker_ecolog ;визуал NPC

; cse_alife_creature_abstract properties
g_team = 0
g_squad = 0
g_group = 0
health = 3
dynamic_out_restrictions =
dynamic_in_restrictions =
upd:health = 3
upd:timestamp = 0x6d6d695f
upd:creature_flags = 0x75
upd:position = -212.877227783203,-23.1829051971436,-122.68586730957 ;сюда надо вписать теже кординаты, что и в позицию
upd:o_model = 0
upd:o_torso = 0.0285909995436668,0,-0.999590992927551
upd:g_team = 0
upd:g_squad = 0
upd:g_group = 0

; cse_alife_monster_abstract properties
upd:next_game_vertex_id = 65535
upd:prev_game_vertex_id = 65535
upd:distance_from_point = 0
upd:distance_to_point = 0

; cse_alife_human_abstract properties
predicate5 = 1,0,0,2,0
predicate4 = 2,2,1,2

; cse_ph_skeleton properties
upd:start_dialog =

; se_stalker properties

Теперь переходим к путям. Открываем файл way_l01_escape.ltx и вставляем туда это (все настройки аналогичны alife_l01_escape.ltx):

[esc_lager_kvesto_look]
points = p0
p0:name = wp00
p0:position = -213.064239501953,-22.4240226745605,-126.251586914063
p0:game_vertex_id = 59
p0:level_vertex_id = 41279

[esc_lager_kvesto_pack]
points = p0
p0:name = wp00
p0:position = -212.877227783203,-23.1829051971436,-122.68586730957
p0:game_vertex_id = 59
p0:level_vertex_id = 40610

Теперь, скомпилируйте all.spawn.

Все со спавном закончили.
Профиль нового NPC

Думаю вы уже умеете работать с профилями, поэтому расписывать не буду - есть много статей про это.

Я сделал профиль так:

<specific_character id="kvestodatel" team_default = "1">
           <name>kvestodatel</name>
           <icon>ui_npc_u_stalker_ecolog</icon>
           <bio>esc_stalker_novice_bio</bio>
              <class>kvestodatel</class>
              <community>ecolog</community> <terrain_sect>stalker_terrain</terrain_sect>
              <rank>400</rank>
              <reputation>30</reputation>
              <money min="20000" max="600000" infinitive="1"/>
              <snd_config>characters_voice\human_03\ecolog\</snd_config>
              <crouch_type>-1</crouch_type>
               <visual>actors\ecolog\stalker_ecolog</visual>
               <supplies>
                [spawn] \n
                wpn_pm \n
                ammo_9x18_fmj = 1 \n
                wpn_bm16 \n
                ammo_12x70_buck \n
                device_torch \n
             #include "gameplay\character_items.xml" \n
             #include "gameplay\character_food.xml"
               </supplies>
            #include "gameplay\character_criticals_3.xml"
             <start_dialog>hello_dialog</start_dialog>
             <actor_dialog>tm_kvestovik_dialog</actor_dialog> ;ссылка на диалог однотипного квеста
     <actor_dialog>tm_kvestovik_reward</actor_dialog> ;ссылка на награду за выполнения квеста
             </specific_character>

Теперь создадим класс и спавн секцию.

Открываем файл npc_profile.xml. Добавляем в него вот это:

<character id="kvestodatel">
<class>kvestodatel</class>
</character>

В spawn_sections.ltx добавляем такую секцию:

[esc_kvest]:stalker
$spawn=  "respawn\esc_kvest"
character_profile= kvestodatel
spec_rank = regular
community = ecolog

Логика

Создайте файл kvestodatel.ltx в config/scripts.

Пропишите в нем:

[logic]
active = walker
inv_max_weight = 10000
on_death = death
combat_ignore = combat_ignore

[walker]
path_walk = esc_lager_kvesto_pack
path_look = esc_lager_kvesto_look
meet = meet

[meet]
use = true
use_wpn = true
meet_talk_enabled = true

[combat_ignore]
combat_ignore_cond = always

Ну вот и все, NPC готов, он заспавнится в подвале новичков.
Возможность выдачи квеста
Скрипты

Теперь, пропишем ему однотипные квесты.
Найдите файл game_story_ids.ltx, и после

092   = "escape_provodnik"

напишите

093   = "kvestovik"

Все, дальше переходим к файлу task_manager.script
В нем видим, в самом начале:

local parent_by_story = {
   [003] = "trader",
   [500] = "barman",
   [902] = "ecolog",
   [507] = "dolg",
   [707] = "freedom",
   [006] = "wolf",
   [004] = "shustriy",
   [510] = "drunk_dolg",
   [504] = "hunter",
   [518] = "zastava_commander",
   [506] = "petrenko",
   [607] = "lisiy",
   [515] = "mercenary"
}

Допишем своего персонажа. Должно быть так:

local parent_by_story = {
   [003] = "trader",
   [500] = "barman",
   [902] = "ecolog",
   [507] = "dolg",
   [707] = "freedom",
   [006] = "wolf",
   [004] = "shustriy",
   [510] = "drunk_dolg",
   [504] = "hunter",
   [518] = "zastava_commander",
   [506] = "petrenko",
   [607] = "lisiy",
   [515] = "mercenary",
   [093] = "kvestovik"
}

Далее видим:

local story_by_parent = {
   trader                  = 003,
   barman                  = 500,
   ecolog                  = 902,
   dolg                  = 507,
   freedom                  = 707,
   wolf                  = 006,
   shustriy               = 004,
   drunk_dolg               = 510,
   hunter                  = 504,
   zastava_commander         = 518,
   petrenko               = 506,
   lisiy                  = 607,
   mercenary               = 515
}

Должно быть:

local story_by_parent = {
   trader                  = 003,
   barman                  = 500,
   ecolog                  = 902,
   dolg                  = 507,
   freedom                  = 707,
   wolf                  = 006,
   shustriy               = 004,
   drunk_dolg               = 510,
   hunter                  = 504,
   zastava_commander         = 518,
   petrenko               = 506,
   lisiy                  = 607,
   mercenary               = 515,
   kvestovik               = 093
}

Потом в конце находим:

function init_mercenary_task_dialog(dlg)
get_random_task():init_task_dialog(dlg, "mercenary")
end

После него пишем по аналогии:

function init_kvestovik_task_dialog(dlg)
get_random_task():init_task_dialog(dlg, "kvestovik")
end

Ниже, после

function init_mercenary_reward_dialog(dlg)
get_random_task():init_reward_dialog(dlg, "mercenary")
end

Пишем:

function init_kvestovik_reward_dialog(dlg)
get_random_task():init_reward_dialog(dlg, "kvestovik")
end

Диалоги
Открываем dialogs.xml
Добавим в конец:

<dialog id="tm_kvestovik_dialog" priority="-1">
<init_func>task_manager.init_kvestovik_task_dialog</init_func>
    </dialog>
    <dialog id="tm_kvestovik_reward" priority="0">
<init_func>task_manager.init_kvestovik_reward_dialog</init_func>
<precondition>task_manager.has_active_vendor_task</precondition>
    </dialog>

Откройте game_tasks_by_vendor.xml. Добавьте туда это:

<!-- esc_arter -->
         <game_task id="eliminate_lager_kvestovik">
<title>title</title>
<objective>
<text>objective</text>
<icon>ui_iconsTotal_eliminate_lager</icon>
<function_complete>task_manager.task_complete</function_complete>
<function_fail>task_manager.task_fail</function_fail>
</objective>
</game_task>
<game_task id="defend_lager_kvestovik">
<title>title</title>
<objective>
<text>objective</text>
<icon>ui_iconsTotal_defend_lager</icon>
<function_complete>task_manager.task_complete</function_complete>
<function_fail>task_manager.task_fail</function_fail>
</objective>
</game_task>
<game_task id="artefact_kvestovik">
<title>title</title>
<objective>
<text>objective</text>
<icon>ui_iconsTotal_artefact</icon>
<function_complete>task_manager.task_complete</function_complete>
<function_fail>task_manager.task_fail</function_fail>
</objective>
</game_task>
<game_task id="kill_stalker_kvestovik">
<title>title</title>
<objective>
<text>objective</text>
<icon>ui_iconsTotal_kill_stalker</icon>
<function_complete>task_manager.task_complete</function_complete>
<function_fail>task_manager.task_fail</function_fail>
</objective>
</game_task>
<game_task id="monster_part_kvestovik">
<title>title</title>
<objective>
<text>objective</text>
<icon>ui_iconsTotal_monster_part</icon>
<function_complete>task_manager.task_complete</function_complete>
<function_fail>task_manager.task_fail</function_fail>
</objective>
</game_task>
<game_task id="find_item_kvestovik">
<title>title</title>
<objective>
<text>objective</text>
<icon>ui_iconsTotal_find_item</icon>
<function_complete>task_manager.task_complete</function_complete>
<function_fail>task_manager.task_fail</function_fail>
</objective>
</game_task>

Откройте файл stable_task_manager.xml

Добавьте это:

<string id="tm_kvestovik_has_no_job">
        <text>Пока ничего.</text>
    </string>
    <string id="tm_kvestovik_job_ask">
        <text>По поводу какого задания ты хочешь поговорить?</text>
    </string>
    <string id="tm_kvestovik_job_complete">
        <text>Вот вознаграждение</text>
    </string>
    <string id="tm_kvestovik_job_what">
        <text>Что по заданию?</text>
    </string>
    <string id="tm_kvestovik_list_job">
        <text>Есть кое-что:</text>
    </string>

Заключение

Теперь создайте однотипный квест, останавливаться на этом я не буду - есть много статей на эту тему. Просто чтобы добавить этому NPC задания, когда будете делать квест, в task_manager.ltx, в строке parent пропишите kvestovik.