denis2000 932 Опубликовано 5 часов назад (изменено) Поиск укрытий от выбросов Во время работы над модом Отступник, я задумался о том, что Главный Герой, а точнее его КПК, прекрасно знает о всех укрытиях от выбросов на всех локациях. Как мне кажется, такая ситуация не очень-то реалистична, ведь как правило, Зона отчуждения для персонажа игры или мода - это Терра инкогнито, а стало быть ему (и нам как игрокам) необходимо ее исследовать и узнавать о ней от более сведущих людей (НПС). Подумав так, я решил реализовать такую концепцию: 1. Главный Герой знает на каждой локации по два-три очевидных укрытия, например на известных базах дружественных/нейтральных НПС. 2. Главный Герой может в процессе исследования локации находить места пригодные для укрытия и отмечать их координаты в своем КПК. 3. Главный Герой может в процессе диалога с дружественным/нейтральным НПС выяснить координаты ближайшего не известного ему убежища. Итак, приступим: Спойлер Прежде всего в секции укрытия есть параметр condlist - если он равен true, то укрытие известно/доступно для укрытия там ГГ, это активно использовалось и в оригинальной игре. Теперь если добавить в условие инфопорцию в формате surge_section_name_known, где surge_section_name соответсвенно имя рестриктора укрытия в all.spawn и по совместительству имя секции из surge_manager.ltx, то получим контроль над тем известно ли ГГ укрытие. Файл surge_manager.ltx [settings] condlist = true survive = {+anabiotic_in_process} true, false [list] ;topi tp_surge_1 tp_surge_2 tp_surge_3 tp_surge_4 tp_surge_5 tp_surge_6 tp_surge_7 tp_surge_8 tp_surge_9 tp_surge_10 tp_surge_11 tp_surge_12 tp_surge_13 tp_surge_14 tp_surge_15 tp_surge_16 tp_surge_17 ;;;-----------------Укрытие известное по умолчанию----------------------------------;;; [known_surge] condlist = true ;;;----Это укрытие требуется обнаружить самому или узнать у НПС---------------------;;; [unknown_surge] condlist = {+surge_section_name_known} true, false ;;;-----------------Условия доступности в ПДА укрытий на локации Топи---------------;;; [tp_surge_1]:known_surge [tp_surge_2] condlist = {+tp_surge_2_known} true, false [tp_surge_3] condlist = {+tp_surge_3_known} true, false [tp_surge_4] condlist = {+tp_surge_4_known} true, false [tp_surge_5] condlist = {+tp_surge_5_known} true, false [tp_surge_6] condlist = {+tp_surge_6_known} true, false [tp_surge_7]:known_surge [tp_surge_8]:known_surge [tp_surge_9]:known_surge [tp_surge_10]:known_surge [tp_surge_11]:known_surge [tp_surge_12]:known_surge [tp_surge_13] condlist = {+tp_surge_13_known} true, false [tp_surge_14] condlist = {+tp_surge_14_known} true, false [tp_surge_15] condlist = {+tp_surge_15_known} true, false [tp_surge_16] condlist = {+tp_surge_16_known} true, false [tp_surge_17] condlist = {+tp_surge_17_known} true, false Теперь для того, чтобы ГГ смог находить такие укрытия добавим следующее. Кастом_дата для рестриктора укрытия от выброса [logic] cfg = scripts\surge_known.ltx Файл scripts\surge_known.ltx [logic] active = sr_idle@wait [sr_idle@wait] on_actor_inside = nil %=give_restrictor_known% Функция для xr_effects.script function give_restrictor_known(actor,restr) if restr then if not has_alife_info(restr:name().."_known") then give_info(restr:name().."_known") news_manager.send_tip(db.actor, "st_surge_hide_known", nil, "recent_surge", nil, nil) end end end Благодаря логике и функции, при заходе ГГ в рестриктор укрытия будет выдана инфопорция surge_section_name_known, а также сообщение об обнаружении укрытия. Правка для news_manager.script tips_icons = { ... recent_surge = "ui_inGame2_V_zone_nedavno_proshel_vibros", ...} Далее работа с динамическим диалогом. Чтобы добавить его всем рандомным НПС отредактируем следующий файл. Файл character_dialogs.xml <start_dialog>hello_dialog</start_dialog> <actor_dialog>dm_universal_dialog</actor_dialog> <actor_dialog>about_surge_hide_dialog</actor_dialog> <actor_dialog>actor_break_dialog</actor_dialog> Или же строку, указанную ниже можно добавить уникальным НПС на ваше усмотрение: <actor_dialog>about_surge_hide_dialog</actor_dialog> Сам диалог формируется, как полностью динамический: <!--------------------------------==================================--------------------------------------------------> <!-------------------------------'Диалог с НПС о ближайших укрытиях'--------------------------------------------------> <!--------------------------------==================================--------------------------------------------------> <dialog id="about_surge_hide_dialog"> <precondition>otstypnik_phrases.about_surge_hide_dialog_precond</precondition> <init_func>otstypnik_phrases.about_surge_hide_dialog</init_func> </dialog> Скрипт работы с диалогом otstypnik_phrases.script. Он содержит не только функции проверки доступности диалога у конкретного НПС и функции формирования собственно самго диалога, но и вспомогательные функции по поиску ближайшего неизвестного укрытия. --------------------------------------------------------------------------------------------------- ---------------------Вспомогательные функции для диалогов об укрытиях------------------------------ --------------------------------------------------------------------------------------------------- local ini = ini_file("misc\\surge_manager.ltx") local count = 0 local covers = {} local loaded = false local restr_name = nil local news_caption = "" function init_surge_covers() for i = 0, ini:line_count("list")-1 do temp1, id, temp2 = ini:r_line("list", i, "", "") local zone = db.zone_by_name[id] if zone ~= nil then count = count + 1 covers[count] = zone if(ini:line_exist(id, "condlist")) then covers[count].condlist = {} covers[count].condlist = xr_logic.parse_condlist(npc, id, "condlist", ini:r_string(id, "condlist")) end end end end function get_nearest_cover() if loaded ~= true then init_surge_covers() loaded = true end local hides = {} utils.copy_table(hides, covers) if(count>0) then for k,v in pairs(hides) do if (v.condlist) then local sect = xr_logic.pick_section_from_condlist(db.actor, nil, v.condlist) if(sect=="true" or sect==nil) then table.remove(hides, k) end end end local nearest_cover_name = nil local nearest_cover_dist = 1000 for k,v in pairs(hides) do local dist = v:position():distance_to(db.actor:position()) if(dist<nearest_cover_dist) then if(v.condlist) then local sect = xr_logic.pick_section_from_condlist(db.actor, nil, v.condlist) if(sect~="true") then nearest_cover_name = v:name() nearest_cover_dist = dist end else nearest_cover_name = v:name() nearest_cover_dist = dist end end end return nearest_cover_name else return nil end end function about_surge_hide_dialog_precond(first_speaker, second_speaker) local npc = dialogs.who_is_npc(first_speaker, second_speaker) return (not npc:has_info("about_surge_hide_dialog_complit")) --return true end function about_surge_hide_dialog_add_info(first_speaker, second_speaker) local npc = dialogs.who_is_npc(first_speaker, second_speaker) npc:give_info_portion("about_surge_hide_dialog_complit") end function speaker_is_stalker(first_speaker, second_speaker) local npc = dialogs.who_is_npc(first_speaker, second_speaker) restr_name = get_nearest_cover() return character_community(npc) == "stalker" end function speaker_is_freedom(first_speaker, second_speaker) local npc = dialogs.who_is_npc(first_speaker, second_speaker) restr_name = get_nearest_cover() return character_community(npc) == "freedom" end function speaker_is_dolg(first_speaker, second_speaker) local npc = dialogs.who_is_npc(first_speaker, second_speaker) restr_name = get_nearest_cover() return character_community(npc) == "dolg" end function speaker_is_bandit(first_speaker, second_speaker) local npc = dialogs.who_is_npc(first_speaker, second_speaker) restr_name = get_nearest_cover() return character_community(npc) == "bandit" end function speaker_is_ecolog(first_speaker, second_speaker) local npc = dialogs.who_is_npc(first_speaker, second_speaker) restr_name = get_nearest_cover() return character_community(npc) == "ecolog" end function speaker_dont_know_surge_hide(first_speaker, second_speaker) return (not speaker_is_stalker(first_speaker, second_speaker)) and (not speaker_is_freedom(first_speaker, second_speaker)) and (not speaker_is_dolg(first_speaker, second_speaker )) and (not speaker_is_bandit(first_speaker, second_speaker )) and (not speaker_is_ecolog(first_speaker, second_speaker )) end function speaker_know_nearest(first_speaker, second_speaker) if restr_name ~= nil then return true end return false end function speaker_dont_know_nearest(first_speaker, second_speaker) if restr_name == nil then return true end return false end function add_nearest_surge_hide() if restr_name ~= nil then give_info(restr_name.."_known") news_caption = game.translate_string("st_surge_hide_given").." "..game.translate_string("st_"..restr_name) db.actor:give_talk_message2(news_caption, "", "ui_inGame2_V_zone_nedavno_proshel_vibros", "iconed_answer_item") else news_caption = game.translate_string("st_surge_hide_given").." "..game.translate_string("st_all_surge") db.actor:give_talk_message2(news_caption, "", "ui_inGame2_V_zone_nedavno_proshel_vibros", "iconed_answer_item") end end --------------------------------------------------------------------------------------------------- ---------------------Формирование фраз для диалогов об укрытиях------------------------------ --------------------------------------------------------------------------------------------------- function include_about_surge_hide_main_phrases(dialog,phrase_table,phrase_prefix) phrase_table.main0=dialog:AddPhrase(phrase_prefix.."0",tostring(0),"",-10000) phrase_table.main100=dialog:AddPhrase(phrase_prefix.."stalker_100",tostring(100),tostring(0),-10000) phrase_table.main100:GetPhraseScript():AddPrecondition("otstypnik_phrases.speaker_is_stalker") phrase_table.main101=dialog:AddPhrase(phrase_prefix.."stalker_101",tostring(101),tostring(100),-10000) phrase_table.main101:GetPhraseScript():AddAction("otstypnik_phrases.about_surge_hide_dialog_add_info") phrase_table.main102=dialog:AddPhrase(phrase_prefix.."stalker_102",tostring(102),tostring(101),-10000) phrase_table.main102:GetPhraseScript():AddPrecondition("otstypnik_phrases.speaker_know_nearest") phrase_table.main102:GetPhraseScript():AddAction("otstypnik_phrases.add_nearest_surge_hide") phrase_table.main103=dialog:AddPhrase(phrase_prefix.."stalker_103",tostring(103),tostring(102),-10000) phrase_table.main110=dialog:AddPhrase(phrase_prefix.."stalker_110",tostring(110),tostring(101),-10000) phrase_table.main110:GetPhraseScript():AddPrecondition("otstypnik_phrases.speaker_dont_know_nearest") phrase_table.main111=dialog:AddPhrase(phrase_prefix.."stalker_111",tostring(111),tostring(110),-10000) --phrase_table.main104:GetPhraseScript():AddAction("dialogs.break_dialog") phrase_table.main200=dialog:AddPhrase(phrase_prefix.."freedom_100",tostring(200),tostring(0),-10000) phrase_table.main200:GetPhraseScript():AddPrecondition("otstypnik_phrases.speaker_is_freedom") phrase_table.main201=dialog:AddPhrase(phrase_prefix.."freedom_101",tostring(201),tostring(200),-10000) phrase_table.main201:GetPhraseScript():AddAction("otstypnik_phrases.about_surge_hide_dialog_add_info") phrase_table.main202=dialog:AddPhrase(phrase_prefix.."freedom_102",tostring(202),tostring(201),-10000) phrase_table.main202:GetPhraseScript():AddPrecondition("otstypnik_phrases.speaker_know_nearest") phrase_table.main202:GetPhraseScript():AddAction("otstypnik_phrases.add_nearest_surge_hide") phrase_table.main203=dialog:AddPhrase(phrase_prefix.."freedom_103",tostring(203),tostring(202),-10000) phrase_table.main210=dialog:AddPhrase(phrase_prefix.."freedom_110",tostring(210),tostring(201),-10000) phrase_table.main210:GetPhraseScript():AddPrecondition("otstypnik_phrases.speaker_dont_know_nearest") phrase_table.main211=dialog:AddPhrase(phrase_prefix.."freedom_111",tostring(211),tostring(210),-10000) --phrase_table.main204:GetPhraseScript():AddAction("dialogs.break_dialog") phrase_table.main300=dialog:AddPhrase(phrase_prefix.."dolg_100",tostring(300),tostring(0),-10000) phrase_table.main300:GetPhraseScript():AddPrecondition("otstypnik_phrases.speaker_is_dolg") phrase_table.main301=dialog:AddPhrase(phrase_prefix.."dolg_101",tostring(301),tostring(300),-10000) phrase_table.main301:GetPhraseScript():AddAction("otstypnik_phrases.about_surge_hide_dialog_add_info") phrase_table.main302=dialog:AddPhrase(phrase_prefix.."dolg_102",tostring(302),tostring(301),-10000) phrase_table.main302:GetPhraseScript():AddPrecondition("otstypnik_phrases.speaker_know_nearest") phrase_table.main302:GetPhraseScript():AddAction("otstypnik_phrases.add_nearest_surge_hide") phrase_table.main303=dialog:AddPhrase(phrase_prefix.."dolg_103",tostring(303),tostring(302),-10000) phrase_table.main310=dialog:AddPhrase(phrase_prefix.."dolg_110",tostring(310),tostring(301),-10000) phrase_table.main310:GetPhraseScript():AddPrecondition("otstypnik_phrases.speaker_dont_know_nearest") phrase_table.main311=dialog:AddPhrase(phrase_prefix.."dolg_111",tostring(311),tostring(310),-10000) --phrase_table.main304:GetPhraseScript():AddAction("dialogs.break_dialog") phrase_table.main400=dialog:AddPhrase(phrase_prefix.."bandit_100",tostring(400),tostring(0),-10000) phrase_table.main400:GetPhraseScript():AddPrecondition("otstypnik_phrases.speaker_is_bandit") phrase_table.main401=dialog:AddPhrase(phrase_prefix.."bandit_101",tostring(401),tostring(400),-10000) phrase_table.main401:GetPhraseScript():AddAction("otstypnik_phrases.about_surge_hide_dialog_add_info") phrase_table.main402=dialog:AddPhrase(phrase_prefix.."bandit_102",tostring(402),tostring(401),-10000) phrase_table.main402:GetPhraseScript():AddPrecondition("otstypnik_phrases.speaker_know_nearest") phrase_table.main402:GetPhraseScript():AddAction("otstypnik_phrases.add_nearest_surge_hide") phrase_table.main403=dialog:AddPhrase(phrase_prefix.."bandit_103",tostring(403),tostring(402),-10000) phrase_table.main410=dialog:AddPhrase(phrase_prefix.."bandit_110",tostring(410),tostring(401),-10000) phrase_table.main410:GetPhraseScript():AddPrecondition("otstypnik_phrases.speaker_dont_know_nearest") phrase_table.main411=dialog:AddPhrase(phrase_prefix.."bandit_111",tostring(411),tostring(410),-10000) --phrase_table.main404:GetPhraseScript():AddAction("dialogs.break_dialog") phrase_table.main500=dialog:AddPhrase(phrase_prefix.."ecolog_100",tostring(500),tostring(0),-10000) phrase_table.main500:GetPhraseScript():AddPrecondition("otstypnik_phrases.speaker_is_ecolog") phrase_table.main501=dialog:AddPhrase(phrase_prefix.."ecolog_101",tostring(501),tostring(500),-10000) phrase_table.main501:GetPhraseScript():AddAction("otstypnik_phrases.about_surge_hide_dialog_add_info") phrase_table.main502=dialog:AddPhrase(phrase_prefix.."ecolog_102",tostring(502),tostring(501),-10000) phrase_table.main502:GetPhraseScript():AddPrecondition("otstypnik_phrases.speaker_know_nearest") phrase_table.main502:GetPhraseScript():AddAction("otstypnik_phrases.add_nearest_surge_hide") phrase_table.main503=dialog:AddPhrase(phrase_prefix.."ecolog_103",tostring(503),tostring(502),-10000) phrase_table.main510=dialog:AddPhrase(phrase_prefix.."ecolog_110",tostring(510),tostring(501),-10000) phrase_table.main510:GetPhraseScript():AddPrecondition("otstypnik_phrases.speaker_dont_know_nearest") phrase_table.main511=dialog:AddPhrase(phrase_prefix.."ecolog_111",tostring(511),tostring(510),-10000) --phrase_table.main504:GetPhraseScript():AddAction("dialogs.break_dialog") phrase_table.main9000=dialog:AddPhrase(phrase_prefix.."9000",tostring(9000),tostring(0),-10000) phrase_table.main9000:GetPhraseScript():AddPrecondition("otstypnik_phrases.speaker_dont_know_surge_hide") phrase_table.main9001=dialog:AddPhrase(phrase_prefix.."9001",tostring(9001),tostring(9000),-10000) phrase_table.main9001:GetPhraseScript():AddAction("otstypnik_phrases.about_surge_hide_dialog_add_info") --phrase_table.main9002:GetPhraseScript():AddAction("dialogs.break_dialog") end --------------------------------------------------------------------------------------------------- ---------------------Инициализация фраз диалога об укрытиях---------------------------------------- --------------------------------------------------------------------------------------------------- function about_surge_hide_dialog(dialog) local phrase_table = {} local phrase_prefix = "about_surge_hide_dialog_" local current_level = level.name() include_about_surge_hide_main_phrases(dialog,phrase_table,phrase_prefix) end Фразы для диалога, для разных фракций НПС и что главное теперь все укрытия имеют названия, для обозначения их в диалоге с НПС. Имя фразы например: st_tp_surge_1, то есть st_имя_секции_укрытия. <string id="st_surge_hide_given"> <text>В ПДА отмечено укрытие от выброса.</text> </string> <string id="about_surge_hide_dialog_0"> <text>Не подскажешь насчет укрытий от выброса?</text> </string> <!--Фракция Сталкеров--> <string id="about_surge_hide_dialog_stalker_100"> <text>А что тебя интересует?</text> </string> <string id="about_surge_hide_dialog_stalker_101"> <text>Где ближайшее отсюда укрытие?</text> </string> <string id="about_surge_hide_dialog_stalker_102"> <text>Ближайшее это...</text> </string> <string id="about_surge_hide_dialog_stalker_103"> <text>Спасибо.</text> </string> <string id="about_surge_hide_dialog_stalker_110"> <text>Не могу сказать.</text> </string> <string id="about_surge_hide_dialog_stalker_111"> <text>Жаль.</text> </string> <!--Фракция Свобода--> <string id="about_surge_hide_dialog_freedom_100"> <text>А чего надо то Мэн?</text> </string> <string id="about_surge_hide_dialog_freedom_101"> <text>Чувак ближайшее отсюда укрытие не знаешь где?</text> </string> <string id="about_surge_hide_dialog_freedom_102"> <text>Мен, ближайшее это...</text> </string> <string id="about_surge_hide_dialog_freedom_103"> <text>Респект тебе.</text> </string> <string id="about_surge_hide_dialog_freedom_110"> <text>Не, не помню, чувак.</text> </string> <string id="about_surge_hide_dialog_freedom_111"> <text>Ботва.</text> </string> <!--Фракция Долг--> <string id="about_surge_hide_dialog_dolg_100"> <text>Спрашивай, что именно нужно?</text> </string> <string id="about_surge_hide_dialog_dolg_101"> <text>Командир, где ближайшее отсюда укрытие?</text> </string> <string id="about_surge_hide_dialog_dolg_102"> <text>Ближе всего...</text> </string> <string id="about_surge_hide_dialog_dolg_103"> <text>Благодарю.</text> </string> <string id="about_surge_hide_dialog_dolg_110"> <text>Чего-то не припомню, извини.</text> </string> <string id="about_surge_hide_dialog_dolg_111"> <text>Проехали.</text> </string> <!--Фракция Бандиты--> <string id="about_surge_hide_dialog_bandit_100"> <text>Брателло, что конкретно?</text> </string> <string id="about_surge_hide_dialog_bandit_101"> <text>Чувак ближайшее отсюда укрытие не знаешь где?</text> </string> <string id="about_surge_hide_dialog_bandit_102"> <text>Брателло ближе всего...</text> </string> <string id="about_surge_hide_dialog_bandit_103"> <text>Во это зашибись, чувак.</text> </string> <string id="about_surge_hide_dialog_bandit_110"> <text>Брателло, звиняй, не подскажу.</text> </string> <string id="about_surge_hide_dialog_bandit_111"> <text>Фигово.</text> </string> <!--Фракция Экологи--> <string id="about_surge_hide_dialog_ecolog_100"> <text>Что конкретно хотите узнать?</text> </string> <string id="about_surge_hide_dialog_ecolog_101"> <text>Где ближайшее отсюда укрытие?</text> </string> <string id="about_surge_hide_dialog_ecolog_102"> <text>Ближе всего, молодой человек...</text> </string> <string id="about_surge_hide_dialog_ecolog_103"> <text>Благодарствую.</text> </string> <string id="about_surge_hide_dialog_ecolog_110"> <text>Извините, запамятовал, я не смогу вам помочь.</text> </string> <string id="about_surge_hide_dialog_ecolog_111"> <text>Очень жаль.</text> </string> <!--Иная фракция--> <string id="about_surge_hide_dialog_9000"> <text>Не факт.</text> </string> <string id="about_surge_hide_dialog_9001"> <text>Отстой.</text> </string> <!--Названия укрытий--> <string id="st_all_surge"> <text>На базе.</text> </string> <!--Локация Топи--> <string id="st_tp_surge_1"> <text>Магазин торговца на базе.</text> </string> <string id="st_tp_surge_2"> <text>Гараж справа на КПП.</text> </string> <string id="st_tp_surge_3"> <text>Пещеры кровососов.</text> </string> <string id="st_tp_surge_4"> <text>Малый погреб в деревне.</text> </string> <string id="st_tp_surge_5"> <text>Большой погреб в деревне.</text> </string> <string id="st_tp_surge_6"> <text>Мини котельная.</text> </string> <string id="st_tp_surge_7"> <text>Подвал на базе.</text> </string> <string id="st_tp_surge_8"> <text>Комната медика на базе.</text> </string> <string id="st_tp_surge_9"> <text>Комната механика на базе.</text> </string> <string id="st_tp_surge_10"> <text>Здание управления на базе.</text> </string> <string id="st_tp_surge_11"> <text>Полуразрушенное здание на базе.</text> </string> <string id="st_tp_surge_12"> <text>Гараж на базе.</text> </string> <string id="st_tp_surge_13"> <text>Гараж слева на КПП.</text> </string> <string id="st_tp_surge_14"> <text>Подвал в деревне.</text> </string> <string id="st_tp_surge_15"> <text>Коровник на ферме.</text> </string> <string id="st_tp_surge_16"> <text>Землянка на болоте.</text> </string> <string id="st_tp_surge_17"> <text>Дом в деревне.</text> </string> Изменено 5 часов назад пользователем denis2000 2 2 3 Путь во мгле. Связь времен."Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты