На многих форумах, часто задают такой вопрос "Как перевести нпс в offline, а затем в online, через скрипт?". Но вразумительного ответа, так нигде и не дают. Перечисляют множество возможных операторов перевода, но при этом сами не уверены, работают они или нет. Просмотрев уже существующие скрипты, нашёл нужные операторы перевода мобов в offline-online.
Итак. Вот сами операторы перевода:
alife():set_switch_offline (id, value) alife():set_switch_online (id, value) alife():set_interactive (id, value)
Есть условие их использования. Данные операторы должны использоваться только вместе. Правда зачем нужен оператор set_interactive, я не в курсе. Вроде и без него работает. Но в оригинальных скриптах он везде используется, поэтому я его не стал исключать.
Перевод в offline:
Например, у нас есть уникальный нпс, которого нужно перевести в offline. Первое, что нам нужно сделать, это определить его id. Не sid из файла game_story_ids.ltx, а id объекта. Некоторые причисляют их к одному и тому же параметру. Хотя это не так. Sid -это принудительно-зарегистрированный ключ инициализации объекта, для управления объектом в не зависимости от того, где он находится. Id -это порядковый номер объекта, который задаётся автоматически, при спавне. Определение id может быть разнообразным. Всё зависит от ситуации и откуда наша функция будет вызываться. Но в любом случае, определение id объекта производится через его userdata. Если наша функция будет вызываться из логики нпс, то userdata объекта будет передаваться в функцию автоматически. Главное правильно задать переменную в скобках наименования функции:
function name(actor, npc) ... end
Где, actor и npc -переменные содержащие userdata актора и непися, с логики которого данная функция вызывается, соответственно. Нужно всегда помнить, что в данной ситуации, первая переменная содержит userdata актора, а вторая userdata непися. При этом, наименования переменных могут быть произвольными. Главное соблюдать порядок наименования. Чтобы в данной ситуации определить его id, не потребуется писать никаких действий, достаточно прописать определение id объекта, в том месте, где должно прописываться его id:
npc:id()
Если наша функция будет вызываться не из логики, а например из скрипта, где при определённых условиях, определённый непись будет переводиться в offline, нам понадобится его sid, через который мы и определим его userdata. Есть два способа определения userdata через sid. Первый способ, это определение через функцию level_object_by_sid():
local npc = level_object_by_sid( sid объекта )
Второй способ, это определение через alife():
local npc = alife():story_object( sid объекта )
При этом, первый способ срабатывает значительно быстрее, так как поиск объекта производится из списка объектов, находящихся в online. А, второй способ производит поиск объекта из списка всех объектов находящихся в игре. Предпочтительно, конечно, использовать второй способ, так как при первом способе придётся писать дополнительные действия, для защиты от error, когда нпс будет и так находиться в offline. Но у второго способа есть одно отличие от стандарта. Id объекта придётся определять не через функцию id(), а через его переменную id:
npc.id
Итак. Вроде как определились с данными id. Теперь создадим саму функцию перевода нпс в offline.
Для вызова функции из логики нпс:
function name(actor, npc) if npc then alife():set_switch_offline (npc:id(), true) alife():set_switch_online (npc:id(), false) alife():set_interactive (npc:id(), false) end end
Для вызова функции из другого скрипта, будет выглядеть так (если userdata не определена):
function name() local npc = alife():story_object( sid объекта ) if npc then alife():set_switch_offline (npc.id, true) alife():set_switch_online (npc.id, false) alife():set_interactive (npc.id, false) end end
Перевод в online:
Для перевода в online действуют те же условия. С некоторыми отличиями. Первый способ определения userdata через sid, не допустим. Так как данный оператор действителен, только если объект находится в online. В любом другом случае, он выдаст ошибку. И конечно же, когда нпс находится в offline, логика на него не может быть воздействована, поэтому остаётся только вызов функции из другого скрипта.
Итак, функция перевода нпс в online:
Для вызова функции из другого скрипта,(если userdata не определена):
function name() local npc = alife():story_object( sid объекта ) if npc then alife():set_switch_offline (npc.id, false) alife():set_switch_online (npc.id, true) alife():set_interactive (npc.id, true) end end
Переводы в offline и в online производится независимо от того, где находится актор, хоть нос к носу с переводимым нпс. Есть одно ограничение. Если в логике нпс, хоть где-то указано постоянное нахождение в online, то перевод его в offline будет не возможен, пока данное указание не будет снято.
Автор статьи Singapur22
Работа в offline и online
Начало
Начнем! Распакуем all.spawn и откроем файл alife_l06_rostok.ltx. В нём найдём такие строчки:
[3851] ; cse_abstract properties section_name = stalker name = bar_freedom_attacker_1 position = -214.942504882813,-2.09808349609375e-005,164.513900756836 direction = 0,0,0
; cse_alife_trader_abstract properties money = 5000 character_profile = bar_Killer_regular
; cse_alife_object properties game_vertex_id = 1335 distance = 6.29999971389771 level_vertex_id = 23441 object_flags = 0xffffffff custom_data = <<END [spawner] cond = {+bar_heli_scene_stay_online}
[smart_terrains] bar_freedom_attack = true END
; cse_visual properties visual_name = actors\killer\stalker_ki_mask
; cse_alife_creature_abstract properties g_team = 0 g_squad = 5 g_group = 7 health = 1 dynamic_out_restrictions = dynamic_in_restrictions =
upd:health = 1 upd:timestamp = 0 upd:creature_flags = 0 upd:position = -214.942504882813,-2.09808349609375e-005,164.513900756836 upd:o_model = 0 upd:o_torso = 0,0,0 upd:g_team = 0 upd:g_squad = 5 upd:g_group = 7
; 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 = 0,1,2,0,2 predicate4 = 0,1,1,0
; cse_ph_skeleton properties
upd:start_dialog =
; se_stalker properties
В этой писанине нам нужно только это:
[spawner] cond = {+bar_heli_scene_stay_online}
Это переход НПС в онлайн при выдаче инфопоршня. Чтбы убедится в этом найдём его в info_l07rostok.xml. Убедились? Отлично! Двигаемся дальше. Вместо знака + вы можете поставить знак -. Значит при этом инфопоршне НПС уйдет в оффлайн.
Можно менять эти инфопоршны на любые другие, в том числе свои. Теперь поменяем его к примеру на bar_kruglov_follow_tunnel. В итоге:
[spawner] cond = {+bar_kruglov_follow_tunnel}
Этот НПС (или несколько неписей) буду рождаться, когда вы пройдете через туннель, где наёмники-снайперы. Все инфопоршны брать из файла, соответствующего локации. Вы можете сделать свой квест и применить инфопоршы к этому делу. [править] P.S.
Теперь сделаем, чтобы всё до конца работало. Найдём смарт_террейн, в котором прописан +bar_heli_scene_stay_online. И допишем туда свой.
[3857] ; cse_abstract properties section_name = smart_terrain name = bar_ecolog_crush position = -294.061706542969,7.43865966796875e-005,140.005218505859 direction = 1.01860559880151e-005,-7.54995954643789e-010,7.41205367376097e-005
; cse_alife_object properties game_vertex_id = 1350 distance = 2.79999995231628 level_vertex_id = 100 object_flags = 0xffffffbe custom_data = <<END [smart_terrain] type = bar_ecolog_crush capacity = 5 squad = 5 groups = 1,2 cond = {+bar_heli_scene_stay_online},{+bar_kruglov_follow_tunnel} END
; cse_shape properties shapes = shape0 shape0:type = sphere shape0:offset = 0,0,0 shape0:radius = 2.66736793518066
; cse_alife_space_restrictor properties restrictor_type = 0
; se_smart_terrain properties
Вот он. Вот и всё!
|