SoC. Смартеррейны и гулаги — различия между версиями
Материал из S.T.A.L.K.E.R. Inside Wiki
RedPython (обсуждение | вклад) м («Смартеррейны и гулаги» переименована в «SoC. Смартеррейны и гулаги»: prefix) |
|||
(не показаны 22 промежуточных версий 5 участников) | |||
Строка 1: | Строка 1: | ||
− | В последнее время люди постоянно меня спрашивали как создать скрипт гулага для смартеррейнов. Чтобы постоянно не отвечать на каждое отдельное письмо, я решил написать небольшой тутор. Прежде чем начать, хотелось бы предупредить, что не являюсь экспертом в подобного рода вещах и некоторые моменты мне всё еще не ясны до конца, так что вероятно я не смогу объяснить всё правильно. Также я буду использовать ST как абревиатуру смартеррейна. Этот тутор посвящен НПС в ST, но он также сгодится и для мутантов. Предполагаю что вы знакомы с: | + | В последнее время люди постоянно меня спрашивали как создать скрипт гулага для смартеррейнов. Чтобы постоянно не отвечать на каждое отдельное письмо, я решил написать небольшой тутор. Прежде чем начать, хотелось бы предупредить, что не являюсь экспертом в подобного рода вещах и некоторые моменты мне всё еще не ясны до конца, так что вероятно я не смогу объяснить всё правильно. Также я буду использовать ST как абревиатуру смартеррейна. Этот тутор посвящен НПС в ST, но он также сгодится и для мутантов. Предполагаю что вы знакомы с:<br> |
− | - луа программированием | + | - луа программированием<br> |
− | - редактированием all.spawn | + | - редактированием all.spawn<br> |
− | - работа с вейпоинтами(патрульными путями) | + | - работа с вейпоинтами(патрульными путями)<br> |
- утилитами аи | - утилитами аи | ||
Строка 12: | Строка 12: | ||
<ini> | <ini> | ||
[2515] | [2515] | ||
− | ; cse_abstract properties | + | ; cse_abstract properties (основные параметры) |
section_name = smart_terrain | section_name = smart_terrain | ||
name = esc_bandits_smart_terrain | name = esc_bandits_smart_terrain | ||
Строка 18: | Строка 18: | ||
direction = 0,0,0 | direction = 0,0,0 | ||
− | ; cse_alife_object properties | + | ; cse_alife_object properties (параметры объекта) |
game_vertex_id = 635 | game_vertex_id = 635 | ||
distance = 9.09999942779541 | distance = 9.09999942779541 | ||
Строка 33: | Строка 33: | ||
END | END | ||
− | ; cse_shape properties | + | ; cse_shape properties (параметры шейпа объекта) |
shapes = shape0 | shapes = shape0 | ||
shape0:type = sphere | shape0:type = sphere | ||
Строка 39: | Строка 39: | ||
shape0:radius = 20.55957102775574 | shape0:radius = 20.55957102775574 | ||
− | ; cse_alife_space_restrictor properties | + | ; cse_alife_space_restrictor properties (параметры рестриктора) |
restrictor_type = 3 | restrictor_type = 3 | ||
− | ; se_smart_terrain properties | + | ; se_smart_terrain properties (параметры смарттеррейна) |
</ini> | </ini> | ||
Строка 57: | Строка 57: | ||
− | '''type''' название вашего нового ST(обязательно) | + | '''type''' название вашего нового ST(обязательно)<br> |
− | '''cond''' описывает условия, которые необходимы для | + | '''cond''' описывает условия, которые необходимы для включения гулага(по желанию)<br> |
− | '''capacity''' количество мутантов/нпс, которое может вместить смарттеррейн(обязательно) | + | '''capacity''' количество мутантов/нпс, которое может вместить смарттеррейн(обязательно)<br> |
− | '''squad, groups''' - номер сквада и количество групп(по желанию) | + | '''squad, groups''' - номер сквада и количество групп(по желанию)<br> |
− | '''respawn''' название тайника(синяя коробка) куда будут спавниться предметы, когда мы вызовем респавн в ST.(по желанию) | + | '''respawn''' название тайника(синяя коробка) куда будут спавниться предметы, когда мы вызовем респавн в ST.(по желанию)<br> |
− | + | ||
− | + | ||
2. Спавн нпс/мутантов и назначение(биндинг) их к нашему ST: для этого мы должны добавить каждому мутанту/нпс определенную логику: | 2. Спавн нпс/мутантов и назначение(биндинг) их к нашему ST: для этого мы должны добавить каждому мутанту/нпс определенную логику: | ||
Строка 74: | Строка 72: | ||
</ini> | </ini> | ||
− | .. | + | Если таковых нпс не обнаружится то гулаг выберет себе население из числа заспавнившихся в Зоне нпс с подходящими параметрами. |
+ | Даже если они на другой локации. | ||
− | 3. | + | 3. Добавляем "работу" (логика) для каждого нпс/мутанта из нашего ST(для каждого состояния). Предположии у ST их два: состояние 0 (описывает какие нпс/мутанты "работают" днем) и состояние 1 (ночью). У нас 3 бандита, определяемся: |
− | - bandit1: walker ( | + | - bandit1: walker (состояние 0) и kamp (состояние 1)<br> |
− | - bandit2: guard ( | + | - bandit2: guard (состояние 0) и sleeper (состояние 1)<br> |
− | - bandit3: walker ( | + | - bandit3: walker (состояние 0 и 1 <= он делает тоже и днём, и ночью)<br> |
− | + | У нас есть 3 способа добавить логику (работу) для каждого нпс/мутанта, мы будем использовать наиболее общепринятый способ, добавим логику в фаил config\misc\gulag_escape.ltx. Она должна выглядеть примерно так: | |
<ini> | <ini> | ||
− | ;-- bandit1 (walker -> | + | ;-- bandit1 (walker(прогуливающийся) -> состояние 0, днем) |
[logic@esc_bandits_smart_terrain_bandit1_walker] | [logic@esc_bandits_smart_terrain_bandit1_walker] | ||
active = walker@esc_bandits_smart_terrain_bandit1 | active = walker@esc_bandits_smart_terrain_bandit1 | ||
Строка 97: | Строка 96: | ||
meet = no_meet | meet = no_meet | ||
− | ;-- bandit1 (kamp -> | + | ;-- bandit1 (kamp(лагерь) -> состояние 1, ночью) |
[logic@esc_bandits_smart_terrain_bandit1_kamp] | [logic@esc_bandits_smart_terrain_bandit1_kamp] | ||
active = kamp@esc_bandits_smart_terrain_bandit1 | active = kamp@esc_bandits_smart_terrain_bandit1 | ||
Строка 105: | Строка 104: | ||
path_walk = bandit_kamp_task | path_walk = bandit_kamp_task | ||
− | ;-- bandit2 (guard -> | + | ;-- bandit2 (guard(охранник) -> состояние 0, днем) |
[logic@esc_bandits_smart_terrain_bandit2_walker] | [logic@esc_bandits_smart_terrain_bandit2_walker] | ||
active = walker@esc_bandits_smart_terrain_bandit2 | active = walker@esc_bandits_smart_terrain_bandit2 | ||
Строка 114: | Строка 113: | ||
danger = danger_condition@esc_bandits_smart_terrain | danger = danger_condition@esc_bandits_smart_terrain | ||
− | ;-- bandit2 (sleeper -> | + | ;-- bandit2 (sleeper(спящий) -> состояние 1, ночью) |
[logic@esc_bandits_smart_terrain_bandit2_sleeper] | [logic@esc_bandits_smart_terrain_bandit2_sleeper] | ||
active = sleeper@esc_bandits_smart_terrain_bandit2 | active = sleeper@esc_bandits_smart_terrain_bandit2 | ||
Строка 122: | Строка 121: | ||
wakeable = false | wakeable = false | ||
− | ;-- bandit3 (guard -> | + | ;-- bandit3 (guard -> состояние 0 и 1, днем/ночью) |
[logic@esc_bandits_smart_terrain_bandit3_walker] | [logic@esc_bandits_smart_terrain_bandit3_walker] | ||
active = walker@esc_bandits_smart_terrain_bandit3 | active = walker@esc_bandits_smart_terrain_bandit3 | ||
Строка 135: | Строка 134: | ||
</ini> | </ini> | ||
− | 4. | + | 4. Теперь нам нужно заскриптовать наш ST. Так что добавим наш код в фаил скрипта \gulag_escape.script. Есть еще несколько моментов, которые мы должны здесь доделать (каждый из этих шагов обязателен): |
− | - | + | - грузим логику (работу) для каждого нпс/мутанта и для каждого состояния -> function load_job(...) |
<lua> | <lua> | ||
if type == "esc_bandits_smart_terrain" then | if type == "esc_bandits_smart_terrain" then | ||
t = {} | t = {} | ||
− | ;-- | + | ;-- "соеденительная секция" для логики, определяем ltx фаилом |
t.section = "logic@esc_bandits_smart_terrain_bandit1_walker" | t.section = "logic@esc_bandits_smart_terrain_bandit1_walker" | ||
;-- no idea, probably describes after what time | ;-- no idea, probably describes after what time | ||
Строка 149: | Строка 148: | ||
;-- no idea but i guess it's optional | ;-- no idea but i guess it's optional | ||
t.timeout = 0 | t.timeout = 0 | ||
− | ;-- | + | ;-- пріоритет |
t.prior = 100 | t.prior = 100 | ||
− | ;-- | + | ;-- нпс будет использовать эту логику, |
− | ;-- | + | ;-- если ST переключится в это состояние |
+ | ;-- в этом случае - состояние 0 (день) | ||
t.state = {0} | t.state = {0} | ||
− | ;-- | + | ;-- Какой squad и group назначится персонажу принявшему эту работу. |
t.squad = squad | t.squad = squad | ||
t.group = groups[1] | t.group = groups[1] | ||
;-- no idea what means position_threshold | ;-- no idea what means position_threshold | ||
t.position_threshold = 100 | t.position_threshold = 100 | ||
− | ;-- | + | ;-- описывает нпс в этом состоянии: онлайн или офлайн |
− | ;-- | + | ;-- онлайн = истина по дефолту |
t.online = true | t.online = true | ||
− | ;-- | + | ;-- описывает рестрикторы (куда нпс могут/не могут пойти) |
t.in_rest = "" | t.in_rest = "" | ||
t.out_rest = "" | t.out_rest = "" | ||
− | + | ;-- ввиду особого способа присвоения работ в | |
− | + | ;-- smart_terrain.script вы никогда не знаете, какая работа | |
− | ;-- | + | ;-- будет использоваться каждым нпсом; если вы хотите быть уверенным |
− | ;-- | + | ;-- что конкретный нпс взял конкретную работу, тогда |
− | ;-- | + | ;-- вам нужно заюзать предикатную функцию; в этом слуае |
− | ;-- | + | ;-- мы хотим чтобы эта работа присвоилась мастеру бандиту |
t.predicate = function(obj_info) return obj_info.rank >= 900 end | t.predicate = function(obj_info) return obj_info.rank >= 900 end | ||
table.insert(sj, t) | table.insert(sj, t) | ||
Строка 180: | Строка 180: | ||
table.insert(sj, t) | table.insert(sj, t) | ||
− | ;-- bandit2 -> | + | ;-- bandit2 -> состояние 0 (день) |
t = {section = "logic@esc_bandits_smart_terrain_bandit2_walker", | t = {section = "logic@esc_bandits_smart_terrain_bandit2_walker", | ||
idle = 0, prior = 5, state = {0}, squad = squad, group = groups[1], | idle = 0, prior = 5, state = {0}, squad = squad, group = groups[1], | ||
Строка 186: | Строка 186: | ||
table.insert(sj, t) | table.insert(sj, t) | ||
− | ;-- bandit2 -> | + | ;-- bandit2 -> состояние 1 (ночь) |
t = {section = "logic@esc_bandits_smart_terrain_bandit2_sleeper", | t = {section = "logic@esc_bandits_smart_terrain_bandit2_sleeper", | ||
idle = 0, prior = 5, state = {1}, squad = squad, group = groups[1], | idle = 0, prior = 5, state = {1}, squad = squad, group = groups[1], | ||
Строка 192: | Строка 192: | ||
table.insert(sj, t) | table.insert(sj, t) | ||
− | ;-- bandit3 -> | + | ;-- bandit3 -> состояние 0 (день) и состояние 1 (ночь) |
t = {section = "logic@esc_bandits_smart_terrain_bandit3_walker", | t = {section = "logic@esc_bandits_smart_terrain_bandit3_walker", | ||
idle = 0, prior = 5, state = {0, 1}, squad = squad, group = groups[1], | idle = 0, prior = 5, state = {0, 1}, squad = squad, group = groups[1], | ||
Строка 200: | Строка 200: | ||
</lua> | </lua> | ||
− | + | Еще один момент о состояниях ST, всё зависит от того сколько у вас их в ST. Еще одна важной вещью является добавление логики для каждого состояния. Например в вашем ST такие состояния: | |
− | 0 - | + | 0 - нпс оффлайн<br> |
− | 1 - | + | 1 - нпс онлайн (день)<br> |
− | 2 - | + | 2 - нпс онлайн (ночь)<br> |
− | 3 - | + | 3 - нпс онлайн, они решили напасть на другой ST<br> |
− | 4 - | + | 4 - нпс онлайн, актор напал на них |
− | + | К сведению, меня не прет заполнять такое большое количество таблиц, так что обычно я использую эту функцию: | |
<lua> | <lua> | ||
Строка 232: | Строка 232: | ||
</lua> | </lua> | ||
− | + | Используя функцию выше, мы можем загружать логику наподобие этой: | |
<lua> | <lua> | ||
Строка 255: | Строка 255: | ||
</lua> | </lua> | ||
− | - | + | - автоматически изменяем работу для каждого нпс/мутанта -> function load_states(...) |
<lua> | <lua> | ||
Строка 264: | Строка 264: | ||
end | end | ||
if level.get_time_hours() >= 5 and level.get_time_hours() <= 22 then | if level.get_time_hours() >= 5 and level.get_time_hours() <= 22 then | ||
− | + | return 0 -- переключает всех мутантов/нпс на дневную работу | |
else | else | ||
− | return 1 -- | + | return 1 -- ереключает всех мутантов/нпс на ночную работу |
end | end | ||
end | end | ||
Строка 272: | Строка 272: | ||
</lua> | </lua> | ||
− | - | + | - убедитесь что наш ST будет использоваться только для бандитов -> function checkStalker(...) |
<lua> | <lua> | ||
Строка 280: | Строка 280: | ||
</lua> | </lua> | ||
− | |||
− | [[ | + | Так же существуют универсальные гулаги General_lager для сталкеров. Они считаются упрощенными гулагами. |
+ | |||
+ | Пример, создаем смарт: | ||
+ | <lua> | ||
+ | [9999] | ||
+ | ; cse_abstract properties (основные параметры) | ||
+ | section_name = smart_terrain | ||
+ | name = esc_gen_lager | ||
+ | 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 = <<END | ||
+ | [smart_terrain] | ||
+ | type = general_lager | ||
+ | capacity = 3 ;вместимость | ||
+ | communities = bandit ; комьюнити населения | ||
+ | END | ||
+ | |||
+ | ; cse_shape properties (параметры шейпа объекта) | ||
+ | shapes = shape0 | ||
+ | shape0:type = sphere | ||
+ | shape0:offset = 0,0,0 | ||
+ | shape0:radius = 20.55957102775574 | ||
+ | |||
+ | ; cse_alife_space_restrictor properties (параметры рестриктора) | ||
+ | restrictor_type = 3 | ||
+ | |||
+ | ; se_smart_terrain properties (параметры смарттеррейна) | ||
+ | </lua> | ||
+ | |||
+ | 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 нужны заранее расставленые точки путей для него. | ||
+ | |||
+ | |||
+ | == Автор == | ||
+ | |||
+ | [[Dez0wave]] | ||
+ | И [[Rez@niy]] | ||
+ | РЕДАКТИРОВАНИЕ | ||
+ | |||
+ | == Перевод == | ||
+ | [[Loxotron]] | ||
+ | |||
+ | == Дополнял == | ||
+ | [[IamFarsight]] | ||
==Ссылки== | ==Ссылки== | ||
− | + | [http://www.gsc-game.com/main.php?t=community&s=forums&s_game_type=xr&thm_page=77&thm_id=14712&sec_id=16&page=1#199726 Обсуждение тут] | |
− | http://www.gsc-game.com/main.php?t=community&s=forums&s_game_type=xr&thm_page=77&thm_id=14712&sec_id=16&page=1#199726 | + | |
Используйте нашу утилиту для дебаггинга смартеррейнов и экспорта вейпоинтов: | Используйте нашу утилиту для дебаггинга смартеррейнов и экспорта вейпоинтов: | ||
− | + | [http://sdk.stalker-game.com/ru/images/d/d7/Smartterrain_and_Waypoint_Tools_by_dez0wave.zip Скачать Smartterrain and Waypoint Tools] | |
− | + | [http://ifolder.ru/7179080 Зеркало на всякий случай] | |
− | [[Категория:Скрипты]] | + | [[Категория:A-Life]][[Категория:Скрипты]] |
Текущая версия на 18:16, 15 января 2011
В последнее время люди постоянно меня спрашивали как создать скрипт гулага для смартеррейнов. Чтобы постоянно не отвечать на каждое отдельное письмо, я решил написать небольшой тутор. Прежде чем начать, хотелось бы предупредить, что не являюсь экспертом в подобного рода вещах и некоторые моменты мне всё еще не ясны до конца, так что вероятно я не смогу объяснить всё правильно. Также я буду использовать ST как абревиатуру смартеррейна. Этот тутор посвящен НПС в ST, но он также сгодится и для мутантов. Предполагаю что вы знакомы с:
- луа программированием
- редактированием all.spawn
- работа с вейпоинтами(патрульными путями)
- утилитами аи
В первую очередить подумайте о своём ST, где бы его заспавнить, сколько нпс/мутантов будут в нем выполнять определенную "работу", когда ST должен активироваться/отключаться, сколько и какие состояния будет у вашего ST и тд. Думаю, наиболее эффективный способ объяснить вам как это работает на примере. Давайте предположим.. мы хотим поставить ST(smart terrain) на Кордоне для 3х бандитов.
1. Спавн ST:
[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 = <<END [smart_terrain] type = esc_bandits_smart_terrain cond = {-infoportion} capacity = 3 squad = 1 groups = 5 respawn = esc_respawn_inventory_box_0002 END ; cse_shape properties (параметры шейпа объекта) shapes = shape0 shape0:type = sphere shape0:offset = 0,0,0 shape0:radius = 20.55957102775574 ; cse_alife_space_restrictor properties (параметры рестриктора) restrictor_type = 3 ; se_smart_terrain properties (параметры смарттеррейна)
Эта наиболее важная часть:
type = esc_bandits_smart_terrain cond = {-infoportion} capacity = 3 squad = 1 groups = 5 respawn = esc_respawn_inventory_box_0002</source>
type название вашего нового ST(обязательно)
cond описывает условия, которые необходимы для включения гулага(по желанию)
capacity количество мутантов/нпс, которое может вместить смарттеррейн(обязательно)
squad, groups - номер сквада и количество групп(по желанию)
respawn название тайника(синяя коробка) куда будут спавниться предметы, когда мы вызовем респавн в ST.(по желанию)
2. Спавн нпс/мутантов и назначение(биндинг) их к нашему ST: для этого мы должны добавить каждому мутанту/нпс определенную логику:
custom_data = <<END [smart_terrains] esc_bandits_smart_terrain = true END
Если таковых нпс не обнаружится то гулаг выберет себе население из числа заспавнившихся в Зоне нпс с подходящими параметрами. Даже если они на другой локации.
3. Добавляем "работу" (логика) для каждого нпс/мутанта из нашего ST(для каждого состояния). Предположии у ST их два: состояние 0 (описывает какие нпс/мутанты "работают" днем) и состояние 1 (ночью). У нас 3 бандита, определяемся:
- bandit1: walker (состояние 0) и kamp (состояние 1)
- bandit2: guard (состояние 0) и sleeper (состояние 1)
- bandit3: walker (состояние 0 и 1 <= он делает тоже и днём, и ночью)
У нас есть 3 способа добавить логику (работу) для каждого нпс/мутанта, мы будем использовать наиболее общепринятый способ, добавим логику в фаил config\misc\gulag_escape.ltx. Она должна выглядеть примерно так:
;-- bandit1 (walker(прогуливающийся) -> состояние 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 ;-- bandit1 (kamp(лагерь) -> состояние 1, ночью) [logic@esc_bandits_smart_terrain_bandit1_kamp] active = kamp@esc_bandits_smart_terrain_bandit1 [kamp@esc_bandits_smart_terrain_bandit1] center_point = bandit_kamp path_walk = bandit_kamp_task ;-- bandit2 (guard(охранник) -> состояние 0, днем) [logic@esc_bandits_smart_terrain_bandit2_walker] active = walker@esc_bandits_smart_terrain_bandit2 [walker@esc_bandits_smart_terrain_bandit2] path_walk = bandit2_walk path_look = bandit2_look danger = danger_condition@esc_bandits_smart_terrain ;-- bandit2 (sleeper(спящий) -> состояние 1, ночью) [logic@esc_bandits_smart_terrain_bandit2_sleeper] active = sleeper@esc_bandits_smart_terrain_bandit2 [sleeper@esc_bandits_smart_terrain_bandit2] path_main = bandit2_sleep wakeable = false ;-- bandit3 (guard -> состояние 0 и 1, днем/ночью) [logic@esc_bandits_smart_terrain_bandit3_walker] active = walker@esc_bandits_smart_terrain_bandit3 [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. Есть еще несколько моментов, которые мы должны здесь доделать (каждый из этих шагов обязателен):
- грузим логику (работу) для каждого нпс/мутанта и для каждого состояния -> function load_job(...)
if type == "esc_bandits_smart_terrain" then t = {} ;-- "соеденительная секция" для логики, определяем ltx фаилом t.section = "logic@esc_bandits_smart_terrain_bandit1_walker" ;-- no idea, probably describes after what time ;-- npc will use this job again (?) t.idle = 0 ;-- no idea but i guess it's optional t.timeout = 0 ;-- пріоритет t.prior = 100 ;-- нпс будет использовать эту логику, ;-- если ST переключится в это состояние ;-- в этом случае - состояние 0 (день) t.state = {0} ;-- Какой squad и group назначится персонажу принявшему эту работу. t.squad = squad t.group = groups[1] ;-- no idea what means position_threshold t.position_threshold = 100 ;-- описывает нпс в этом состоянии: онлайн или офлайн ;-- онлайн = истина по дефолту t.online = true ;-- описывает рестрикторы (куда нпс могут/не могут пойти) t.in_rest = "" t.out_rest = "" ;-- ввиду особого способа присвоения работ в ;-- smart_terrain.script вы никогда не знаете, какая работа ;-- будет использоваться каждым нпсом; если вы хотите быть уверенным ;-- что конкретный нпс взял конкретную работу, тогда ;-- вам нужно заюзать предикатную функцию; в этом слуае ;-- мы хотим чтобы эта работа присвоилась мастеру бандиту t.predicate = function(obj_info) return obj_info.rank >= 900 end table.insert(sj, t) t = {section = "logic@esc_bandits_smart_terrain_bandit1_kamp", idle = 0, timeout = 0, prior = 100, state = {1},squad = squad, 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) ;-- bandit2 -> состояние 0 (день) t = {section = "logic@esc_bandits_smart_terrain_bandit2_walker", idle = 0, prior = 5, state = {0}, squad = squad, group = groups[1], in_rest = "", out_rest = ""} table.insert(sj, t) ;-- bandit2 -> состояние 1 (ночь) t = {section = "logic@esc_bandits_smart_terrain_bandit2_sleeper", idle = 0, prior = 5, state = {1}, squad = squad, group = groups[1], in_rest = "", out_rest = ""} table.insert(sj, t) ;-- bandit3 -> состояние 0 (день) и состояние 1 (ночь) t = {section = "logic@esc_bandits_smart_terrain_bandit3_walker", idle = 0, prior = 5, state = {0, 1}, squad = squad, group = groups[1], in_rest = "", out_rest = ""} table.insert(sj, t) end
Еще один момент о состояниях ST, всё зависит от того сколько у вас их в ST. Еще одна важной вещью является добавление логики для каждого состояния. Например в вашем ST такие состояния:
0 - нпс оффлайн
1 - нпс онлайн (день)
2 - нпс онлайн (ночь)
3 - нпс онлайн, они решили напасть на другой ST
4 - нпс онлайн, актор напал на них
К сведению, меня не прет заполнять такое большое количество таблиц, так что обычно я использую эту функцию:
function fill_tbl(section, idle, prior, states, squad, group, in_rest, out_rest, online, gulag_name) local tbl = {} tbl.section = "logic@" .. gulag_name .. "_" .. section tbl.idle = idle tbl.prior = prior tbl.state = {} 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
- автоматически изменяем работу для каждого нпс/мутанта -> function load_states(...)
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() <= 22 then return 0 -- переключает всех мутантов/нпс на дневную работу else return 1 -- ереключает всех мутантов/нпс на ночную работу end end end
- убедитесь что наш ST будет использоваться только для бандитов -> 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 ; cse_alife_object properties (параметры объекта) game_vertex_id = 635 distance = 9.09999942779541 level_vertex_id = 363757 object_flags = 0x==3e custom_data = <<END [smart_terrain] type = general_lager capacity = 3 ;вместимость communities = bandit ; комьюнити населения END ; cse_shape properties (параметры шейпа объекта) shapes = shape0 shape0:type = sphere shape0:offset = 0,0,0 shape0:radius = 20.55957102775574 ; cse_alife_space_restrictor properties (параметры рестриктора) restrictor_type = 3 ; se_smart_terrain properties (параметры смарттеррейна)
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 нужны заранее расставленые точки путей для него.
Содержание
Автор
Dez0wave И Rez@niy РЕДАКТИРОВАНИЕ
Перевод
Дополнял
Ссылки
Используйте нашу утилиту для дебаггинга смартеррейнов и экспорта вейпоинтов: