сталкер гулаги что это
SoC. Смартеррейны и гулаги
Материал из S.T.A.L.K.E.R. Inside Wiki
В последнее время люди постоянно меня спрашивали как создать скрипт гулага для смартеррейнов. Чтобы постоянно не отвечать на каждое отдельное письмо, я решил написать небольшой тутор. Прежде чем начать, хотелось бы предупредить, что не являюсь экспертом в подобного рода вещах и некоторые моменты мне всё еще не ясны до конца, так что вероятно я не смогу объяснить всё правильно. Также я буду использовать ST как абревиатуру смартеррейна. Этот тутор посвящен НПС в ST, но он также сгодится и для мутантов. Предполагаю что вы знакомы с:
— луа программированием
— редактированием all.spawn
— работа с вейпоинтами(патрульными путями)
— утилитами аи
В первую очередить подумайте о своём ST, где бы его заспавнить, сколько нпс/мутантов будут в нем выполнять определенную «работу», когда ST должен активироваться/отключаться, сколько и какие состояния будет у вашего ST и тд. Думаю, наиболее эффективный способ объяснить вам как это работает на примере. Давайте предположим.. мы хотим поставить ST(smart terrain) на Кордоне для 3х бандитов.
Эта наиболее важная часть:
2. Спавн нпс/мутантов и назначение(биндинг) их к нашему ST: для этого мы должны добавить каждому мутанту/нпс определенную логику:
Если таковых нпс не обнаружится то гулаг выберет себе население из числа заспавнившихся в Зоне нпс с подходящими параметрами. Даже если они на другой локации.
3. Добавляем «работу» (логика) для каждого нпс/мутанта из нашего ST(для каждого состояния). Предположии у ST их два: состояние 0 (описывает какие нпс/мутанты «работают» днем) и состояние 1 (ночью). У нас 3 бандита, определяемся:
— bandit1: walker (состояние 0) и kamp (состояние 1)
— bandit2: guard (состояние 0) и sleeper (состояние 1)
— bandit3: walker (состояние 0 и 1 function load_job(. )
Еще один момент о состояниях ST, всё зависит от того сколько у вас их в ST. Еще одна важной вещью является добавление логики для каждого состояния. Например в вашем ST такие состояния:
К сведению, меня не прет заполнять такое большое количество таблиц, так что обычно я использую эту функцию:
Используя функцию выше, мы можем загружать логику наподобие этой:
Так же существуют универсальные гулаги General_lager для сталкеров. Они считаются упрощенными гулагами.
Пример, создаем смарт:
General_lager автоматически соберет все точки путей на уровне начинающиеся на имя смарта(в нашем случае esc_gen_lager) и разделит их названия таким образом: (имя_смарта)_(аи схема)_(номер если требуется,напрмер если 2 walkerа то 1 и 2 соответственно)_(поднастройка схемы)_(состояние гулага 1 или 0,день или ночь) пример: esc_gen_lager _walker _1 _walk _1 (walk то же что и path_walk,look это path_look соответственно)
Пришедший на general_lager сталкер рандомно примет любую свободную работу работой считается комбинация схем с одним номером. например esc_gen_lager_walker_1_walk_1 и esc_gen_lager_walker_1_look_1 это схема дневной работы одного персонажа из гулага.
Так что для каждого general_lager нужны заранее расставленые точки путей для него.
Смартеррейны и гулаги
В последнее время люди постоянно меня спрашивали как создать скрипт гулага для смартеррейнов. Чтобы постоянно не отвечать на каждое отдельное письмо, я решил написать небольшой тутор. Прежде чем начать, хотелось бы предупредить, что не являюсь экспертом в подобного рода вещах и некоторые моменты мне всё еще не ясны до конца, так что вероятно я не смогу объяснить всё правильно. Также я буду использовать ST как абревиатуру смартеррейна. Этот тутор посвящен НПС в ST, но он также сгодится и для мутантов. Предполагаю что вы знакомы с:
— луа программированием
— редактированием all.spawn
— работа с вейпоинтами(патрульными путями)
— утилитами аи
В первую очередить подумайте о своём ST, где бы его заспавнить, сколько нпс/мутантов будут в нем выполнять определенную «работу», когда ST должен активироваться/отключаться, сколько и какие состояния будет у вашего ST и тд. Думаю, наиболее эффективный способ объяснить вам как это работает на примере. Давайте предположим.. мы хотим поставить ST(smart terrain) на Кордоне для 3х бандитов.
[2515]
; cse_abstract properties (основные параметры)
section_name = smart_terrain
name = esc_bandits_smart_terrain
position = 131.02030944824,0.065616846084595,-248.9094543457
direction = 0,0,0
; cse_alife_object properties (параметры объекта)
game_vertex_id = 635
distance = 9.09999942779541
level_vertex_id = 363757
object_flags = 0x==3e
custom_data =
2. Спавн нпс/мутантов и назначение(биндинг) их к нашему ST: для этого мы должны добавить каждому мутанту/нпс определенную логику:
custom_data = состояние 0, днем)
[logic@esc_bandits_smart_terrain_bandit1_walker]
active = walker@esc_bandits_smart_terrain_bandit1
[walker@esc_bandits_smart_terrain_bandit1]
path_walk = bandit1_walk
danger = danger_condition@esc_bandits_smart_terrain
def_state_moving1 = patrol
def_state_moving2 = patrol
def_state_moving3 = patrol
meet = no_meet
[kamp@esc_bandits_smart_terrain_bandit1]
center_point = bandit_kamp
path_walk = bandit_kamp_task
[walker@esc_bandits_smart_terrain_bandit2]
path_walk = bandit2_walk
path_look = bandit2_look
danger = danger_condition@esc_bandits_smart_terrain
[sleeper@esc_bandits_smart_terrain_bandit2]
path_main = bandit2_sleep
wakeable = false
[walker@esc_bandits_smart_terrain_bandit3]
path_walk = bandit3_walk
path_look = bandit3_look
[danger_condition@esc_bandits_smart_terrain]
ignore_distance_corpse = 0
ignore_distance = 0
4. Теперь нам нужно заскриптовать наш ST. Так что добавим наш код в фаил скрипта \gulag_escape.script. Есть еще несколько моментов, которые мы должны здесь доделать (каждый из этих шагов обязателен):
t =
group = groups[1], position_threshold = 100, online = true, in_rest = «»,
out_rest = «», predicate = function(obj_info) return obj_info.rank >= 900 end>
table.insert(sj, t)
Еще один момент о состояниях ST, всё зависит от того сколько у вас их в ST. Еще одна важной вещью является добавление логики для каждого состояния. Например в вашем ST такие состояния:
К сведению, меня не прет заполнять такое большое количество таблиц, так что обычно я использую эту функцию:
function fill_tbl(section, idle, prior, states, squad, group, in_rest, out_rest, online, gulag_name)
local tbl = <>
for index = 1, #states do
table.insert(tbl.state, states[index])
end
tbl.squad = squad
tbl.group = group
tbl.in_rest = in_rest
tbl.out_rest = out_rest
tbl.online = online
return tbl
end
Используя функцию выше, мы можем загружать логику наподобие этой:
if type == «esc_bandits_smart_terrain» then
local t = table.insert(sj, fill_tbl(«bandit1_walker», 0, 100, <0>, squad, groups[1], «», «», true, type))
t.timeout = 0
t.position_threshold = 100
t.predicate = function(obj_info) return obj_info.rank >= 900 end
table.insert(sj, t)
t = table.insert(sj, fill_tbl(«bandit1_kamp», 0, 100, <1>, squad, groups[1], «», «», true, type))
t.timeout = 0
t.position_threshold = 100
t.predicate = function(obj_info) return obj_info.rank >= 900 end
table.insert(sj, t)
table.insert(sj, fill_tbl(«bandit2_walker», 0, 5, <0>, squad, groups[1], «», «», true, type))
table.insert(sj, fill_tbl(«bandit2_sleeper», 0, 5, <1>, squad, groups[1], «», «», true, type))
table.insert(sj, fill_tbl(«bandit3_walker», 0, 5, <0, 1>, squad, groups[1], «», «», true, type))
end
if type == «esc_bandits_smart_terrain» then
return function(gulag)
if not db.actor then
return gulag.state
end
if level.get_time_hours() >= 5 and level.get_time_hours() function checkStalker(. )
if gulag_type == «esc_bandits_smart_terrain» then
return npc_community == «bandit»
end
Так же существуют универсальные гулаги General_lager для сталкеров. Они считаются упрощенными гулагами.
Пример, создаем смарт:
[9999]
; cse_abstract properties (основные параметры)
section_name = smart_terrain
name = esc_gen_lager
position = 131.02030944824,0.065616846084595,-248.9094543457
direction = 0,0,0
* Примечание.
* Есле вы создали смарт на своем, новом, уровне то нужно добавить в config\misc\general_lair
[Имя уровня] boar = weak, normal, strong bloodsucker = weak, normal, strong flesh = weak, normal, strong dog = weak, normal, strong pseudodog = weak, normal, strong giant = weak, normal, strong zombie = weak, normal, strong burer = weak, normal, strong controller = weak, normal, strong poltergeist = weak, normal, strong snork = weak, normal, strong tushkano = weak, normal, strong
и в тои же папке в smart_terrain_presets добавить
[Имя уровня] stalker = novice, experienced, veteran, master monolith = novice, experienced, veteran, master military = novice, experienced, veteran, master killer = novice, experienced, veteran, master ecolog = novice, experienced, veteran, master dolg = novice, experienced, veteran, master freedom = novice, experienced, veteran, master bandit = novice, experienced, veteran, master zombied = novice, experienced, veteran, master
boar = weak, normal, strong bloodsucker = weak, normal, strong flesh = weak, normal, strong dog = weak, normal, strong pseudodog = weak, normal, strong giant = weak, normal, strong zombie = weak, normal, strong burer = weak, normal, strong controller = weak, normal, strong poltergeist = weak, normal, strong snork = weak, normal, strong tushkano = weak, normal, strong
[править]
Создадим смарт для НПС
И так, повторяем действия сделанные выше Открываем сдк, жмем spawn element>ai>smart terrains, шлепаем сие на локацию, затем переходим в shape>sphere(можно и box по желанию) и снова вставляем сие на локацию, увеличиваем до нужных размеров (не сильно больших), переходим обратно в режим spawn element, жмем кнопку attach object и кликаем на созданной нами сфере. открываем properties правым щелчком мыши или eneter по умолчанию. открываем custom data и пишем в ней [smart_terrain] type = general_lager capacity = 5 что такое capacity вы уже знаете. Создаем пути для НПС (Работы для НПС) вот примеры путей
* smart_name_kamp_1
* smart_name_sleep_1
* smart_name_walker_1_walk \ smart_name_walker_1_look
* smart_name_walker2_1_walk \ smart_name_walker2_1_look
* smart_name_patrol_1_walk
* smart_name_guard_1_walk \ smart_name_guard_1_look
* smart_name_sniper_1_walk \ smart_name_sniper_1_look
smart_name_kamp_1 имя_гулага_kamp_коментарии типа [esc2_tunnel3_home_1] причем вместо 1 может быть все что угодно
Гулаги(Динамические LTX)
Гулаги(Динамические LTX)
Материал из S.T.A.L.K.E.R. Inside Wiki.
При создании гулага, не многие знают, что практически всю настройку логики гулагов, можно производить в файле «script». Такой способ построения достигается за счёт динамических ltx. Попробую описать, каким образом это достигается. Я думаю, многие заметили в файлах с гулагами такую функцию:
Это именно та функция, которая и отвечает за динамические ltx. В данном случае, она отключена. Разберём простейший способ построения динамических ltx.
Создаём стандартным способом «smart_terrain» в файле «all.spawn» и гулаг в файле «gulag_уровень.script». Назначим ему имя, например «kakashki». Задаём ему несколько заданий. Например, зададим 3 кампа и двух уолкеров:
if type == «kakashki» then
Так как мы собираемся использовать динамические ltx, то дальнейшая настройка заданий будет производиться не в конфигурационных файлах, а непосредственно в этом же файле. То есть в упомянутой выше функции «load_ltx». Для этого находим нужную функцию «load_ltx», и в ней создаём динамический ltx и прописываем требуемые схемы логики:
if type == «kakashki» then
local ltx = «[logic@kakashki_kamp]\n»..
«active = kamp@kakashki\n»..
«[kamp@kakashki]\n»..
«center_point = kamp\n»..
«[logic@kakashki_walker_1]\n»..
«active = walker@kakashki_1\n»..
«[walker@kakashki_1]\n»..
«path_walk = walk_1\n»..
«path_look = look_1\n»..
«[logic@kakashki_walker_2]\n»..
«active = walker@kakashki_2\n»..
«[walker@kakashki_2]\n»..
«path_walk = walk_2\n»..
«path_look = look_2\n»
Где, кавычки обязательны, <\n>назначает новую строку в динамическом ltx, и <..>ставится для привязки строк между собой. В последней строке схем, двоеточие ставить не нужно, так как привязывать больше нечего. Переменная «ltx» может иметь любое другое имя.
Теперь создаём вэйпоинты путей, в файле «all.spawn», и можно смело идти проверять.
Создаём 8 уолкеров в функции «load_job». Обязательно с помощью счётчика «for-do»:
Кто ещё не знает, как это работает, то поясню. Создаётся переменная i, или любое другое имя. Назначается ей два, или три значения, (через запятую). Где:
первое значение = какое число задаётся при первом цикле счёта;
второе значение = при достижении или переполнении какого числа, остановить счёт;
третье значение = какое значение прибавлять, при каждом цикле счёта.
Если третье значение не задаётся, то при каждом цикле счёта, прибавляется 1.
Переменной «section» задаётся «имя секции»+переменная i. В итоге, при каждом последующем цикле счёта, к имени секции будет приписываться в конце значение переменной i. Тоесть, «logic@kakashki_walker_1»; «logic@kakashki_walker_2»; «logic@kakashki_walker_3» и т.д.
В нашем случае, переменной «prior» задано значение 9-i, что делать не обязательно. Здесь при каждом цикле счёта, вычитается значение переменной i от числа 9. В итоге, при каждом последующем цикле, переменной «prior» задаётся значение на 1 меньше предыдущего.
Итак, уолкеров создали. Теперь нам нужно задать им всем логику действий. Создаём переменную ltx, которую мы будем использовать для динамических ltx. Для этого, подымаемся на самый верх файла, где прописано создание переменной t, и ниже прописываем:
Теперь, в функции «load_ltx» создаём ltx файл для нашего гулага:
function load_ltx(gname, type)
if type == «kakashki» then
return ltx
end
Данным способом, мы возвращаем поиск секций логики, назад в функцию «load_job».
Теперь возвращаемся в функцию «load_job», и в секции нашего гулага, внутри счётчика «for-do» прописываем логику уолкерам. Выглядеть это будет так:
ltx = ltx.. «[logic@kakashki_walker_»..i..»]\n»..
«active = walker@kakashki_»..i..»\n»..
«[walker@kakashki_»..i..»]\n»..
«path_walk = walk_»..i..»\n»..
«path_look = look_»..i..»\n»
Где, так же как и в случае с переменной «section», приписывается в конец имён секций и путей, значение переменной i. В итоге получаем такие имена путей:
walk_1, look_1; walk_2, look_2; walk_3, look_3; и т.д.
Заметим, как мы прописали переменную ltx. Таким способом, мы при каждом цикле счёта, новую секцию логики пришиваем к секциям, пришитым к динамическому ltx при предыдущих циклах. Если прописать просто:
То при каждом цикле счёта новая секция будет накладываться на предыдущую, что приведёт к нехорошим последствиям.
Ну и создаём соответствующие секции поинтов путей в файле all.spawn. И всё будет работать как часы.
Не забываем, при создании секций поинтов, к именам путей пришить имя смарт террэйна.
Вот IG-2007 на оф.форуме осенью прошлого года написал такой тутор по гулагам. Здесь показана работа в гулаге для сталкера. Днем он гуляет (walker), а ночью сидит у костра (kamp).
Смарттерейны и гулаги. Смарттеррейн
Смарттеррейн.
Под смарттеррейном мы понимаем зону, зайдя в которую, сталкер на некоторое время попадает под гулаг и начинает выполнять работу, предусмотренную этим гулагом. После некоторого времени он выходит из-под гулага и ходит свободно.
Как поставить smart terrain?
Для всех smart terrain нужно:
1) Поставить smart terrain с необходимым shape. Большой shape не рекомендуется (размер влияет на производительность).
2) В его custom data прописать настройки.
3) Расставить пути для соответствующих схем поведения.
Параметры custom data:
capacity = макс. вместимость в людях
*offline = может ли гулаг образоваться в offline (true(по дефолту)/false)
*squad = squad, который будет проставлен всем сталкерам под гулагом (№ уровня)
*groups = набор group через запятые
Указывать тип гулага нужно без кавычек.
Если не задан squad или groups, то соответствующие свойства сталкеров не будут изменяться.
Все времена задаются в часах игрового времени и могут быть дробными.
Имена путей для схем поведения всегда должны начинаться с имени данного smart terrain. Например, esc_smart_ambush_vagon_sleep.
Если пути для smart terrain на нескольких человек (campers, walkers), то их имена должны заканчиваться всегда на цифру (esc_smart_ambush_vagon_walk1, esc_smart_ambush_vagon_walk2)
Гулагов под одним smart terrain может быть несколько. Их можно настраивать в секциях [gulag2], [gulag3] и т.д. При входе сталкера под smart terrain будет случайно выбран один из доступных на данный момент гулагов.
Стандартные типы смарттеррейнов.
Если нужно, чтоб сталкер не захватывался, допишите ему в custom data следующую строку:
Если сталкер уже под каким-то smart terrain, то остальные smart terrain он будет игнорировать.
Campers
Кемперы. custom data:
capacity = от 1 до 3
Walkers
Ходячие. На базе этого можна сделать поиск, обыск и куча всего.
capacity = от 1 до 3
Search
Ходячие. На базе этого можна сделать поиск, обыск и куча всего.
Rest
Отдых. Сталкер по очереди то sleeper, то walker, то rest(ест еду, пьёт водку).
rest – путь из двух вершинок (возможно из 1). В одной сидит, в другую смотрит.
Гулаги.
Б) Работы имеют приоритеты;
В) Гулаг назначает на работы сталкеров входящих в гулаг, начиная с работ с наивысшим приоритетом;
Г) Гулаг имеет состояния. Каждое состояние характеризуется своим набором работ, отличным от набора работ в любом другом состоянии гулага.
Гулаг создается следующим образом:
1. Необходимо четко определить набор состояний гулага: день, ночь, спокойное, при тревоге и так далее. Для простых гулагов достаточно одного состояния, для крутых и сложных – желательно разные. Это придает разнообразия и смотрится лучше.
2. Определяем максимальное количество людей, которым гулаг может управлять. То есть определяем вместимость гулага. Она должна быть такой, чтобы в любом состоянии гулага гарантированно нашлось занятие для каждого человека.
3. Для каждого состояния гулага определяется набор работ. Эти работы могут быть как активного плана (часовой, патруль, и так далее), так и пассивного плана (сидят вокруг костра, спят). Каждая работа имеет свой приоритет. Соответственно пассивные работы должны иметь меньший приоритет.
4. Ставится в редакторе количество людей, которые должны быть под гулагом, и накрываются зонкой smart_terrain (источник ошибок – иногда ставят space_restictor). Зонке нужно давать осмысленное название. Это же название будет являться префиксом к названием всех патрульных путей, относящихся к этому же гулагу. Например если вы назвали зонку esc_blockpost, то все патрульные пути должны начинаться с этого префикса, например esc_blockpost_guard_walk. В custom_data зоны необходимо прописать настройку гулага.
capacity = макс. вместимость в людях
*squad = squad, который будет проставлен всем сталкерам под гулагом
*groups = набор group через запятые
*respawn = имя респауна (вызывает респаунер с заданым именем каждый раз, когда кто-то из самрттеррейна заступает на работу)
Capacity нужно задавать всегда. Она может быть равна или меньше числа работ.
Указывать тип гулага нужно без кавычек.
Полем offline можно задать, чтоб гулаг не образовывался в офлайн. Т.е. существовать в офлайн он может, а образовываться – нет.
Если не задан squad или groups, то соответствующие свойства сталкеров не будут изменяться.
Все времена задаются в часах игрового времени и могут быть дробными.
5. В скрипте \gamedata\scripts\gulag_название_уровня.script необходимо прописать условия, при которых сталкеры берутся под конкретный гулаг. В функцию checkNPC необходимо прописать условие:
if gulag_type == «gar_dolg» then
return npc_community == «dolg»
В эту функцию пока передается два параметра, тип гулага и комьюнити персонажа. В данном случае под гулаг с типом gar_dolg будут приниматься все персонажи, относящиеся к группировке Долг.
6. В файле \gamedata\scripts\gulag_название_уровня.script необходимо описать переключение состояний гулага.
function loadStates(gname, type)
в нее передается имя зонки и тип гулага. Состояние гулага описывается в виде функции, возвращающей номер состояния гулага. Например:
Сталкер гулаги что это
Прописывается у физического объекта какие звуки он выдает (изначально планировался как матюгальник).
[ph_sound]
snd = имя темы из файла sound_theme.script из таблицы ph_snd_themes
NB! Если мы задаем random = true и looped = true, то версия сыпется
Также поддерждивается кондлист.
Данная схема работает через задницу, поэтому зацикленный звук будет продолжать отыгрываться, даже если объект уходит в nil. В связи с этим надо создавать новую секцию, которая бы отыгрывала одиночный короткий звук, после которого (поскольку он будет точно также играться раз за разом) ставим on_signal = sound_end| nil
Пример подобной извращенной логики:
[logic]
active = ph_sound
[ph_sound]
snd = gar_seryi_shooting
looped = true
max_idle = 5000
on_actor_in_zone = gar_seryi_factory| ph_sound@end
[ph_sound@end]
snd = gar_seryi_shooting_2
looped = false
on_signal = sound_end| nil
Кроме того специфическим образом создается звуковая схема.
В sound_theme.script в начале файла есть секция ph_themes в которой и описываются темы для физ объектов.
Например:
ph_snd_themes[«gar_seryi_shooting»] =
Кроме того (незадекларированная фича) ph_sound можно вешать на рестрикторы. Но за правильность работы в таком случае никто ответственности не несет.
Однако в оригинале такое встречается, например в бункере Выжигателя мозгов есть рестриктор bun_space_restrictor_sound1 на который как раз и повешан ph_sound.
[править] 3.10.7. Ph_force
Схема позволяет пнуть предмет в указанную сторону. Прописывается в кастом дате предмета.
force = сила, которая прикладывается к объекту. Измеряется в убитых енотах
time = время прикладывания силы к предмету (в секундах)
*delay = задержка (в секундах) перед применением силы
point = имя патрульного пути, точки которого будут использованы как цели (куда направлять предмет)
point_index = индекс точки патрульного пути, в стону которого полетит предмет.
3.10.8. Ph_on_death
Схема для отслеживания разрушения физического объекта и выдавания по такому случаю различных эффектов
Пример:
Юзать исключительно с разрушаемыми физ. Объектами
3.10.9. Ph_car
Настройка возможности игроку управлять машиной.
секция: [ph_car]
поле: usable =
На основе этой схемы можно сделать машину, которая зведется только если у актера есть ключ именно от нее.
3.10.10. Ph_heavy
Прописывается в физ объектах, которые запрещены для швыряния бюрерам и полтергейстам. Например, если они должны лежать на конкретном месте (типа документов сюжетных) или слишком громоздки по габаритам, чтобы их можно было красиво кидать.В кастом дате пишем:
3.10.11. Ph_oscillate
Схема предназначена для плавного раскачивания физики (лампы, висящие зомби и т.д.)Пример логики
Сила прикладывается к кости объекта с линейным наростанием. То есть в течении заданого периода времени сила вырастет с 0 до заявленого значения. После этого настает пауза (сила не применяется) на время period/2. После окончания паузы сила применяется так же, как и в начале, но в обратном направлении.
3.11. Смарттерейны и гулаги.
3.11.1. Смарттеррейн.
Под смарттеррейном мы понимаем зону, зайдя в которую, сталкер на некоторое время попадает под гулаг и начинает выполнять работу, предусмотренную этим гулагом. После некоторого времени он выходит из-под гулага и ходит свободно.
Как поставить smart terrain?
Для всех smart terrain нужно:
1) Поставить smart terrain с необходимым shape. Большой shape не рекомендуется (размер влияет на производительность).
2) В его custom data прописать настройки.
3) Расставить пути для соответствующих схем поведения.
Параметры custom data:
[gulag1]
type = тип гулага
capacity = макс. вместимость в людях
Указывать тип гулага нужно без кавычек.
Если не задан squad или groups, то соответствующие свойства сталкеров не будут изменяться.Все времена задаются в часах игрового времени и могут быть дробными.
Пути:
Имена путей для схем поведения всегда должны начинаться с имени данного smart terrain. Например, esc_smart_ambush_vagon_sleep.
Если пути для smart terrain на нескольких человек (campers, walkers), то их имена должны заканчиваться всегда на цифру (esc_smart_ambush_vagon_walk1, esc_smart_ambush_vagon_walk2)
Гулагов под одним smart terrain может быть несколько. Их можно настраивать в секциях [gulag2], [gulag3] и т.д. При входе сталкера под smart terrain будет случайно выбран один из доступных на данный момент гулагов.
3.11.1.1. Стандартные типы смарттеррейнов.
Если нужно, чтоб сталкер не захватывался, допишите ему в custom data следующую строку:
[smart_terrains]
none = true
Если сталкер уже под каким-то smart terrain, то остальные smart terrain он будет игнорировать.
campers
Кемперы. custom data:
[gulag1]
type = campers
capacity = от 1 до 3
Пути:
camper_walk1, camper_look1
camper_walk2, camper_look2
camper_walk3, camper_look3
walkers
Ходячие. На базе этого можна сделать поиск, обыск и куча всего.
custom data:
[gulag1]
type = walkers
capacity = от 1 до 3
Пути:
walker_walk1, walker_look1
walker_walk2, walker_look2
walker_walk3, walker_look3
search
Ходячие. На базе этого можна сделать поиск, обыск и куча всего.
custom data:
[gulag1]
type = search
capacity = 1
Схема следующая:
1. Персонаж ходит по точкам, смотрит по сторонам
2. В определенных точках останавливается и что-то высматривает (caution, search, hide)
3. При этом говорит определенные реплики (…)
Отдых. Сталкер по очереди то sleeper, то walker, то rest(ест еду, пьёт водку).custom data:
[gulag1]
type = rest
capacity = 1
3.11.2. Гулаги.
Гулаг создается следующим образом:
1. Необходимо четко определить набор состояний гулага: день, ночь, спокойное, при тревоге и так далее. Для простых гулагов достаточно одного состояния, для крутых и сложных – желательно разные. Это придает разнообразия и смотрится лучше.
2. Определяем максимальное количество людей, которым гулаг может управлять. То есть определяем вместимость гулага. Она должна быть такой, чтобы в любом состоянии гулага гарантированно нашлось занятие для каждого человека.
3. Для каждого состояния гулага определяется набор работ. Эти работы могут быть как активного плана (часовой, патруль, и так далее), так и пассивного плана (сидят вокруг костра, спят). Каждая работа имеет свой приоритет. Соответственно пассивные работы должны иметь меньший приоритет.
4. Ставится в редакторе количество людей, которые должны быть под гулагом, и накрываются зонкой smart_terrain (источник ошибок – иногда ставят space_restictor). Зонке нужно давать осмысленное название. Это же название будет являться префиксом к названием всех патрульных путей, относящихся к этому же гулагу. Например если вы назвали зонку esc_blockpost, то все патрульные пути должны начинаться с этого префикса, например esc_blockpost_guard_walk. В custom_data зоны необходимо прописать настройку гулага.
[gulag1]
type = тип гулага
capacity = макс. вместимость в людях
Capacity нужно задавать всегда. Она может быть равна или меньше числа работ.
Указывать тип гулага нужно без кавычек.
Полем offline можно задать, чтоб гулаг не образовывался в офлайн. Т.е. существовать в офлайн он может, а образовываться – нет.
Если не задан squad или groups, то соответствующие свойства сталкеров не будут изменяться.
Все времена задаются в часах игрового времени и могут быть дробными.
5. В скрипте \gamedata\scripts\gulag_название_уровня.script необходимо прописать условия, при которых сталкеры берутся под конкретный гулаг. В функцию checkNPC необходимо прописать условие:
В эту функцию пока передается два параметра, тип гулага и комьюнити персонажа. В данном случае под гулаг с типом gar_dolg будут приниматься все персонажи, относящиеся к группировке Долг.
6. В файле \gamedata\scripts\gulag_название_уровня.script необходимо описать переключение состояний гулага.
function loadStates(gname, type)
в нее передается имя зонки и тип гулага. Состояние гулага описывается в виде функции, возвращающей номер состояния гулага. Например:
В данном случае если сейчас между 7 и 22 часов, то гулаг находится в дневном состоянии, иначе в ночном.
8. В файле \gamedata\scripts\gulag_название_уровня.script необходимо описать должности гулага. В функции loadJob загружаются все допустимые работы. В саму функцию передаются следующие параметры:
function loadJob(sj, gname, type, squad, groups)
sj – сама табличка работ гулагов,
gname – имя нашей зонки смар-тиррейна. Оно используется как префикс.
Type – тип гулага
Squad, groups – таблички сквадов и групп, если нам нужно переопределять родные группы сталкеров на какие либо другие. В каждой работе можно указать какой сквад и группа сетится сталкеру при установке на работу.
Примерное описание работ гулага:
Данный гулаг описывает поведение только одного человека, обычно их гораздо больше. Данный человек в нулевом состоянии(день) делает одну работу, в первом состоянии(ночь) делает другую работу.
то есть данную работу сможет выполнять лишь персонаж с профилем soldier_commander.
9. В \gamedata\config\misc\gulag_название_уровня.ltx необходимо указать, какие схемы поведения соответсвуют той или иной работе. Например в случае с вышерассмотренным гулагом gar_maniac:
Настройка здесь соответствует настроке в обычной кастом дате сталкера, с разницей:
1) пути следует указывать без префикса. То есть если зонка носила название gar_maniac, то пути следует на уровне ставить с названием gar_maniac_walk1, однако в gamedata\config\misc\gulag_название_уровня.ltx следует указывать только walk1.
2) в именах секций схем поведения после @ добавлять название гулага и, возможно, дополнительные сведения (например, walker2@rad_antena_gate)
3) в именах секций logic для каждой работы добавлять после @ имя гулага, дополнительные сведения и имя секции активной схемы поведения (например, logic@rad_antena_gate_walker2).
В работах для гулагов поля leader больше нет. Есть поле dependent. Работа может быть занята только тогда, когда работа с именем dependent уже занята. Например, follower может быть назначен только тогода, когда уже кто-то назначен на работу лидера (имя работы лидера теперь в поле dependent). Естественно, что приоритет работ, от которых зависят другие, должен быть больше чем у них.
3.11.3. Новые особенности смарттеррейнов
Возможности нового смарттеррейна (СТ):
1) Не держит сталкеров постоянно в онлайне. Работает стандартный онлайн-радиус.
2) Сталкеры идут на ближайшие работы.
3) На места работ сталкеры идут независимо от того, в онлайне они или в оффлайне.
4) СТ в офлайне работает так же, как и в онлайне: выполняет переключение своих состояний, перераспределение работ.
5) Сталкерам можно прописать, при каких условиях в какие СТ они могут идти. (см. ниже) Если сталкер попал в СТ, то онбудет находится в нём, пока не истечёт время и выполняется условие.
6) Работы могут находиться на разных уровнях.
7) Скриптовая зона СТ теперь не используется для захвата персонажей.
8) Симуляция заключается в миграции персонажей между разными СТ.
Что нужно переделать:
1) Персонажи могут быть двух типов: либо для СТ, либо для самостоятельной работы под логикой из custom data. У первых логики в custom data не должно быть. У вторых должно быть прописано, что они не хотят ни в один СТ. (см ниже)
2) Нельзя под СТ отправлять сталкеров в nil. Вместо nil дайте им пути. Например, walker-ы в рестрикторе вместо nil в рестрикторе. (есть abort на такой случай)
3) Всех участников созданных сцен поставьте рядом с местами работ, а не в кучу. Так им не придётся полчаса разбредаться по местам работ: они сразу позанимают ближайшие. В custom data им пропишите, что до окончания сцены они могут быть только в этом СТ. (см. ниже)
4) Незначительно переделать функции predicate() и функции переключения состояния СТ. (см. ниже)5) Проследите, чтоб под СТ в логиках в поле active было прописано только имя секции и ничего больше (никаких там процентов и фигурных скобок). Для персонажей не предназначенных под СТ это не играет роли.6) Переименуйте в custom data СТ секцию [gulag1] в секцию [smart_terrain].
Разрешения персонажам идти в определённые СТ задаются в custom data секцией [smart_terrains]. В ней можно задавать пары «имя_СТ = condlist». Пример:
[smart_terrains]
strn_1 = условие1
strn_2 = условие2
Если для какого-то smart_terrain условие выполнилось, он называется эксклюзивным.
Если у объекта появился хоть один эксклюзивный smart terrain, то он будет согласен идти только в него.Если не появилось ни одного эксклюзивного, то он согласен идти в любой.
Есть зарезервированное сочетание «none=true». Если оно указано, то персонаж никогда не пойдёт ни в один СТ. Такой персонаж будет работать только под своей логикой.
Также можно задать, кого принимает СТ. В дополнение к старому механизму (функции checkNpc() в файлах gulag_*.script) можно в custom data СТ написать:
Если это поле не задано, то проверяется старым механизмом. Если задано, то под СТ возьмутся только персонажи указанных группировок (учтите, старый механизм тоже вызовется).
В эти функции вместо game_object будет передаваться табличка с информацией о персонаже. Там есть поля:
name
community
class_id
story_id
profile_name
Если нужно, чтобы работа занималась только снайперами, то в предикате нужно писать:
Обращайтесь индивидуально. Все переделки связаны с работой этой функции в офлайне. Например, таблица gulag.Object[] не содержит game_object-ы, если персонаж в офлайне и т.п.
Состояния работ online/offline
3.12. Логика вертолёта
3.12.1. Схема heli_move:
Для схемы должен быть задан path_move – путь, по которому будет летать вертолёт. Он может содержать одну вершину, если нужно, чтоб вертолёт висел на месте.
Можно (но не обязательно) задать path_look – путь, в вершины которого вертолет может смотреть.
Вершины этих путей могут быть поставлены где угодно в пределах ограничивающего бокса уровня. Они не зависят от ai-nodes.
По пути вертолёт летает без учёта связей между вершинами. Он летает от вершины к вершине в порядке возрастания их номера (т.е. в порядке, в котором их поставили на уровень).
Вертолёт старается летать точно по вершинам пути. При желании можно сделать ювелирный пролёт под мостом.
Вертолёт старается летать как можно быстрее. Пояснение: если ему задать, что в следующей вершине пути он должен иметь скорость 10 м/с, а его максимальная скорость установлена в 30 м/с, то он не станет сразу лететь 10 м/с. Он сначала будет разгоняться вплоть до 30 м/с и только на подлёте к целевой вершине начнёт тормозить с расчётом прибыть в неё имея 10 м/с.
Если в вершине пути path_move задан набор флажков, то вертолёт будет смотреть в любую из вершин path_look, в которых задан такой же набор флажков. Поворачиваться к этой точке вертолёт начнёт с предыдущей вершины пути. На данном этапе вертолет не может, зависнув в одном месте, смотреть поочередно в несколько точек path_look
Вкл/выкл звук двигателя вертолёта.
Неуязвимость. Если true, вертолёт игнорирует все хиты.
Бессмертие. Если true, вертолёт получает повреждения, но не умирает.
Отключает универсальные реплики пилотов вертолета.
Задержака между пусками ракет. По дефолту берется из ltx (сейчас 1250 мсек)
Параметры, задаваемые в именах вершин пути path_move:
Параметры, задаваемые в именах вершин пути path_look:
«w» – см. такой же параметр для пути path_move.
Вертолёт не видит никого. Узнать о враге вертолёт может только при получении хита или из параметра в custom data.
Вертолёт стреляет по врагу, если видит его. Если не видит – ищет, облетая вокруг точки, где последний раз видел. Если долго не видит врага – забывает его. Если врага задали принудительно из текущей секции схемы поведения, то он не забудет его, пока находится в этой секции.
Отдельной секции для этой схемы поведения нет. Поэтому настройки производятся в секции текущей схемы поведения:
combat_ignore = true/falsetrue означает игнорирование получения хита. Т.е. вертолёт не будет пытаться «отомстить» тому, от кого он получил хит.
combat_enemy = nil/actor/StoryIDС помощью этого параметра можно задать вертолёту конкретного врага. nil – нету врага; actor – игрок; SID – числовое story id врага.
combat_use_rocket = true/falseМожно ли вертолёту пользоваться рокетами.
combat_use_mgun = true/falseМожно ли вертолёту пользоваться пулемётом.
combat_velocity = Скорсть, с которой вертолет будет делать боевые заходы
К вертолёту подключена схема xr_hit. Работает как у сталкеров. В xr_effects есть группа функций для работы с вертолётом из его custom data:
3.13. Meet_manager
[meet]
meet_state = 30| state@sound| 20| state@sound| 10| state@sound
meet_state_wpn = 30| state@sound| 20| state@sound| 10| state@sound
victim = 30| nil| 20| actor
victim_wpn = 30| nil| 20| actor
use = self
use_wpn = false
zone = name| state@sound
meet_dialog = dialog_id
synpairs = state@sound|state@sound
abuse = true/false
Вся настройка встречи отныне будет производится в отдельной секции. В секции logic или в текущей схеме можно будет указать, какую именно секцию с настройкой нужно использовать. Секция, которая указана в секции logic будет влиять на обработку встречи свободногулящим сталкером.
Перечень полей:
meet_state, meet_state_wpn – задает анимацию и озвучку персонажа, в зависимости от расстояния до актера. Для случая если актер безоружен либо вооружен соответственно.
victim, victim_wpn – задает объект, на который должен будет смотреть персонаж. Возможные параметры: nil – никуда не смотрит, actor – смотрит на игрока, story_id – номер стори айди персонажа, на которого нужно будет смотреть.
use, use_wpn – настройки юзабельности персонажа. Возможны три варианта: true, false, self. При self НПС сам юзнет игрока, как только сможет дотянуться
zone – Содержит набор имен рестрикторов, а также анимаций и озвучки, которую НПС будет отыгрывать, если игрок будет замечен в рестрикторе
meet_dialog – стартовый диалог НПС.
synpairs – cодержит набор пар состояние_тела@звуковая_тема. Если при каком то наборе условий встреча будет отыгрывать именно это состояние и эту звуковую тему – то они будут синхронизироваться по рандомным анимациям состояния тела.
аbuse – по умолчанию true, если false, то неюзающийся противник не будет обижаться.
Любую строку(в общей схеме они написаны строчными буквами) можно задавать кондлистом. ( <+info1 –info2>ward %+info% )
Для облегчения настройки встречи сделана возможность упрощенного задания дефолта:
Саму секцию [default_meet] задавать не надо. Все настройки и так возьмутся из дефолта.
Теперь о том, как с помощью этого конструктора собрать ту реакцию на актера, которая вам нужна (Во всех примерах зеленым цветом выделены состояния state_manager, синим – звуковые темы):
Ситуация 1
[meet]
meet_state = 50| hello@talk_hello| 20| wait@wait| 10| ward@wait
meet_state_wpn = 50| hello@talk_hello| 20| threat@threat_weap
victim = 50| actor
victim_wpn = 50| actor
use = true
use_wpn = false
Ситуация 2
[meet]
meet_state = 50| <+info>threat_fire %=killactor%, walk@ <+info>talk_abuse, wait | 10 | walk %+info%; wait | 2 | threat;state
meet_state_wpn = 50| <+info>threat_fire %=killactor%, threat@ <+info>talk_abuse, wait
victim = 50| actor
victim_wpn = 50| actor
use = <-info2>self, false
use_wpn = false
Ситуация 3
Персонаж ходит по патрульному пути на заставе лагеря. Если игрок имеет допуск в лагерь – пропускает его и здоровается, иначе сперва отпугивает, а если игрок пробрался в лагерь – то обижается на него. При этом диалог зависит от того, имеет игрок допуск в лагерь или нет.
[camper]
path_walk = path_walk
path_look = path_look
meet = meet
[meet]
meet_state = 30| <+info>wait, threat@ <+info>talk_hello, threat_back
meet_state_wpn = 30| <+info>wait, threat@ <+info>talk_hello, threat_back
victim = 30| actor
victim_wpn = 30| actor
use = true
use_wpn = true
zone = warnzone| <-info>threat@ <-info>threat_back|kampzone| <-info>true@ <-info>talk_abuse
meet_dialog = <+info>dialog1, dialog2
Здесь:
True – вместо анимации, атаковать игрока.
Info – Инфопоршн, который говорит что мы имеем допуск к лагерю
Warnzone – рестриктор, в котором нас предупреждают
Kampzone – рестриктор, в котором нас убивают
Dialog1 – стартовый диалог НПС, если мы имеем допуск в лагерь
Dialog2 – стартовый диалог НПС, если мы не имеем допуск в лагерь.
Дефолтные настройки:
По дефолту встреча настроена со следующими параметрами:
meet_state = 30|hello@hail|20|wait@wait
meet_state_wpn = 30|backoff@threat_weap
victim = 30|actor
victim_wpn = 30|actor
use = true
use_wpn = false
syndata = hello@hail|backoff@threat_weap
NB: Если нужно, чтобы сталкер не разговаривал с игроком в данной секции, необходимо прописать ему meet = no_meet
3.14. Отметки на минимапе
Появилась возможность не показывать сталкеров на минимапе и на карте (прятать синие и красные точки). Для этого в секции логики или в текущей схеме указываем параметр:
[camper]
show_spot = false (будучи в этой секции сталкер не показывается на карте)
Сталкер не будет показываться, если у игрока есть инфопоршн info1 и т.д.
3.15. Передача параметров в функции.
Ниже перечислен набор функций к которым можно обращаться из кастом даты и при этом передавать в них переменные.
NB! Во всех функциях xr_conditions и xr_effects, которые обращались к гулагам по имени, теперь можно использовать как имя, так и story id. Причем если мы указываем имя, то использовать функцию можно только, когда гулаг находится в онлайне, а если мы вешаем на самрттеррейн story_id, то можем обращаться к гулагу и в оффлайне.
Новый принцип создания звуковых групп: 3.16. Настройка звуковых групп.
1. Каждый персонаж по умолчанию считается находящимся в уникальной саундгруппе.
2. Для того, чтобы объеденить нескольких персонажей в единую саундгруппу, необходимо в секции логики прописать soundgroup =
Звуковые группы должны быть уникальными в пределах уровня, а еще лучше в пределах всей игры. Для этого указывайте в звуковой группе идентификатор уровня и сценки, например:
soundgroup = bar_dolg_kampfire1
3. Объеденять в звуковые группы необходимо персонажей сидящих в кемпе и идущих в патрулях. А также при других схожих ситуациях.
4. Дабы избежать ошибок при обижании, наподобие той, которая сейчас проявляется в лагере на эксейпе, необходимо чтобы все НПС, логически относящиеся к одному лагерю имели одинаковый team, squad, group
Пример:
[kamp@esc_bridge_post1]
center_point = kamp_point
soundgroup = esc_bridge_soldiers