--[[ File: amk_mod .script copyright © AMK TEAM 2007-2008 добавлена  fenechka by TAG --]] local math_random = math.random local math_floor = math.floor local math_pi = math.pi local math_sin = math.sin local math_cos = math.cos local math_ceil = math.ceil local string_find = string.find local string_sub = string.sub local flag_ubrat_minigun = false local table_insert = table.insert --zombied = {} --'******************************************************************************* --' ** ** ** ** ** ** ** ** QUEST_AF_STAR ** ** ** ** ** ** ** ** --'******************************************************************************* local points={ { position={x=-24.2727108001709,y=-12.1660995483398,z=-100.200202941895}, gv=0, lv=73868 }, { position={x=159.56,y=4.72,z=88.60}, gv=155, lv=463808 }, { position={x=-4.11,y=2.90,z=108.09}, gv=85, lv=272619 } } function spawn_star(actor,npc,p1,p2) local a = points[math_random(#points)] local obj = alife():create("af_night_star", vector():set(a.position.x,a.position.y,a.position.z), a.lv, a.gv) local m_where if news_main then m_where = news_main.get_point_description("l01_escape", vector():set(a.position.x,a.position.y,a.position.z)) else m_where = "Tu, na Kordonie" end db.actor:give_talk_message(m_where.." trzeba bкdzie poszukaж. On gdzieњ tam jest, na pewno.", "ui\\ui_iconstotal", Frect():set(0,0,10,10), "simple_answer_item") end --'******************************************************************************* --' ** ** ** ** ** ** ** ** FIRST_RUN ** ** ** ** ** ** ** ** ** --'******************************************************************************* function first_run() if amk.load_variable("x_first_run",true) then amk.g_start_timer("gg_need_sleep",0,0,6) amk.g_start_timer("show_news",0,0,10) amk.save_variable("gg_need_sleep",80) math.randomseed( time_global() + 172800 ) amk.save_variable("x_first_run",false) end if amk.load_variable("amk_version", 0) < 1400 then amk.save_variable("amk_version", 1400) amk.spawn_item("amk_zapiska",vector():set(-140.88,-28.49,-356.86),19,110480) amk.spawn_item("amk_zapiska",vector():set(-36.69,-8.94,2.30),1147,338) amk.spawn_item("amk_zapiska",vector():set(78.50,5.57,-24.51),1539,5886) sak.add_new_lcitem() spawn_fuel() ex_hoard.hoard_restrictor() spawn_unspawned_respawners_2() end -- Фикс по бункеру монолита до правок от 18.05.2017 -- if amk.load_variable("sol_fix_oso", 0) ~= 1 then amk.save_variable("sol_fix_oso", 1) local sobj = alife():story_object(1307) if sobj then alife():release(sobj) alife():create(7227) end end end --'******************************************************************************* --' ** ** ** ** ** ** ** ** CHECK_SPAWN ** ** ** ** ** ** ** ** --'******************************************************************************* function check_spawn() game_options.init() -- переменные -------------------------------------------------------------------- local lname = level.name() local sname = amk.load_variable("level_on_save","") local sim = alife() local gg = game_graph() local sobj, clid, sect, id, lvl, lvl_name, sobj_deleted local newLevel = (lname ~= sname and sname ~= "") local validActorGV = gg:valid_vertex_id(db.actor:game_vertex_id()) local blow=amk.load_variable("blowout",-1) local blow_type=blowout_type() local hours_type=blowout_hours() local horr=amk.load_variable("horror",-1) local horr_type=ex_horror.level_setting[lname][1] -- переменные ------------------------------------------------------------ end --- meceniy_work.main() --- запуск проверок и загрузка таблиц -------------------------------------------- if amk.load_variable("freeplay", 0) == 1 then amk.save_variable("freeplay", 0) end --проверка на фриплей netpacket_pda_id = netpacket_pda_create.create_pda() --проверка на наличие ПДА if blow > 0 and blow <= 6 then --загрузка погоды при Выбросе level.set_weather(hours_type.."_blow",true) if amk.has_timer("blowout") then amk.remove_timer("blowout") if blow_type==2 then amk.g_start_timer("blowout",0,0,0,4) else amk.g_start_timer("blowout",0,0,0,blow-1) end end end if horr > 0 and horr <= 7 then --загрузка погоды при ЧУ level.set_weather("horror",true) if amk.has_timer("horror") then amk.remove_timer("horror") amk.g_start_timer("horror",0,0,0,horr-1) end end --сообщения при переходе на уровень. if (lname ~= sname and sname ~= "") then if (news_main.isIsolatedLevel(lname)== true and news_main.isIsolatedLevel(sname) == false) then -- спустились под землю. news_main.on_disconnect() elseif (news_main.isIsolatedLevel(lname) == false and news_main.isIsolatedLevel(sname) == true) then -- выбрались из-под земли. news_main.on_connect() elseif lname == "atp_for_test22" and db.actor:has_info("atp_torgovetz_start") then db.actor:give_info_portion("atp_torgovetz_done") end end amk_anoms.init_0() --загрузка таблицы "anti_spawn_zones" amk_offline_alife.init() --строим таблицу неписей, монстров и оружия news_main.init() --инициализация новостей -- перебор объектов и запуск функций с ним связанных if validActorGV then clid = gg:vertex(db.actor:game_vertex_id()):level_id() end --аддон Бака rx_wmgr.manage_box_0() --уборщик sak_off_corpses.off_corpses_0() for i = 1, 65534 do sobj = sim:object(i) if sobj then --удаление кривых объектов(по game_vertex и level_vertex) sobj_deleted,lvl,lvl_name = ex_all.dell_bad_obj(sobj) if not sobj_deleted then -- собираем информацию по всем объектам для анализа статистики --if sol_stat then -- sol_stat.collectInfoSingle(sobj, lvl, lvl_name) --end sect = sobj:section_name() -- если брошенная граната - удаление(опять через три скрипта; тут - ручная граната, а там - для подствольника ;)) if xrs_ai.actor_net_spawn_single(sobj, sect) then -- предварительная работа уборщика(составляем таблицы всего всего -- (а если что то удалится последующими скриптами, до срабатывания Уборщика? -- ничего из того, что удаляется уборщиком последующими скриптами не удаляется) sak_off_corpses.off_corpses_single(sobj, clid, lvl) -- аддон Бака - поиск или создание ящика на локации rx_wmgr.manage_box_single(sobj, clid, lvl, sect, i) -- удаляем аномалии if amk_anoms.init_1(sobj, lvl_name) then -- собираем информацию о взрывчатке (сейчас - только мины) babah.collectBombs_single(sobj, sect) -- выстреленная граната из подствольника (опять через три скрипта; где ?? о_О) rx_ai.actor_net_spawn_single(sobj, sect, i) -- обновляем список закрытых замком тайников zamok.restore_single(sobj, sect) -- динамические костры xr_kamp.collect_kamp_fire_single(sobj, clid, lvl, sect) end end end end end --тоже с перебором. обновление таблицы "off_npcs"; иначе нельзя, а то неписи не поймут, какие тайники под замком, а какие нет amk_offline_alife.update_npc_tables() --- перебор объектов и запуск функций с ним связанных ------------------ end ---- --if sol_stat then -- sol_stat.printInfo() --end --- спавн удаление и т.д. -------------------------------------------------------- --собственно - Уборщик sak_off_corpses.off_corpses_2() sak_off_corpses.purge() sak_off_corpses.purge = nil sak_off_corpses = nil amk_anoms.init_2() --спавн аномалий xr_kamp.keep_actual_lights() -- костры - зачистка лишнего собранного --аддон Бака - создание ящика при необходимости rx_wmgr.manage_box_2() --загадочное удаление огнемёта у ГГ if db.actor and not has_alife_info("game_over") then local flame = db.actor:object("wpn_flame") if flame then db.actor:iterate_inventory( function(dummy, item) if item:section()=="wpn_flame" then alife():release(alife():object(item:id())) end end, db.actor) end end restore_sun(lname) --- спавн удаление и т.д. ----------------------------------------------- end ---- death_manager.init() --тесты --zamok.test_trim() --zamok.test_str_explode() end function restore_sun(lname) amk.save_variable("level_on_save",lname) if amk.load_variable("blow_started", 0) == 0 then start_blow_timer() amk.save_variable("blow_started", 1) end --- ex_all ---------------------------------------------------------------- if amk.load_variable("horror_started", 0) == 0 then ex_horror.start_horror_timer() amk.save_variable("horror_started", 1) end --- ex_all -------------------------------------------------------- end --- -- Вид ГГ после смерти в его собственной броне local npc_SP = db.actor local outfit = npc_SP:item_in_slot(6) if outfit ~= nil then local outfit_name = outfit:section() local outfit_cond = outfit:condition() bind_stalker.outfit_restored = true --get_console():execute("load [amk_mod]265 bind_stalker.outfit_restored = true") alife():release(alife():object(outfit:id()), true) outfit = alife():create(outfit_name, npc_SP:position(), npc_SP:level_vertex_id(), npc_SP:game_vertex_id(), npc_SP:id()) if outfit ~= nil then --amk.send_tip("set_condition, outfit.id: "..tostring(outfit.id)..", night_vision_outfit_id: "..tostring(bind_stalker.night_vision_outfit_id)) bind_stalker.night_vision_outfit_id = outfit.id --get_console():execute("load [amk_mod]271 bind_stalker.night_vision_outfit_id "..tostring(bind_stalker.night_vision_outfit_id)) amk.start_timer("set_condition", 1, {outfit.id, math.min(math_ceil(outfit_cond * 100), 100)}) end end end --'******************************************************************************* --' ** ** ** ** ** ** ** ** FREEPLAY ** ** ** ** ** ** ** ** ** --'******************************************************************************* function freeplay() amk.save_variable("freeplay",1) end --[[--------------------------------- lsclon -----------------------------------]] --'******************************************************************************* --' ** ** ** ** ** ** ** ** NEWS_AMK ** ** ** ** ** ** ** ** ** --'******************************************************************************* function show_news() if (news_main and news_main.on_news) then news_main.on_news() end local ln = level.name() if (ln == "l03u_agr_underground" or ln == "l04u_labx18" or ln == "l08u_brainlab" or ln == "l10u_bunker" or ln == "l12u_control_monolith" or ln == "l12u_sarcofag" or ln == "av_peshera" or ln == "jupiter_underground" or ln == "labx8" or ln == "mine" or ln == "peshera" or ln == "warlab" ) then -- Радиомолчание else if math_random()>0.2 then if math_random()>0.875 then if amk_dolg and math_random()>0.5 then local dolg_news=amk_dolg.get_strings() db.actor:give_game_news(dolg_news, "ui\\ui_iconsTotal", Frect():set(498,141,83,47), 0, 15000) elseif amk_freedom then local freedom_news=amk_freedom.get_strings() db.actor:give_game_news(freedom_news, "ui\\ui_iconsTotal", Frect():set(498,94,83,47), 0, 15000) end else if math_random()>0.57 then --amk.send_tip(when.." "..where.." "..text.." "..mat,name.." "..sname,nil,15,"gen_info") else --amk.send_tip(name.." "..sname..". "..dead..". "..reason,game.translate_string("stalker_died"),nil,10,"death") end end else if amk_uniq_news_lists and math_random()>0.5 then local uniq=amk_uniq_news_lists.get_strings() local name,sname = amk_names_lists.get_strings() amk.send_tip(uniq,name.." "..sname,nil,15,"uniq") elseif amk_modders then local mod_news=amk_modders.get_strings() db.actor:give_game_news(mod_news, "ui\\ui_iconsTotal", Frect():set(498,47,83,47), 0, 15000) end end end amk.g_start_timer("show_news",0,0,math_random(40,80)) end --'******************************************************************************* --' ** ** ** ** ** ** ** ** SLEEP_AMK ** ** ** ** ** ** ** ** ** --'******************************************************************************* ---- *** Сон *** ---- --[[ Сохраняемые переменные: block_sleep_menu - флаг "блокировки сна" gg_need_sleep - счетчик времени "без_сна" gg_need_sleep_nrg - счетчик "выпитых энергетиков" Таймеры: block_sleep_menu - "блокировки сна" энергетиком gg_need_sleep - счетчика времени "без_сна" Функции: reduce_need_sleep - взависимости от времени сна, устанавливывает значение счетчика времени "без_сна" test_for_need_sleep - каждые шесть минут увеличивывает счетчик времени "без_сна" test_sleep_pp - проверяет счетчик времени "без_сна": -- больше 30 часов - включает эффекты бессонницы -- больше 36 часов - автоматом уложит спать --]] function reduce_need_sleep(scale) counterAdd("amk_mod.reduce_need_sleep") local tmp = amk.load_variable("gg_need_sleep",0) if tmp > 80 then tmp = 80 end tmp = tmp - scale*10 if tmp < 0 then tmp = 0 end amk.save_variable("block_sleep_menu",0) amk.save_variable("gg_need_sleep",tmp) amk.save_variable("gg_need_sleep_nrg",0) test_sleep_pp() end function test_for_need_sleep() counterAdd("amk_mod.test_for_need_sleep") if not sleep_manager.is_sleep_active() then local tmp = amk.load_variable("gg_need_sleep",0) tmp = tmp + 1 amk.save_variable("gg_need_sleep",tmp) test_sleep_pp() end amk.g_start_timer("gg_need_sleep",0,0,6) end function test_sleep_pp() counterAdd("amk_mod.test_sleep_pp") local tmp = amk.load_variable("gg_need_sleep",0) if tmp > 360 and not db.actor:is_talking() then sleep_manager.main(8 + amk.load_variable("gg_need_sleep_nrg",0)) end if tmp > 300 and tmp <= 360 then level.add_pp_effector("yantar_underground_psi.ppe",999,true) level.set_pp_effector_factor(999,5.0) end if tmp <= 300 then level.remove_pp_effector(999) end end --'******************************************************************************* --' ** ** ** ** ** ** ** ** ITEM_TRANSFORM ** ** ** ** ** ** ** ** --'******************************************************************************* local tramsform_items = { -- ["af_kaktus_izomorf"] = {info_has = {"kaktus_izo_resept"}, result = {"bloodsucker_sky", "af_spirit_4", "af_arhara_globus", "mutant_krovosos_cocoon"}}, ["af_globus_izomorf"] = {info_has = {"kaktus_izo_resept"}, result = {"af_babka_3", "af_spirit_4", "bloodsucker_sky", "af_arhara_globus", "mutant_krovosos_cocoon"}}, ["af_deokristall"] = {info_has = {"kaktus_izo_resept"}, result = {"af_spirit_3", "af_babka_2", "wpn_m4"}}, ["af_plastilin_izomorf"] = {info_has = {"molniya_plastilin_ok_start"}, result = {"korobka_sigars", "ammo_5.45x39_izomorf", "ammo_7.62x54_izomorf", "ammo_zhekan_izomorf"}}, ["korobka_sigars"] = {info_has = {"kluch_poluchen"}, result = {"af_9x39_izomorf", "ammo_9x39_izomorf", "ammo_9x39_izomorf", "ammo_9x39_izomorf"}}, ["primanka_1"] = {info_has = {"mozhno_kidat"}, info_give = {"primanka_zakinuta"}, result = {"primanka_2"}} } -- проверка на упавший предмет/артефакт function check_for_item_drop(obj) counterAdd("amk_mod.check_for_item_drop") local obj_sect = obj:section() local actor = db.actor if tramsform_items[obj_sect] and actor_has_all_info(tramsform_items[obj_sect].info_has) then local lv = obj:level_vertex_id() local gv = obj:game_vertex_id() if gv == 65535 then gv = actor:game_vertex_id() end if gv == 65535 then return end -- похоже, что рядом нету вертекса -- предмет подходит - отправляем его на экспертизу -- узнаем не съели ли его или выложили в нычку local tbl = {} tbl.obj_id = obj:id() tbl.lv = lv tbl.gv = gv tbl.info_give = tramsform_items[obj_sect].info_give amk.start_timer("timer_drop_obj_transform", 0.2, tbl) end end function actor_has_all_info(info) counterAdd("amk_mod.actor_has_all_info") local result = true local actor = db.actor for i = 1, #info do if actor:dont_has_info(info[i]) then result = false break end end return result end function item_transform(tbl) counterAdd("amk_mod.item_transform") local obj = level.object_by_id(tbl.obj_id) if obj then level.add_pp_effector("teleport.ppe", 1524, false) local result = tramsform_items[obj:section()].result local position = obj:position() for i = 1, #result do amk.spawn_item(result[i], position, tbl.gv, tbl.lv) end if tbl.info_give ~= nil then for i = 1, #tbl.info_give do db.actor:give_info_portion(tbl.info_give[i]) end end amk.remove_item(obj) end end --'******************************************************************************* --' ** ** ** ** ** ** ** ** AF_TRANSFORM ** ** ** ** ** ** ** ** --'******************************************************************************* local cur_level=nil local havegoodart=false -- список компонентов -- желательно добавлять в алфавитном порядке -- -- автоматическое заполнение таблицы afs ниже по коду - после таблицы anom_recept_komp local afs={} -- проверка на упавший предмет/артефакт function check_for_af_drop(obj) counterAdd("amk_mod.check_for_af_drop") local obj_sect = obj:section() -- проверка не один ли это из компонентов if afs[obj_sect] == true then local anom_id,anom_pos,anom_radius,dist = amk_anoms.get_nearest_anomaly(obj) if anom_id and anom_radius - dist > -5 then --local anom_sect = level.object_by_id(anom_id):section() --local obj_pos = obj:position() local lv = level.object_by_id(anom_id):level_vertex_id() local gv = level.object_by_id(anom_id):game_vertex_id() if gv == 65535 then gv = obj:game_vertex_id() end if gv == 65535 then gv = db.actor:game_vertex_id() end if gv == 65535 then return end -- похоже, что рядом нету вертекса -- предмет подходит - отправляем его на экспертизу -- узнаем не съели ли его или вvложили в нvчку local tbl = {} tbl.obj_id = obj:id() tbl.anom_id = anom_id tbl.anom_radius = anom_radius tbl.lv = lv tbl.gv = gv amk.start_timer("timer_drop_obj_varka", 0.2, tbl) -- перенесено в amk.script --check_af_transform(obj, obj_sect, obj_pos, anom_id, anom_sect, anom_pos, anom_radius, lv, gv) end end end -- проверка: является ли компонентом для варки -- параметр - название секции function is_komponent(sec) counterAdd("amk_mod.is_komponent") return (afs[sec] ~= nil) end -- аномалии "узнаются" по части названия! -- komp - компоненты -- удача v_udachi + вырождение в булыжник v_virogd <= 100 !!! -- отторжение v_ottorg = 100 - (v_udachi + v_virogd) посему и не нужно прописывать в таблицу -- cel - цель (может быть одновременно несколько целей) -- info - инфопорция, которая будет выдана после L-L+=+Ј варки -- virogd - во что вырождается (может бvть одновременно несколько вырождений) -- vremya = {дни, часы, минуты} - время варки/мутации -- remove_anomaly - удалить ли аномалию (можно комбинировать вместе с варкой/мутацией) -- not_for_mutator - рецепт никогда не попадет в трансмутатор -- ne_ugadat - рецепт не угадывается в трансмутаторе, но будет в нем показан при наличии поршня -- ВНИМАНИЕ ! Если изменился любой набор компонентов, то такую правку нельзя ставить, если есть активная варка ! local anom_recept_komp = { -- умолчание, если нет данных ближе к рецепту default = { cel = {}, v_udachi = 100, v_virogd = 0, virogd = {["af_buliz"]=true}, vremya = {0,0,5}, remove_anomaly = false }, anomalii = { ["_zharka"] = { -- умолчание, если нет данных ближе к рецепту, -- которое может переопределятья в рецепте name = "\"Piec\"", default = { v_udachi = 100, v_virogd = 0, vremya = {0,0,5} }, recepti = { ["info_izomorf_kompas"] = { -- артефакт удалит аномалию без результатов варки/мутации komp = {["af_kompas_izomorf"]=true}, cel = {["af_kompas_izomorf"]=true}, vremya = {0,0,1}, remove_anomaly = true }, ["info_artmod_electra_flash_zharka"] = { komp = {["af_medusa"]=true,["af_rusty_thorn"]=true,["af_vyvert"]=true,["vodka"]=true}, cel = {["af_electra_flash"]=true} }, ["info_artmod_ameba_slime_zharka"] = { komp = {["af_medusa"]=true,["af_blood"]=true,["kolbasa"]=true,["mutant_dog_tail"]=true}, cel = {["af_ameba_slime"]=true} }, ["info_artmod_gravi_zharka"] = { komp = {["af_medusa"]=true,["af_blood"]=true,["bandage"]=true,["conserva"]=true}, cel = {["af_gravi"]=true} }, ["info_artmod_night_star_zharka"] = { komp = {["af_rusty_kristall"]=true,["af_vyvert"]=true,["af_electra_flash"]=true,["mutant_snork_leg"]=true}, cel = {["af_night_star"]=true} }, ["info_artmod_electra_moonlight_zharka"] = { komp = {["af_gravi"]=true,["af_medusa"]=true,["af_electra_flash"]=true,["mutant_krovosos_jaw"]=true}, cel = {["af_electra_moonlight"]=true} }, ["info_artmod_dummy_battery_zharka"] = { komp = {["af_electra_flash"]=true,["af_ameba_mica"]=true,["vodka"]=true,["mutant_dog_tail"]=true}, cel = {["af_dummy_battery"]=true} }, --["info_amk_recipt_soul_drops"] = { ["info_amk_recipt_souls"] = { komp = {["af_soul"]=true}, cel = {["af_spirit_1"]=true}, vremya = {0,4,0} }, ["info_artmod_gusenica"] = { komp = {["bezoar"]=true}, cel = {["af_caterpillar"]=true}, vremya = {0,0,5}, v_udachi = 75, v_virogd = 25 }, ["info_artmod_probabka_burera"] = { komp = {["af_babka_3"]=true}, cel = {["af_babka_4"]=true}, vremya = {0,0,5}, v_udachi = 75, v_virogd = 25 }, --["info_amk_recipt_soul_fire"] = { ["info_amk_recipt_souls"] = { komp = {["af_spirit_1"]=true}, cel = {["af_spirit_2"]=true}, vremya = {0,6,0} }, --["info_amk_recipt_soul_cristal"] = { ["info_amk_recipt_souls"] = { komp = {["af_spirit_2"]=true}, cel = {["af_spirit_3"]=true}, vremya = {0,10,0} }, ["info_amk_recipt_tears_fire"] = { komp = {["af_cry_1"]=true}, cel = {["af_cry_2"]=true}, vremya = {0,5,0} }, ["info_amk_recipt_dikoobraz"] = { komp = {["af_rusty_sea_urchin"]=true}, cel = {["af_dik_1"]=true}, vremya = {0,3,0} }, ["info_amk_recipt_giant_small_brother"] = { komp = {["af_kol_3"]=true}, cel = {["af_kol_4"]=true}, vremya = {0,3,0} }, ["info_amk_recipt_controller_skalp"] = { komp = {["af_armor_3"]=true}, cel = {["af_armor_4"]=true}, vremya = {0,6,0} } } }, ["_galant"] = { -- умолчание, если нет данных ближе к рецепту name = "\"Elektra\"", default = { v_udachi = 100, v_virogd = 0, vremya = {0,0,5} }, recepti = { ["info_red_battery"] = { -- артефакт удалит аномалию без результатов варки/мутации komp = {["af_dummy_battery_red"]=true}, remove_anomaly = true, vremya = {0,0,1}, not_for_mutator = true }, ["info_artmod_fireball_galant"] = { komp = {["af_blood"]=true,["af_medusa"]=true,["vodka"]=true,["mutant_dog_tail"]=true}, cel = {["af_fireball"]=true} }, ["info_artmod_cristall_flower_galant"] = { komp = {["af_vyvert"]=true,["af_rusty_thorn"]=true,["conserva"]=true,["mutant_dog_tail"]=true}, cel = {["af_cristall_flower"]=true} }, ["info_artmod_ameba_mica_galant"] = { komp = {["af_ameba_slime"]=true,["af_rusty_thorn"]=true,["af_medusa"]=true,["kolbasa"]=true}, cel = {["af_ameba_mica"]=true} }, ["info_artmod_electra_moonlight_galant"] = { komp = {["af_gravi"]=true,["af_blood"]=true,["af_fireball"]=true,["mutant_psevdodog_tail"]=true}, cel = {["af_soul"]=true} }, ["info_artmod_gold_fish_galant"] = { komp = {["af_medusa"]=true,["af_rusty_thorn"]=true,["af_cristall_flower"]=true,["mutant_flesh_eye"]=true}, cel = {["af_gold_fish"]=true} }, ["info_artmod_dummy_spring_galant"] = { komp = {["af_cristall_flower"]=true,["af_cristall"]=true,["mutant_psevdodog_tail"]=true,["conserva"]=true}, cel = {["af_dummy_spring"]=true} }, ["info_artmod_medusa_galant"] = { komp = {["mutant_face_tushkano"]=true,["bandage"]=true,["conserva"]=true,["mutant_dog_tail"]=true}, cel = {["af_medusa"]=true} }, --["info_amk_recipt_soul_bengal"] = { ["info_amk_recipt_souls"] = { komp = {["af_spirit_3"]=true}, cel = {["af_spirit_4"]=true}, vremya = {0,1,0} }, ["info_amk_recipt_tears_electra"] = { komp = {["af_drops"]=true}, cel = {["af_cry_1"]=true}, vremya = {0,5,0} }, ["info_amk_recipt_grandmother_glassbeards"] = { komp = {["af_dummy_glassbeads"]=true}, cel = {["af_babka_1"]=true}, vremya = {0,5,0} }, -- ["info_amk_recipt_dummy"] = { ["info_amk_recipt_dummy_fire"] = { komp = {["af_dummy_dummy"]=true}, cel = {["af_pudd_1"]=true}, vremya = {0,3,0} }, -- ["info_amk_recipt_dummy"] = { ["info_amk_recipt_dummy_bright"] = { komp = {["af_pudd_1"]=true}, cel = {["af_pudd_2"]=true}, vremya = {0,6,0} }, -- ["info_amk_recipt_dummy"] = { ["info_amk_recipt_dummy_moon"] = { komp = {["af_pudd_2"]=true}, cel = {["af_pudd_3"]=true}, vremya = {0,8,0} }, ["info_amk_recipt_electra_dikoobraz"] = { komp = {["af_dik_1"]=true}, cel = {["af_dik_2"]=true}, vremya = {0,5,0} } } }, ["_buzz"] = { -- умолчание, если нет данных ближе к рецепту name = "\"Galareta\"", default = { v_udachi = 100, v_virogd = 0, vremya = {0,0,5} }, recepti = { ["info_izomorf_kompas"] = { -- артефакт удалит аномалию без результатов варки/мутации komp = {["af_kompas_izomorf"]=true}, cel = {["af_kompas_izomorf"]=true}, vremya = {0,0,1}, remove_anomaly = true }, ["info_artmod_rusty_kristall_buzz"] = { komp = {["af_electra_sparkler"]=true,["af_medusa"]=true,["af_drops"]=true,["bread"]=true}, cel = {["af_rusty_kristall"]=true} }, ["info_artmod_rusty_thorn_buzz"] = { komp = {["af_blood"]=true,["bandage"]=true,["bread"]=true,["mutant_dog_tail"]=true}, cel = {["af_rusty_thorn"]=true} }, ["info_artmod_fireball_buzz"] = { komp = {["af_rusty_thorn"]=true,["af_vyvert"]=true,["mutant_snork_leg"]=true,["bread"]=true}, cel = {["af_fireball"]=true} }, ["info_artmod_night_star_buzz"] = { komp = {["af_gravi"]=true,["af_blood"]=true,["af_electra_flash"]=true,["mutant_psevdodog_tail"]=true}, cel = {["af_gold_fish"]=true} }, ["info_artmod_fuzz_kolobok_buzz"] = { komp = {["af_night_star"]=true,["af_soul"]=true,["af_electra_moonlight"]=true,["af_rusty_sea_urchin"]=true}, cel = {["af_fuzz_kolobok"]=true} }, ["info_artmod_vyvert_buzz"] = { komp = {["mutant_face_tushkano"]=true,["bandage"]=true,["conserva"]=true,["mutant_dog_tail"]=true}, cel = {["af_vyvert"]=true} }, ["info_amk_recipt_tears_chimaera"] = { komp = {["af_cry_2"]=true}, cel = {["af_cry_3"]=true}, vremya = {0,2,0} }, ["info_amk_recipt_pra_grandmother_glassbeards"] = { komp = {["af_babka_1"]=true}, cel = {["af_babka_2"]=true}, vremya = {0,3,0} }, -- ["info_amk_recipt_dummy"] = { ["info_amk_recipt_dummy_puding"] = { komp = {["af_pudd_3"]=true}, cel = {["af_pudd_4"]=true}, vremya = {0,12,0} }, ["info_amk_recipt_sopl_dikoobraz"] = { komp = {["af_dik_2"]=true}, cel = {["af_dik_3"]=true}, vremya = {0,2,0} }, ["info_amk_recipt_almaz_kolobok"] = { komp = {["af_kol_2"]=true}, cel = {["af_kol_3"]=true}, vremya = {0,8,0} }, ["info_amk_recipt_pancir"] = { komp = {["af_armor_2"]=true}, cel = {["af_armor_3"]=true}, vremya = {0,2,0} }, ["info_artmod_globus"] = { komp = {["af_simbion"]=true}, cel = {["af_arhara_globus"]=true}, vremya = {0,0,10}, v_udachi = 75, v_virogd = 25 --, -- ne_ugadat = true }, ["info_amk_recipt_simbion"] = { komp = {["af_medusa"]=true,["af_drops"]=true,["af_blood"]=true,["af_rusty_thorn"]=true}, cel = {["af_simbion"]=true}, vremya = {0,5,0} }, ["info_medwed_dry_paw"] = { komp = {["mutant_medwed_paw"]=true}, cel = {["mutant_medwed_dry_paw"]=true}, vremya = {0,2,0} } } }, ["_fountain"] = { name = "\"Fontanna\"", recepti = { ["info_izomorf_kompas"] = { -- артефакт удалит аномалию без результатов варки/мутации komp = {["af_kompas_izomorf"]=true}, cel = {["af_kompas_izomorf"]=true}, vremya = {0,0,1}, remove_anomaly = true }, ["info_artmod_cristall_buzz"] = { komp = {["af_cristall_flower"]=true,["af_medusa"]=true,["af_fireball"]=true,["mutant_krovosos_jaw"]=true}, cel = {["af_cristall"]=true} } } }, ["_mincer"] = { -- умолчание, если нет данных ближе к рецепту name = "\"Karuzela\"", default = { v_udachi = 100, v_virogd = 0, vremya = {0,0,5} }, recepti = { ["info_red_spring"] = { -- артефакт удалит аномалию без результатов варки/мутации komp = {["af_dummy_spring_red"]=true}, remove_anomaly = true, vremya = {0,0,1}, not_for_mutator = true }, ["info_artmod_cristall_flower_mincer"] = { komp = {["af_blood"]=true,["af_medusa"]=true,["bandage"]=true,["conserva"]=true}, cel = {["af_cristall_flower"]=true} }, ["info_artmod_drops_mincer"] = { komp = {["af_vyvert"]=true,["bandage"]=true,["vodka"]=true,["mutant_dog_tail"]=true}, cel = {["af_drops"]=true} }, ["info_artmod_rusty_kristall_mincer"] = { komp = {["af_electra_sparkler"]=true,["af_medusa"]=true,["conserva"]=true,["mutant_dog_tail"]=true}, cel = {["af_rusty_kristall"]=true} }, ["info_artmod_electra_moonlight_mincer"] = { komp = {["af_fireball"]=true,["af_blood"]=true,["af_ameba_slug"]=true,["mutant_krovosos_jaw"]=true}, cel = {["af_electra_moonlight"]=true} }, ["info_artmod_ameba_slug_mincer"] = { komp = {["af_electra_flash"]=true,["af_vyvert"]=true,["af_fireball"]=true,["mutant_psevdodog_tail"]=true}, cel = {["af_ameba_mica"]=true} }, ["info_artmod_dummy_glassbeads_mincer"] = { komp = {["af_ameba_mica"]=true,["af_rusty_sea_urchin"]=true,["af_gold_fish"]=true,["af_night_star"]=true}, cel = {["af_dummy_glassbeads"]=true} }, ["info_amk_recipt_burer_grandmother_glassbeards"] = { komp = {["af_babka_2"]=true}, cel = {["af_babka_3"]=true}, vremya = {0,0,10} }, ["info_amk_recipt_titan_kolobok"] = { komp = {["af_kol_1"]=true}, cel = {["af_kol_2"]=true}, vremya = {0,5,0} }, ["we_ne_chmuri"] = { komp = {["af_kamen_udachy"]=true}, cel = {["af_kompas_izomorf"]=true}, vremya = {0,0,1}, not_for_mutator = true, info = "spawn_hospit_live" }, ["mozno_varit"] = { komp = {["af_part_monolit2"]=true}, cel = {["af_kamen_udachy"]=true}, vremya = {0,0,1}, not_for_mutator = true, info = "spawn_kamen_udachy" }, ["info_amk_recipt_cheshya"] = { komp = {["af_armor_1"]=true}, cel = {["af_armor_2"]=true}, vremya = {0,5,0} } } }, ["_mosquito_bald"] = { -- умолчание, если нет данных ближе к рецепту name = "\"Trampolina\"", default = { v_udachi = 100, v_virogd = 0, vremya = {0,0,5} }, recepti = { ["info_red_pellicle"] = { -- артефакт удалит аномалиі без результатов варки/мутации komp = {["af_dummy_pellicle_red"]=true}, remove_anomaly = true, vremya = {0,0,1}, not_for_mutator = true }, ["info_artmod_mincer_meat_mosquito_bald"] = { komp = {["af_vyvert"]=true,["af_blood"]=true,["vodka"]=true,["mutant_dog_tail"]=true}, cel = {["af_mincer_meat"]=true} }, ["info_artmod_electra_sparkler_mosquito_bald"] = { komp = {["af_drops"]=true,["bandage"]=true,["kolbasa"]=true,["mutant_dog_tail"]=true}, cel = {["af_electra_sparkler"]=true} }, ["info_artmod_ameba_slug_mosquito_bald"] = { komp = {["af_medusa"]=true,["af_drops"]=true,["bandage"]=true,["vodka"]=true}, cel = {["af_ameba_slug"]=true} }, ["info_artmod_cristall_mosquito_bald"] = { komp = {["af_mincer_meat"]=true,["af_vyvert"]=true,["af_fireball"]=true,["mutant_flesh_eye"]=true}, cel = {["af_cristall"]=true} }, ["info_artmod_rusty_sea-urchin_mosquito_bald"] = { komp = {["af_ameba_slime"]=true,["af_blood"]=true,["af_rusty_kristall"]=true,["mutant_krovosos_jaw"]=true}, cel = {["af_rusty_sea_urchin"]=true} }, ["info_artmod_dummy_dummy_mosquito_bald"] = { komp = {["af_ameba_mica"]=true,["af_cristall"]=true,["af_mincer_meat"]=true,["af_night_star"]=true}, cel = {["af_dummy_dummy"]=true} }, ["info_amk_recipt_stone_dikoobraz"] = { komp = {["af_dik_3"]=true}, cel = {["af_dik_4"]=true}, vremya = {0,9,0} }, ["info_amk_recipt_steel_kolobok"] = { komp = {["af_fuzz_kolobok"]=true}, cel = {["af_kol_1"]=true}, vremya = {0,2,0} }, ["info_amk_recipt_shkura"] = { komp = {["af_dummy_pellicle"]=true}, cel = {["af_armor_1"]=true}, vremya = {0,5,0} } } }, ["_gravi_zone"] = { -- умолчание, если нет даннvх ближе к рецепту name = "\"Lejek\"", default = { v_udachi = 100, v_virogd = 0, vremya = {0,0,5} }, recepti = { ["info_red_battery"] = { -- артефакт удалит аномалиі без результатов варки/мутации komp = {["af_dummy_battery_red"]=true}, remove_anomaly = true, vremya = {0,0,1}, not_for_mutator = true }, ["info_artmod_ameba_slug_gravi_zone"] = { komp = {["af_vyvert"]=true,["af_medusa"]=true,["kolbasa"]=true,["mutant_dog_tail"]=true}, cel = {["af_ameba_slug"]=true} }, ["info_artmod_ameba_slime_gravi_zone"] = { komp = {["af_medusa"]=true,["bandage"]=true,["conserva"]=true,["mutant_dog_tail"]=true}, cel = {["af_ameba_slime"]=true} }, ["info_artmod_electra_flash_gravi_zone"] = { komp = {["af_vyvert"]=true,["af_blood"]=true,["mutant_dog_tail"]=true,["vodka"]=true}, cel = {["af_electra_flash"]=true} }, ["info_artmod_night_star_gravi_zone"] = { komp = {["af_rusty_thorn"]=true,["af_medusa"]=true,["af_rusty_kristall"]=true,["mutant_psevdodog_tail"]=true}, cel = {["af_night_star"]=true} }, ["info_artmod_soul_gravi_zone"] = { komp = {["af_electra_flash"]=true,["af_cristall_flower"]=true,["af_ameba_slug"]=true,["mutant_snork_leg"]=true}, cel = {["af_soul"]=true} }, ["info_artmod_dummy_pellicle_gravi_zone"] = { komp = {["af_ameba_mica"]=true,["af_cristall"]=true,["af_gold_fish"]=true,["af_soul"]=true}, cel = {["af_dummy_pellicle"]=true} } } }, ["_ice"] = { -- умолчание, если нет даннvх ближе к рецепту name = "\"Њnieїna\"", default = { v_udachi = 100, v_virogd = 0, vremya = {0,0,5} }, recepti = { ["info_izomorf_kompas"] = { -- артефакт удалит аномалиі без результатов варки/мутации komp = {["af_kompas_izomorf"]=true}, cel = {["af_kompas_izomorf"]=true}, vremya = {0,0,1}, remove_anomaly = true }, ["info_red_battery"] = { komp = {["af_dummy_battery"]=true}, cel = {["af_dummy_battery_red"]=true} }, ["info_red_spring"] = { komp = {["af_dummy_spring"]=true}, cel = {["af_dummy_spring_red"]=true} }, ["info_red_pellicle"] = { komp = {["af_dummy_pellicle"]=true}, cel = {["af_dummy_pellicle_red"]=true} } } }, ["_ogon"] = { name = "\"їar\"" }, ["_sphere"] = { name = "\"pкcherz\"", default = { v_udachi = 100, v_virogd = 0, vremya = {0,0,5} }, recepti = { ["info_izomorf_kompas"] = { -- артефакт удалит аномалиі без результатов варки/мутации komp = {["af_kompas_izomorf"]=true}, cel = {["af_kompas_izomorf"]=true}, vremya = {0,0,1}, remove_anomaly = true } } }, ["_zavesa"] = { name = "\"Tornado\"", default = { v_udachi = 100, v_virogd = 0, vremya = {0,0,5} }, recepti = { ["info_izomorf_kompas"] = { -- артефакт удалит аномалиі без результатов варки/мутации komp = {["af_kompas_izomorf"]=true}, cel = {["af_kompas_izomorf"]=true}, vremya = {0,0,1}, remove_anomaly = true } } }, ["_smallrain"] = { name = "\"Dym z Ogniska\"", default = { v_udachi = 100, v_virogd = 0, vremya = {0,0,5} }, recepti = { ["info_izomorf_kompas"] = { -- артефакт удалит аномалиі без результатов варки/мутации komp = {["af_kompas_izomorf"]=true}, cel = {["af_kompas_izomorf"]=true}, vremya = {0,0,1}, remove_anomaly = true } } }, ["_monolith"] = { name = "\"Radonowy Obіok\"" }, ["_no_gravity"] = { name = "\"Winda\"" } } } ---------------------------------------- -- автоматическое заполнение таблицы afs ---------------------------------------- function collect(t) counterAdd("amk_mod.collect") if t then for sect, _ in pairs(t) do afs[sect] = true end end end function collect_recept(recept) counterAdd("amk_mod.collect_recept") if recept then collect(recept.cel) collect(recept.komp) collect(recept.virogd) end end collect_recept(anom_recept_komp.default) for anom_sect, anom_info in pairs(anom_recept_komp.anomalii) do collect_recept(anom_info.default) if anom_info.recepti then for recept_name, recept_info in pairs(anom_info.recepti) do collect_recept(recept_info) end end end -- создание таблиц для компактной работы с таймерами - name_id, id_name local afs_name_id = {} local afs_id_name = {} for k,v in pairs(afs) do table_insert(afs_id_name, k) end table.sort(afs_id_name) for i = 1, #afs_id_name do afs_name_id[afs_id_name[i]] = i end ---------------------------------------- -- возвращает значение, возможно из умолчаний function get_af_transform_param(name, recept, recepti) counterAdd("amk_mod.get_af_transform_param") local result --get_console():execute("load ~#I#:"..string.format(name.." imiк")) if recept[name] ~= nil then result = recept[name] elseif recepti["default"] ~= nil and recepti["default"][name] ~= nil then result = recepti["default"][name] elseif anom_recept_komp["default"] ~= nil and anom_recept_komp["default"][name] ~= nil then result = anom_recept_komp["default"][name] else -- нет информации!!! amk.send_tip("brak informacji dla "..name.."!","modyfikacja artefaktуw",0,15,"gen_info") result = nil end return result end -- получаем полный набор рецептов для аномалии anom_sect function fill_recepti_est(anom_sect) counterAdd("amk_mod.fill_recepti_est") local recepti_est = {} -- рецепты для заданной аномалии local anom_name = nil for anom, recepti in pairs(anom_recept_komp["anomalii"]) do if string_find(anom_sect, anom) ~= nil then --нашли в списке аномалию. anom_name = anom_recept_komp["anomalii"][anom]["name"] if anom_recept_komp["anomalii"][anom]["recepti"] then for info, recept in pairs(recepti["recepti"]) do if not recept["not_for_mutator"] and not recept["remove_anomaly"] and (db.actor:has_info(info) or not recept["ne_ugadat"]) then -- if db.actor:has_info(info) then -- у ГГ есть такой рецепт: заносим в таблицу recepti_est[info] = {} for k, v in pairs(recept) do if type(v) == "table" then recepti_est[info][k] = {} for i, j in pairs(v) do recepti_est[info][k][i] = j end else recepti_est[info][k] = v end end -- end end end end end end return recepti_est,anom_name end -- проверяет рецепты и компонеты -- если все в порядке - запускает варку/мутацию function check_af_transform(af, af_sect, obj_pos, anom_id, anom_sect, anom_pos, anom_radius, lv, gv) counterAdd("amk_mod.check_af_transform") local actor = db.actor --поиск по аномалиям local finish = false -- флаг для вvхода из циклов for anom, recepti in pairs(anom_recept_komp["anomalii"]) do if string_find(anom_sect, anom) ~= nil then --нашли в списке аномалию, возле которой стоим local recepti_est = {} -- рецепты в наличии у ГГ, в которых участвует данный компонент local recept_podhodit = false -- собираем рецепты, в которых участвует данный компонент for info, recept in pairs(recepti["recepti"]) do if actor:has_info(info) and recept["komp"][af_sect] == true then --есть рецепт и этот компонент в нем участвует recept_podhodit = true -- копируем рецепт recepti_est[info] = {} for k, v in pairs(recept) do if type(v) == "table" then recepti_est[info][k] = {} for i, j in pairs(v) do recepti_est[info][k][i] = j end else recepti_est[info][k] = v end end -- так как table.getn() как и оператор # не работают с таблицами, у которых не целочисленные индексы, -- то считаем количество в ручнуі local count = 0 for k,v in pairs(recepti_est[info]["komp"]) do count = count + 1 end recepti_est[info]["count"] = count --get_console():execute("load ~#I#:"..string.format("0 "..af_sect.." przyjкte: "..anom.." rec. "..info.." "..recepti_est[info]["count"])) end end if recept_podhodit then -- если нашли хоть один имеющийся подходящий рецепт --amk.send_tip("рецепт подошел. anom_radius "..anom_radius," варка",0,15,"gen_info") --ищем рядом другие компоненты --если находим их в выбраннvх рецептах, то удаляем их из рецептов --как только какой-то рецепт остается без компонентов - рецепт сработал local obj for i=1,65534 do obj = level.object_by_id(i) if obj and alife():object(i) then local dist = obj:position():distance_to(anom_pos) if obj:parent() == nil and ((anom_radius - obj:position():distance_to(anom_pos)) > -5) then local obj_sect = obj:section() --get_console():execute("load ~#I#:"..string.format(" obj_sect: "..obj_sect.." dist: "..dist)) --проверяем отобраннvе рецептv for info, recept in pairs(recepti_est) do -- если компонент есть в рецепте if recepti_est[info]["komp"][obj_sect] == true then -- добавляем L- компонента для будущего удаления из игры recepti_est[info]["komp"][obj_sect] = obj:id() -- уменьшаем количество компонентов в рецепте recepti_est[info]["count"] = recepti_est[info]["count"] - 1 --amk.send_tip(obj_sect.." znalezione: "..anom.." rec. "..info.." "..recepti_est[info]["count"],"transmutacja",0,15,"gen_info") --get_console():execute("load ~#I#:"..string.format(obj_sect.." znalezione: "..anom.." rec. "..info.." "..recepti_est[info]["count"])) -- если рецепт пуст, то он сработал if recepti_est[info]["count"] == 0 then --get_console():execute("load ~#I#:"..string.format(info.." wykonane: "..anom)) -- устанавливаем все параметрv для рецепта, возможно из умолчаний local cel = get_af_transform_param("cel", recepti_est[info], recepti) local v_udachi = get_af_transform_param("v_udachi", recepti_est[info], recepti) local v_virogd = get_af_transform_param("v_virogd", recepti_est[info], recepti) local virogd = get_af_transform_param("virogd", recepti_est[info], recepti) local vremya = get_af_transform_param("vremya", recepti_est[info], recepti) local remove_anomaly = get_af_transform_param("remove_anomaly", recepti_est[info], recepti) local remove_anomaly_id = anom_id local komp = recepti_est[info]["komp"] local result, udacha = af_select_result(v_udachi, v_virogd, virogd, cel, komp) local info_portion = recepti_est[info]["info"] if cel == nil or v_udachi == nil or v_virogd == nil or virogd == nil or vremya == nil or remove_anomaly == nil or cel == nil and remove_anomaly == false or v_udachi + v_virogd > 100 then -- кривой рецепт - выходим finish = true break end -- неудача if udacha == false then remove_anomaly = false info_portion = nil end level.add_pp_effector("teleport.ppe", 1524, false) -- запускаем варку/мутацию --[[if info_portion then get_console():execute("load ~#I#: info_portion: "..info_portion) else get_console():execute("load ~#I#: info_portion: nil") end]] as_start_universal_transform_timer(komp, result, obj_pos, vremya, gv, lv, info_portion, remove_anomaly, remove_anomaly_id) -- удаляем из игры компоненты рецепта for k,v in pairs(komp) do alife():release(alife():object(v)) end -- выходим finish = true break end end end end end if finish then break end end end -- аномалия с рецептами найдена, все дела сделаны - выходим break end end end function af_flash(af) counterAdd("amk_mod.af_flash") level.add_pp_effector("teleport.ppe", 1524, false) amk.remove_item(af) end -- случайно выбирает результат, возвращает таблицу с секциями результатов function af_select_result(v_udachi, v_virogd, virogd, cel, komp) counterAdd("amk_mod.af_select_result") local rnd=math_random(0,100) if rnd > v_udachi then --неудача if rnd > v_virogd + v_udachi then return komp, false -- отторжение else return virogd, false -- вырождение end else -- удача -- get_console():execute("load ~#I#:"..string.format("Powodzenie"..amk.pack_array_to_string(cel))) return cel, true end end -- запускаем трансофрмацию -- результаты могут быть многочисленны (несколько целей, полное отторжение компонентов, несколько вырождений) function as_start_universal_transform_timer(komp, result, pos, vremya, gv, lv, info_portion, remove_anomaly, remove_anomaly_id) counterAdd("amk_mod.as_start_universal_transform_timer") -- преобразовываем имена в ID local resultIds = {} if result then for sect, _ in pairs(result) do table_insert(resultIds, afs_name_id[sect]) end end local kompIds = {} if komp then for sect, _ in pairs(komp) do table_insert(kompIds, afs_name_id[sect]) end end local t={} -- сохраняемые даннvе table_insert(t, resultIds) -- 1 table_insert(t, pos.x) -- 2 table_insert(t, pos.y) -- 3 table_insert(t, pos.z) -- 4 table_insert(t, gv) -- 5 table_insert(t, lv) -- 6 table_insert(t, info_portion or false) -- 7 table_insert(t, kompIds) -- 8 table_insert(t, remove_anomaly or false) -- 9 table_insert(t, remove_anomaly_id or false) -- 10 --get_console():execute("load ~#I#:"..string.format(" g_start_timer: "..vremya[1].." "..vremya[2].." "..vremya[3].." "..amk.pack_array_to_string(t))) amk.g_start_timer("af_transform_universal", vremya[1], vremya[2], vremya[3], t) end -- старая фунция function af_start_transform(v1,v2,af_from,af_target) counterAdd("amk_mod.af_start_transform") local rnd=math_random(0,100) if rnd>v1 then if rnd>v2+v1 then return af_from else return "af_buliz" end else return af_target end end -- старая фунция function af_start_transform_timer(af,pos,delay_d,delay_h,delay_m,af_sect) counterAdd("amk_mod.af_start_transform_timer") local t={} t.section=af t.pos={} t.pos.x=pos.x t.pos.y=pos.y t.pos.z=pos.z t.gv=gv t.lv=lv t.from_sect=af_sect amk.g_start_timer("af_transform",delay_d,delay_h,delay_m,t) end -- завершаем варку/мутацию -- может быть много результатов function af_transform_universal_end(params) counterAdd("amk_mod.af_transform_universal_end") --get_console():execute("load ~#I#:"..string.format(" af_transform_universal_end ")) -- если есть результаты local count = 0 if #params[1] > 0 then local anom_pos = vector():set(params[2], params[3], params[4]) if db.actor:position():distance_to(anom_pos) < 15 then level.add_pp_effector("teleport.ppe", 1524, false) end -- формируем строку с названиями компонентов local from_komp = "" local kompIds = params[8] for i = 1, #kompIds do if kompIds[i] then from_komp = from_komp..game.translate_string(amk.get_inv_name(afs_id_name[kompIds[i]]))..", " end end -- отсекаем ", " в хвосте from_komp = string_sub(from_komp, 1, -2) -- спавним результат(ы) local resultIds = params[1] for i = 1, #resultIds do local obj obj = amk.spawn_item(afs_id_name[resultIds[i]], vector():set(params[2],params[3],params[4]), params[5], params[6]) obj.first_online = true amk.add_spot_on_map(obj.id, "red_location", game.translate_string("trans_finished_title").." z %c[255,255,0,0]"..from_komp) end amk.send_tip(game.translate_string("trans_finished_title").." z %c[255,255,0,0]"..from_komp) end -- даем инфопорцию, если есть if params[7] and db.actor:dont_has_info(params[7]) then db.actor:give_info_portion(params[7]) end -- удаляем аномалию if params[9] then local sobj = alife():object(params[10]) if sobj and sobj.m_story_id == 4294967296 then alife():release(sobj, true) end end end -- старая функция function af_transform_end(params) counterAdd("amk_mod.af_transform_end") local from_sect="\""..params.from_sect.."\"" local obj obj=amk.spawn_item(params.section,vector():set(params.pos.x,params.pos.y,params.pos.z),params.gv,params.lv) amk.add_spot_on_map(obj.id,"red_location",game.translate_string("trans_finished_title").."%c[255,255,0,0]"..from_sect) amk.send_tip(game.translate_string("trans_finished_title").."%c[255,255,0,0]"..from_sect) end --'******************************************************************************* --' ** ** ** ** ** ** ** ** ** AMK_METKA ** ** ** ** ** ** ** ** ** --'******************************************************************************* local beakons={} function check_beacon_drop(obj) counterAdd("amk_mod.check_beacon_drop") local sim=not (alife()==nil) local actor=db~=nil and db.actor~=nil local lp=level.present() local dp=device()==nil or device():is_paused() if obj:section()=="amk_metka" then beakons[obj:id()]=true end end function check_metka() counterAdd("amk_mod.check_metka") for id,v in pairs(beakons) do local obj=level.object_by_id(id) if obj then beakons[id]=nil if obj:parent()==nil then local spwn=ui_dots.dots(get_hud(),id) level.start_stop_menu(spwn,true) end end end end local last_update=0 local inert = 1000 local clicks_prev = 200 music_section="" music_previous_section="" music_next_section_start_time=0 music_stop_previous=0 music=false music_init = 0 music_themes = {} music_phases={} musicflag=1 local music_objs={[1]=nil,[2]=nil} local music_stor={ enemy_see_actor=0, actor_see_enemy=0, enemy_hit_actor=0, actor_hit_enemy=0 } music_lo_lvl=7 music_hi_lvl=17 local music_graph={} function build_music_graph() counterAdd("amk_mod.build_music_graph") local skip = false local lname = level.name() local iniFileName = "scripts\\amk\\music\\music.ltx" local sect = "music_themes" local sini = g_ini_file(iniFileName) if sini and sini:section_exist(sect) then local result, id, value = nil, nil, nil for a=0,sini:line_count(sect)-1 do result, id, value = sini:r_line(sect,a,"","") if id~=nil and trim(id)~="" and trim(id)~=nil then id=trim(id) value1 = Parse_StrToTbl(value, "|") value={} for k,v in pairs(value1) do local tmp = Parse_StrToTbl(v, "=") value[tmp[1]]=tmp[2] end if value.map then local t = Parse_StrToTbl(value.map, ",") for kk,vv in pairs(t)do skip = skip or vv == lname end skip = not skip else skip = false end if not skip then table.insert(music_themes, id) --local t = amk.parse_ini_section_to_array(sini,id.."_music_files") local t = amk.parse_ini_section_to_array_new(iniFileName,id.."_music_files") t.null = "" for k,v in pairs(t) do music_phases[id.."_"..k]=v if not music_graph[id.."_"..k] then music_graph[id.."_"..k] = {} end --local tt = amk.parse_ini_section_to_array(sini,id.."_graph_"..k) local tt = amk.parse_ini_section_to_array_new(iniFileName,id.."_graph_"..k) for kk,vv in pairs(tt) do local tmp = Parse_StrToTbl(vv,",") local lvl = tmp[1] lvl = amk_mod["music_"..lvl.."_lvl"] music_graph[id.."_"..k][id.."_"..kk] = {lvl,tmp[2]} end end end end end if #music_themes > 0 then return true else return false end end return false end function music_start(sound) counterAdd("amk_mod.music_start") if not music then if music_objs[1]==nil then music_objs[1]=amk_music.amk_music() end if music_objs[2]==nil then music_objs[2]=amk_music.amk_music() end music_objs[musicflag]:initialize(music_phases[sound]) music_next_section_start_time=music_objs[musicflag]:play()-200 music_previous_section=music_section musicflag=3-musicflag end music = true end function music_change(sound) counterAdd("amk_mod.music_change") if music then music_objs[musicflag]:initialize(music_phases[sound]) music_next_section_start_time=music_objs[musicflag]:play_at_time(music_next_section_start_time+200)-200 musicflag=3-musicflag music_previous_section=music_section end end function interactive_music() counterAdd("amk_mod.interactive_music") amk.oau_reason="music begin" --- ex_horror ------------------------------------------------------------- if amk.load_variable("horror",-1)>=0 and amk.load_variable("horror",-1)<=7 then music_init=-1 return end --- ex_horror ----------------------------------------------------- end --- if not game_options.interative_music or amk_music == nil then return end if music_init==-1 then return end if music_init==0 then if build_music_graph() then music_init=1 else music_init=-1 return end end if not music then if time_global() - last_update > inert then music_select_section(inert) last_update = time_global() end if music_previous_section=="" and music_section~="" then music_start(music_section) end else if music_previous_section~="" and music_section=="" then music_previous_section="" end music_objs[1]:update() music_objs[2]:update() if time_global() > music_next_section_start_time then music_select_section(music_objs[musicflag]:length()) if music_section~="" then music_change(music_section) else music=false end end end amk.oau_reason="" end function reset_music_cntrs(c) counterAdd("amk_mod.reset_music_cntrs") music_stor.actor_see_enemy = music_stor.actor_see_enemy - 2 * c music_stor.enemy_see_actor = music_stor.enemy_see_actor - 2 * c music_stor.actor_hit_enemy = music_stor.actor_hit_enemy - 8 * c music_stor.enemy_hit_actor = music_stor.enemy_hit_actor - 4 * c if music_stor.actor_see_enemy < 0 then music_stor.actor_see_enemy = 0 elseif music_stor.actor_see_enemy > music_lo_lvl then music_stor.actor_see_enemy = music_lo_lvl end if music_stor.enemy_see_actor < 0 then music_stor.enemy_see_actor = 0 elseif music_stor.enemy_see_actor > music_lo_lvl then music_stor.enemy_see_actor = music_lo_lvl end if music_stor.actor_hit_enemy < 0 then music_stor.actor_hit_enemy = 0 elseif music_stor.actor_hit_enemy > music_hi_lvl then music_stor.actor_hit_enemy = music_hi_lvl end if music_stor.enemy_hit_actor < 0 then music_stor.enemy_hit_actor = 0 elseif music_stor.enemy_hit_actor > music_hi_lvl then music_stor.enemy_hit_actor = music_hi_lvl end end local shoot_helper = 0 function calc_adrenaline(act,obj,typ) counterAdd("amk_mod.calc_adrenaline") --- ex_horror ------------------------------------------------------------- if music_init==-1 then music_init=0 end --- ex_horror ----------------------------------------------------- end --- local dist = obj:position():distance_to(db.actor:position()) if act=="actor_see_enemy" then music_stor.actor_see_enemy=music_stor.actor_see_enemy+50/dist elseif act=="enemy_see_actor" then music_stor.enemy_see_actor=music_stor.enemy_see_actor+50/dist elseif act=="actor_hit_enemy" then if time_global()>shoot_helper then music_stor.actor_hit_enemy=music_stor.actor_hit_enemy+13 shoot_helper=time_global()+500 end elseif act=="enemy_hit_actor" then music_stor.enemy_hit_actor=music_stor.enemy_hit_actor+8 end end function music_select_section(time) counterAdd("amk_mod.music_select_section") reset_music_cntrs(time/inert) local cs = music_section local eseen = music_stor.enemy_see_actor if eseen >= music_lo_lvl then eseen = music_lo_lvl end local aseen = music_stor.actor_see_enemy if aseen >= music_lo_lvl then aseen = music_lo_lvl end local ehits = music_stor.enemy_hit_actor if ehits >= music_hi_lvl then ehits = music_hi_lvl end local ahits = music_stor.actor_hit_enemy if ahits >= music_hi_lvl then ahits = music_hi_lvl end local lvl = aseen + eseen if lvl>music_hi_lvl*0.75 then lvl=music_hi_lvl*0.75 end lvl = ehits + lvl + ahits if music_section=="" then music_section=music_themes[math_random(#music_themes)].."_null" end local last_sel_max=0 local last_sel_min=1000 for k,v in pairs(music_graph[music_section]) do if v[2]=="<" and v[1]lvl then music_section=k last_sel_min=v[1] end end if v[2]==">" and v[1]>=last_sel_max then if v[1]<=lvl then music_section=k last_sel_max=v[1] end end end if string_find(music_section,"null") then music_section="" end if music and music_previous_section~="" and music_section=="" then music_previous_section="" end --[[local l=0 if music and music_objs[musicflag]~=nil then l=music_objs[musicflag]:length() -- и что дальше ? sapsan end]] end --'******************************************************************************* --' ** ** ** ** ** ** ** ** ** BLOWOUT ** ** ** ** ** ** ** ** ** --'******************************************************************************* ---- *** Выброс *** ---- --[[ Таблицы: blow_damages - мощность хита в зависимости от удаления от ЧАЭС blow_psy_sounds - локации, на которых будет проигрываться пси-звук blow_setting - время фаз {фазы хита, предшествующие фазы} blow_sounds - амбиент выброса blow_types - тип локации: 0 - в полном объеме, 1 - частичные эффекты, 2 - нет выброса Сохраняемые переменные: blow_time - время фазы(используется в blowout_scheme.script) blowout - номер фазы выброса Таймеры: blow_shift - времени до следующего выброса blowout - время до следующей фазы blowout_ss - на проигрывание амбиента phantom_init - на спавн фантомов Функции: Run_Blowout_pp - старт выброса Blowout_pp - эффекты для выброса: -- Начало: 1минута, нпс встревожены, убираем аномалии, меняем погоду -- Первая фаза: звук сопровождаемый кратковременной тряской, 1-е сообщение, нпс спокойно идут в укрытия -- Вторая фаза: нпс бегом в укрытия, гром, включается тряска -- Третья фаза: - наносим хит, включаем фантомов -- Четвёртая фаза: - убираем тряску, остаточная радиация -- Пятая фаза: - убираем все эффекты -- Окончание Выброса: - спавним аномалии, меняем погоду blowout_hours - определение времени суток blowout_psy_sound - проигрывание пси-звука blowout_scary_sounds - проигрывание амбиента blowout_type - определяем тип локации start_blow_timer - запуск таймера до следующего выброса check_blowout_on_load - перезапуск хита при загрузке check_npc_in_hideout - проверка, что объект в укрытии on_blowout_hit_actor - наносим хит актеру on_blowout_hit - наносим хит неписям --]] local blow_damages = { l01_escape = 0.02, l02_garbage = 0.07, l03_agroprom = 0.05, l04_darkvalley = 0.1, l05_bar = 0.25, l06_rostok = 0.25, l07_military = 0.35, l08_yantar = 0.2, l10_radar = 0.4, l11_pripyat = 0.6, l12_stancia = 0.8, atp_for_test22 = 0.35, aver = 0.15, dead_city = 0.3, generators = 0.7, hospital = 0.55, jupiter = 0.35, limansk = 0.45, lost_village = 0.5, marsh = 0.02, pripyat = 0.5, puzir = 0.0, red_forest = 0.4, zaton = 0.35, la15_darkscape = 0.0 } local blow_psy_sounds = { dead_city = true, generators = true, hospital = true, jupiter = true, l08_yantar = true, l10_radar = true, l11_pripyat = true, l12_stancia = true, limansk = true, lost_village = true, pripyat = true, red_forest = true, zaton = true } local blow_setting = { l01_escape = {1,4}, l02_garbage = {1.5,3.75}, l03_agroprom = {1.25,3.75}, l03u_agr_underground = {1.25,3.75}, l04_darkvalley = {1.5,3.75}, l04u_labx18 = {1.5,3.75}, l05_bar = {2.25,3.5}, l06_rostok = {2.25,3.5}, l07_military = {3,3.25}, l08_yantar = {2,3.5}, l08u_brainlab = {2,3.5}, l10_radar = {3.5,3}, l10u_bunker = {3.5,3}, l11_pripyat = {4.25,3}, l12_stancia = {5,1.5}, l12_stancia_2 = {5,1.5}, l12u_control_monolith = {5,1.5}, l12u_sarcofag = {5,1.5}, atp_for_test22 = {3,3.25}, av_peshera = {1.75,3.75}, aver = {1.75,3.75}, dead_city = {2.75,3.25}, generators = {4.5,1.75}, hospital = {4.25,2}, jupiter = {3,3.25}, jupiter_underground = {3,3.25}, labx8 = {3,3.25}, limansk = {3.75,2.75}, lost_village = {4,2.25}, marsh = {1,4}, peshera = {1.5,3.75}, pripyat = {4,2.25}, puzir = {1.25,3.75}, red_forest = {3.5,3}, warlab = {3.5,3}, zaton = {3,3.25}, mine = {2.25,3.5}, la15_darkscape = {1.25,3.75} } local blow_sounds = { "ambient\\rnd_outdoor\\rnd_dark", "ambient\\rnd_outdoor\\rnd_dark0", "ambient\\rnd_outdoor\\rnd_dark1", "ambient\\rnd_outdoor\\rnd_dark2", "ambient\\rnd_outdoor\\rnd_dark3", "ambient\\rnd_outdoor\\rnd_dark4", "ambient\\rnd_outdoor\\rnd_dark5", "ambient\\rnd_outdoor\\rnd_dark6", "ambient\\rnd_outdoor\\rnd_dark7", "ambient\\rnd_outdoor\\rnd_dark8", "ambient\\rnd_outdoor\\rnd_dark9", "ambient\\rnd_outdoor\\rnd_dark10", "ambient\\rnd_outdoor\\rnd_darkwind1", "ambient\\rnd_outdoor\\rnd_darkwind2", "ambient\\rnd_outdoor\\rnd_darkwind3", "ambient\\rnd_outdoor\\rnd_darkwind4", "ambient\\rnd_outdoor\\rnd_darkwind5", "ambient\\rnd_outdoor\\rnd_darkwind6", "ambient\\rnd_outdoor\\rnd_horror", "ambient\\rnd_outdoor\\rnd_horror1", "ambient\\random\\rnd_the_horror2", "nature\\rt_ambient1", "nature\\rt_ambient2", "nature\\thunder-3" } local blow_types = { l01_escape = 0, l02_garbage = 0, l03_agroprom = 0, l03u_agr_underground = 1, l04_darkvalley = 0, l04u_labx18 = 1, l05_bar = 2, l06_rostok = 0, l07_military = 0, l08_yantar = 0, l08u_brainlab = 1, l10_radar = 0, l10u_bunker = 1, l11_pripyat = 0, l12_stancia = 2, l12_stancia_2 = 2, l12u_control_monolith = 2, l12u_sarcofag = 2, atp_for_test22 = 0, av_peshera = 1, aver = 0, dead_city = 0, generators = 0, hospital = 0, jupiter = 0, jupiter_underground = 1, labx8 = 1, limansk = 0, lost_village = 0, marsh = 0, peshera = 1, pripyat = 0, puzir = 2, red_forest = 0, warlab = 1, zaton = 0, mine = 1, la15_darkscape = 2 } local snd_obj_right,snd_obj_left,snd_obj_eq function Run_Blowout_pp() counterAdd("amk_mod.Run_Blowout_pp") local horr = amk.load_variable("horror",-1) local blow_type = blowout_type() if not game_options.run_blowout_pp or blow_type == 2 or (horr > 0 and horr < 7) or (sleep_manager.is_sleep_active() and blow_type > 0) then start_blow_timer() --get_console():execute("load ~#blowout#: Run_Blowout_pp() restart timer") return end if sleep_manager.is_sleep_active() then amk.save_variable("gg_need_sleep",80) sleep_manager.stopper() end amk.save_variable("blowout",1) local actor = db.actor local snd_obj = xr_sound.get_safe_sound_object([[ambient\organic_moan1]]) level.add_cam_effector("camera_effects\\shell_shock.anm",2004,false,"") if blow_type < 1 then level.add_pp_effector("monolith_off.ppe",2003,false) snd_obj:play_no_feedback(actor,sound_object.s2d,0,vector(),1) else snd_obj:play_no_feedback(db.actor, sound_object.s2d,0,vector(),0.5) end amk.start_timer("blowout",11,0) amk.start_timer("blowout_ss",math_random(1,3),0) start_blow_timer() --get_console():execute("load ~#blowout#: Run_Blowout_pp() end") end function Blowout_pp(phase) counterAdd("amk_mod.Blowout_pp") local actor = db.actor local lname = level.name() local blow_time = blow_setting[lname][2] + (math_random() - 0.5) local hit_time = blow_setting[lname][1] + (math_random() - 0.5) local blow = amk.load_variable("blowout",-1) local blow_type = blowout_type() local hours_type = blowout_hours() local snd_obj if phase == 0 then level.set_weather(hours_type.."_blow",true) if blow_type < 1 then level.set_weather_fx("surge_"..hours_type.."_0") amk_anoms.pre_blow_off() else level.set_weather_fx("isurge_"..hours_type.."_0") end amk.g_start_timer("blowout",0,0,1,1) elseif phase == 1 then amk.save_variable("blowout",2) snd_obj = xr_sound.get_safe_sound_object([[ambient\earthquake]]) level.add_cam_effector("camera_effects\\shell_shock.anm",2004,false,"") if blow_type < 1 then level.set_weather_fx("surge_"..hours_type.."_1") ex_news.news_blow() snd_obj:play_no_feedback(actor,sound_object.s2d,0,vector(),1) else level.set_weather_fx("isurge_"..hours_type.."_1") snd_obj:play_no_feedback(actor,sound_object.s2d,0,vector(),0.5) end blowout_psy_sound(true) amk.g_start_timer("blowout",0,0,blow_time,2) elseif phase == 2 then amk.save_variable("blowout",3) snd_obj = xr_sound.get_safe_sound_object([[anomaly\blowout]]) if blow_type < 1 then level.set_weather_fx("surge_"..hours_type.."_2") ex_news.news_blow() snd_obj:play_no_feedback(actor,sound_object.s2d,0,vector(),1) else level.set_weather_fx("isurge_"..hours_type.."_2") snd_obj:play_no_feedback(actor,sound_object.s2d,0,vector(),0.3) end level.add_cam_effector("camera_effects\\earthquake.anm",2002,true,"") amk.g_start_timer("blowout",0,0,blow_time,3) elseif phase == 3 then amk.save_variable("blowout",4) if blow_type < 1 then level.set_weather_fx("surge_"..hours_type.."_3") local h = hit() local cr h.type = hit.strike h.power = 1000 h.impulse = 1000 for a = 1,65534,1 do cr = level.object_by_id(a) if cr and cr:section() == "m_crow" and math_random(0,100) < 50 then h.draftsman = cr h.direction = cr:direction() cr:hit(h) end end else level.set_weather_fx("isurge_"..hours_type.."_3") end bind_stalker.task_add("amk_mod.on_blowout_hit_actor",amk_mod.on_blowout_hit_actor,1000) amk.start_timer("phantom_init",math.random(1,3),0) amk.g_start_timer("blowout",0,0,hit_time,4) elseif phase == 4 then amk.save_variable("blowout",5) blowout_psy_sound(false) if blow_type < 1 then level.set_weather_fx("surge_"..hours_type.."_4") else level.set_weather_fx("isurge_"..hours_type.."_4") end level.remove_cam_effector(2002) amk.g_start_timer("blowout",0,0,hit_time,5) elseif phase == 5 then amk.save_variable("blowout",6) if blow_type < 1 then if game_options.zombie_team then tag_spb.zombie_team() end level.add_pp_effector("monolith_off.ppe",2003,false) end bind_stalker.task_delete("amk_mod.on_blowout_hit_actor",1000) amk.start_timer("blowout",11,6) elseif phase == 6 then if blow_type < 1 then amk_anoms.after_blow_on() end local weather_manager = level_weathers.get_weather_manager() weather_manager:weather_set() amk.del_variable("blowout") amk.del_variable("blow_time") end amk.save_variable("blow_time",blow_time) return blow_time end function blowout_hours() counterAdd("amk_mod.blowout_hours") -- Тип времени суток local hours = level.get_time_hours() if hours > 5 and hours < 21 then return "d" elseif hours > 22 or hours < 4 then return "n" end return "m" end function blowout_psy_sound(action) counterAdd("amk_mod.blowout_psy_sound") local actor = db.actor if action then snd_obj_eq = sound_object([[ambient\earthquake]],sound_object.looped + sound_object.s2d) snd_obj_eq:play(actor,4,sound_object.looped + sound_object.s2d) else if snd_obj_eq then snd_obj_eq:stop() end end local psy_sound = game_options.psy_sounds and blow_psy_sounds[level.name()] if not psy_sound then return end if action then snd_obj_right, snd_obj_left = xr_sound.get_sound_object("psy_voices","random") snd_obj_left:play_at_pos(actor,vector():set(-1,0,1),0,sound_object.s2d + sound_object.looped) snd_obj_right:play_at_pos(actor,vector():set(1,0,1),0,sound_object.s2d + sound_object.looped) else if snd_obj_left then snd_obj_left:stop() end if snd_obj_right then snd_obj_right:stop() end end end function blowout_scary_sounds() counterAdd("amk_mod.blowout_scary_sounds") local blow = amk.load_variable("blowout",-1) if blow > 0 and blow < 6 then local actor = db.actor local count = #blow_sounds local snd_obj = xr_sound.get_safe_sound_object(blow_sounds[math_random(count)]) local a = vector() a.x = 10 - math_random(0,20) a.y = 10 - math_random(0,20) a.z = 10 - math_random(0,20) snd_obj:play_at_pos(actor, actor:position():add(a)) amk.start_timer("blowout_ss",math_random(10,30),0) end end function blowout_type() counterAdd("amk_mod.blowout_type") return blow_types[level.name()] or 2 end function start_blow_timer() counterAdd("amk_mod.start_blow_timer") local resuls = 2400 + ((math_random()*3000) - 1200) amk.g_start_timer("blow_shift",0,0,resuls) if (news_main and news_main.next_blow) then news_main.next_blow(resuls) end end function check_blowout_on_load() local blow = amk.load_variable("blowout",-1) local blow_type = blowout_type() if blow_type > 0 or blow < 4 or blow > 5 then return end bind_stalker.task_delete("amk_mod.on_blowout_hit_actor",1000) bind_stalker.task_add("amk_mod.on_blowout_hit_actor", amk_mod.on_blowout_hit_actor, 1000) end function check_npc_in_hideout(npc,hide) counterAdd("amk_mod.check_npc_in_hideout") local in_zone = false if hide and hide.zone then for k,v in pairs(hide.zone) do if v.p3 then in_zone = amk.check_npc_in_box(npc,vector():set(unpack(v.p1)),vector():set(unpack(v.p2)),vector():set(unpack(v.p3))) else in_zone = amk.check_npc_in_box(npc,vector():set(unpack(v.p1)),vector():set(unpack(v.p2))) end if in_zone then break end end end return in_zone end function on_blowout_hit_actor() counterAdd("amk_mod.on_blowout_hit_actor") on_blowout_hit(db.actor) end function on_blowout_hit(npc,hide) counterAdd("amk_mod.on_blowout_hit") local blow = amk.load_variable("blowout",-1) local blow_type = blowout_type() if blow_type > 0 or blow < 4 or blow > 5 then return false end local lname = level.name() local need_hit = false if hide and hide.zone then need_hit = check_npc_in_hideout(npc,hide) else local hides = amk_hideouts.hide[lname] if hides then for k,v in ipairs(hides) do need_hit = check_npc_in_hideout(npc,v) if need_hit then break end end end end if not need_hit then if blow == 4 then local h = hit() h.power = blow_damages[lname]/3 or 0.01 h.impulse = 0 h.draftsman = npc h.direction = vector():set(0,0,0) h:bone("bip01_spine") h.type = hit.strike npc:hit(h) h.type = hit.telepatic npc:hit(h) h.type = hit.radiation npc:hit(h) elseif blow == 5 then local h = hit() h.power = blow_damages[lname]/3 or 0.01 h.impulse = 0 h.draftsman = npc h.direction = vector():set(0,0,0) h:bone("bip01_spine") h.type = hit.radiation npc:hit(h) end end return not need_hit end --'******************************************************************************* --' ** ** ** ** ** ** ** ** ** RECEPTS ** ** ** ** ** ** ** ** ** --'******************************************************************************* function check_usable_item(obj) counterAdd("amk_mod.check_usable_item") local info=nil if obj:name()=="mil_stalker0012" then info="info_amk_recipt_stone_dikoobraz" elseif level.name()=="l01_escape" and obj:section()=="amk_zapiska" then info="info_amk_recipt_shkura" amk.drop_item(db.actor,obj) amk.remove_item(obj) elseif level.name()=="l04u_labx18" and obj:section()=="amk_zapiska" then info="info_amk_recipt_simbion" amk.drop_item(db.actor,obj) amk.remove_item(obj) elseif level.name()=="l08u_brainlab" and obj:section()=="amk_zapiska" then local infos = { "info_amk_recipt_dummy", "info_amk_recipt_dummy_fire", "info_amk_recipt_dummy_bright", "info_amk_recipt_dummy_moon", "info_amk_recipt_dummy_puding" } amk.drop_item(db.actor,obj) amk.remove_item(obj) if db.actor==nil then return end local info_given = false for i=1,#infos do local inf = infos[i] if db.actor:dont_has_info(inf) then db.actor:give_info_portion(inf) info_given = true end end if info_given then amk_dialogs.info_received() end return else local recipes=amk.load_table("amk_body_recipe") info=recipes[obj:id()] end if db.actor==nil or info==nil or db.actor:has_info(info) then return end db.actor:give_info_portion(info) amk_dialogs.info_received() end function generate_recipe(obj) counterAdd("amk_mod.generate_recipe") if obj and IAmAMonster[obj:clsid()] then return end local info=nil local prop=100 if level.name()=="l10_radar" and obj.character_community and obj:character_community()=="monolith" then info="info_amk_recipt_controller_skalp" prob=25 end if not info then return end local recipes=amk.load_table("amk_body_recipe") for k,v in pairs(recipes) do -- проверим не генерился ли уже этот рецепт if v == info then return end end -- сгенерим рецепт if math_random(100)<=prob then recipes[obj:id()]=info amk.save_table("amk_body_recipe",recipes) end end --'******************************************************************************* --' ** ** -- Dynamic HUD Gift from ATT, Arhara and Kolmogor -- ** ** --'******************************************************************************* -- чтобы отключить эффект, поставьте вместо единицы ноль: --local suithud_enable = 0 -- худ костюма --local blurs_enable = 1 -- эффект запотевания --local blood_enable = 1 -- эффект ранения --local bleed_enable = 1 -- эффект плохого самочувствия -- перенесено в game_options (sapsan) local otladka = 0 -- вывод в лог -------------------------------------------------------------------------------- local suitHudName_wotType = { ["bandit_gaz_outfit_"] = "hud_gaz", ["dolg_gaz_outfit_"] = "hud_gaz", ["monolit_gaz_outfit_"] = "hud_gaz", ["neytral_exo_gaz_outfit_"] = "hud_gaz", ["neytral_gaz_outfit_"] = "hud_gaz", ["neytral_novice_gaz_outfit_"] = "hud_gaz", ["outfit_svoboda_"] = "hud_gaz", ["svoboda_gaz_outfit_"] = "hud_gaz", ["svoboda_heavy_gaz_outfit_"] = "hud_gaz", ["dolg_scientific_outfit"] = "hud_sci", ["scientist_suit_white"] = "hud_sci", ["fire_outfit"] = "hud_sci", ["ecolog_outfit"] = "hud_sci", ["freedom_scientific_outfit"] = "hud_sci", ["merc_scientific_outfit"] = "hud_sci", ["monolit_scientific_outfit"] = "hud_sci", ["protection_outfit"] = "hud_sci", ["nebo_exo_outfit"] = "hud_sci", ["nebo_scientific_outfit"] = "hud_sci", ["scientific_outfit"] = "hud_sci", ["killer_gaz_outfit_"] = "hud_merc", ["outfit_killer_"] = "hud_merc", ["military_outfit"] = "hud_mil", ["militaryspec_outfit"] = "hud_mil", ["outfit_specnaz_"] = "hud_mil", ["specops_outfit"] = "hud_mil", ["broken_exoskeleton"] = "hud_exo", ["dolg_black_exoskeleton"] = "hud_exo", ["exo_bandit_outfit"] = "hud_exo", ["exo_outfit"] = "hud_exo", ["killer_blue_exoskeleton"] = "hud_exo", ["military_exo_outfit"] = "hud_exo", ["monolit_exoskeleton"] = "hud_exo", ["neytral_exo_antigas_outfit"] = "hud_exo", ["outfit_exo_"] = "hud_exo", ["svoboda_exoskeleton"] = "hud_exo", ["svoboda_yellow_exo_outfit_"] = "hud_exo" } local freemem = 0 local freemem2 = 0 function doabcevents() counterAdd("amk_mod.doabcevents") if db.actor ~= nil then local chkfreetime = time_global() if freemem == 0 then freemem = chkfreetime + 1000 end if chkfreetime > freemem then freemem = 0 check_hud() end if freemem2 == 0 then freemem2 = chkfreetime + 40 end if chkfreetime > freemem2 then freemem2 = 0 init_blurs() end end end local current_suithud local mycurrent_suithud local suit_condition local wotsuittype = "" --local smoktime = 0 function check_hud() counterAdd("amk_mod.check_hud") if not game_options.suithud_enable then setmysuithud(nil) return end if db.actor ~= nil then local csuithud = db.actor:get_current_outfit() local suithudtype, isitbino, suithudname if csuithud ~= nil then suithudname = csuithud:section() end if suithudname ~= nil then local cond = csuithud:condition() suit_condition = "" if cond > 0.87 then suit_condition = "blue" elseif cond > 0.69 then suit_condition = "green" elseif cond > 0.60 then suit_condition = "yellow" elseif cond > 0.40 then suit_condition = "red" elseif cond > 0.25 then suit_condition = "red2" else suit_condition = "red3" end if otladka ~= 0 then get_console():execute("load ~~~ suithudname: "..suithudname) end for k,v in pairs(suitHudName_wotType) do if string_find(suithudname, k) then suithudtype = v.."_"..suit_condition wotsuittype = v if otladka ~= 0 then get_console():execute("load ~~~ found suithudname: "..suithudname.." key: "..k.." type: "..v) end break end end else suithudtype = nil end if not db.actor:alive() then suithudtype = nil end setmysuithud(suithudtype) end end local suitfirstrun = "yes" function setmysuithud(hudtype) counterAdd("amk_mod.setmysuithud") local hud = get_hud() if hudtype == nil then local wchud = hud:GetCustomStatic(mycurrent_suithud) if wchud ~= nil then hud:RemoveCustomStatic(mycurrent_suithud) end mycurrent_suithud = nil suitfirstrun = "yes" return end if hudtype ~= mycurrent_suithud then if mycurrent_suithud then hud:RemoveCustomStatic(mycurrent_suithud) end if hudtype then hud:AddCustomStatic(hudtype) if string_find(hudtype, wotsuittype) then if suitfirstrun == "no" and suit_condition ~= "green" and suit_condition ~= "blue" then local snd_obj = sound_object("material\\glass\\glass_fall03hl") snd_obj:play_no_feedback(db.actor, sound_object.s2d, 0, vector(), 9.0) end if suitfirstrun == "yes" then suitfirstrun = "no" end end end mycurrent_suithud = hudtype end end function init_blurs() counterAdd("amk_mod.init_blurs") if not game_options.suithud_enable or not game_options.suithud_blurs_enable then set_blurs(false) return end if mycurrent_suithud ~= nil and not string_find(mycurrent_suithud,"_red3") and not string_find(mycurrent_suithud,"hud_sci_") then local zoom=67.5/device().fov zoom=(zoom-1)*1.5+1 if zoom<1.001 then zoom=1.001 end local stretchy=0.75/(math_floor(device().aspect_ratio*1000)/1000) if stretchy<1 then stretchy=1 end local rect={x=-768*zoom+768,y=(-512*zoom+512)*stretchy-(stretchy-1)*300,w=1024*zoom,h=768*zoom*stretchy} set_blurs(true,rect) else set_blurs(false) end end local blurs={} local blurval=0 -- уровень запотевания от 0 до 1 local blurlt=0 -- время последнего обновления local blurcyctime=0 -- время начала последнего цикла дыхания (выдох) local blurlastphase=0 local hud_blur_names = {"hud_blur1","hud_blur2","hud_blur3","hud_blur4","hud_blur5"} function set_blurs(enabled,rect) counterAdd("amk_mod.set_blurs") local hud = get_hud() if not enabled then if #blurs > 0 then for i=1,4 do hud:RemoveCustomStatic(hud_blur_names[i]) --blurs[i]:SetWidth(0) end blurs = {} end return end if #blurs == 0 then --blurs={} local blurs_icon for i=1,4 do blurs_icon = hud:AddCustomStatic(hud_blur_names[i]) blurs[i] = blurs_icon:wnd() blurs[i]:SetWidth(0)-- что за хрень ? похоже на инициализацию и припрятывание на потом :) sapsan end end -- Циклы в зависимости от силы дыхания: 0->1->0 0->1->2->4->5->0 0->1->2->3->4->5->0 5->4->3->4->5 4->3->4 local power=db.actor.power local period=1.0+power*power*1.0 -- текущая частота дыхания от 30 до 120 циклов в минуту local expirt=0.3 local breathpower=3 local t = time_global() local delta=(t-blurlt)/1000 -- дельта в секундах local phase=(t-blurcyctime)/1000 -- фаза дыхательного цикла в сек. blurlt=t if phase>period then phase=phase%period blurcyctime=blurlt-phase*1000 end if blurlastphase>phase then blurlastphase=0 end local blurdelta=delta*-0.7 -- работа вентиляции if blurlastphase0.999 then blurval=0.999 elseif blurval<0 then blurval=0 end local tm=math_floor(blurval*3) local tmn=(tm+1) local v=blurval*3-math_floor(blurval*3) v=1-v local v1=1-v if tm~=0 then blurs[tm]:SetColor(GetARGB(v*255,255,255,255)) end if tmn~=0 then blurs[tmn]:SetColor(GetARGB(v1*255,255,255,255)) end for i=1,4 do if i==tm or i==tmn then blurs[i]:SetWndRect(Frect():set(rect.x,rect.y,rect.w,rect.h)) else blurs[i]:SetWndRect(Frect():set(rect.x,rect.y,0,0)) end end end --' ** ** ** ** ** ** ** ** SPAWN_OBJ ** ** ** ** ** ** ** ** ** function spawn_fuel() counterAdd("amk_mod.spawn_fuel") local ballons = { {-92.21, -1.18, -212.66, 115177, 268}, {-74.17, 1.80, 8.45, 127766, 329}, {3.18, 1.24, 42.48, 243919, 490}, {15.35, -1.90, 2.40, 255433, 479}, {77.54, 0.30, -108.47, 312366, 427}, {-145.54, -0.00, -199.61, 92520, 650}, {-130.08, 10.00, -196.67, 109214, 629}, {-140.13, 10.00, -197.94, 98647, 629}, {37.28, 1.02, -49.90, 220638, 1084}, {476.68, -46.94, -0.23, 155714, 1919}, {76.80, -2.54, -23.93, 36304, 1970}, {94.78, 0.03, -6.88, 88986, 1514}, {-3.24, -11.75, -263.07, 33794, 1448} } local kanisters = { {-69.94, 0.97, 6.51, 131411, 329}, {64.01, 0.60, 148.46, 235341, 364}, {63.29, -0.20, 5.10, 299326, 461}, {-28.52, -1.04, -181.84, 211644, 676}, {2.93, -1.88, -13.30, 176553, 1047}, {41.71, 4.54, -86.36, 227110, 1100}, {7.90, 1.41, -71.93, 183138, 1041}, {158.71, -0.76, -259.73, 358950, 962}, {-342.92, -13.60, 390.01, 11235, 1847}, {305.22, -36.99, -24.40, 68330, 1930}, {55.02, 1.17, 40.35, 68094, 1511}, {-114.14, -0.00, 121.75, 43453, 1315}, {31.33, 5.60, -13.51, 4683, 1538} } local sim = alife() for k,v in pairs(ballons) do if #v == 5 then local obj = sim:create("amk_ballon",vector():set(v[1], v[2], v[3]), v[4], v[5]) end end for k,v in pairs(kanisters) do if #v == 5 then local obj = sim:create("amk_kanistra",vector():set(v[1], v[2], v[3]), v[4], v[5]) end end end --'******************************************************************************* --' ** ** ** ** ** ** ** ** AMK_RESPAWNS ** ** ** ** ** ** ** ** --'******************************************************************************* local respawners={} function spawn_unspawned_respawners_single(sobj) counterAdd("amk_mod.spawn_unspawned_respawners_single") local oini = sobj:spawn_ini() if oini:line_exist ("respawn", "amk_name") == true then local amk_name = utils.cfg_get_string(oini, "respawn", "amk_name", false, false, false, false) if amk_name then respawners[amk_name] = true --get_console():execute("load ~~~ respawners: "..amk_name) end end --get_console():execute("load ~~~ respawners... "..sobj.id) end function spawn_unspawned_respawners_2() counterAdd("amk_mod.spawn_unspawned_respawners_2") --amk.dump_table(respawners, 1, "respawners: ") local sim = alife() local iniFileName = "scripts\\amk\\amk_respawns.ltx" local sini = g_ini_file(iniFileName) -- local dv={} -- if iniLineSectionExist("default_values", iniFileName) then -- local result, id, value = nil, nil, nil -- for a=0,iniLinesCount("default_values", iniFileName)-1 do -- result, id, value = getIniLine("default_values",a,"","", iniFileName) -- if id~=nil and trim(id)~="" and trim(id)~=nil then -- dv[trim(id)]=trim(value) -- end -- end -- end if sini:section_exist("amk_respawns") then local tmp={} local result, id, value = nil, nil, nil local table_insert = table.insert for a=0,sini:line_count("amk_respawns")-1 do result, id, value = sini:r_line("amk_respawns",a,"","") if id~=nil and trim(id)~="" and trim(id)~=nil then table_insert(tmp, trim(id)) end end --for k,v in pairs(tmp) do local v for i = 1, #tmp do v = tmp[i] local flag = utils.cfg_get_bool(sini, "amk_respawns", v, true, false, false) -- if not respawners[v] and flag==true then --local t = amk.parse_ini_section_to_array(sini, v) local t = amk.parse_ini_section_to_array_new(iniFileName, v) local xyzlg = Parse_StrToTbl(t.xyzlg,",") local pos = vector():set(tonumber(xyzlg[1]),tonumber(xyzlg[2]),tonumber(xyzlg[3])) local respawner = amk.spawn_item("respawn",pos,tonumber(xyzlg[5]),tonumber(xyzlg[4])) local tbl = amk.get_spawner_data(respawner) t.xyzlg = nil t.amk_name = v -- for kkk,vvv in pairs(dv) do -- if t[kkk]==nil then -- t[kkk]=vvv -- end -- end tbl.custom = amk.gen_custom_data({respawn=t}) amk.set_spawner_data(tbl, respawner) se_respawn.respawn_params(respawner) --amk.add_spot_on_map(respawner.id,"red_location", v) -- end -- if flag==false then -- local o = se_respawn.get_respawner_by_name(v) -- if o then -- sim:release(o) -- end -- end end end end --'******************************************************************************* --' ** ** ** ** ** ** ** ** ** OTHER ** ** ** ** ** ** ** ** ** --'******************************************************************************* local last_armor_id=0 local last_condition=0 function repair_armor(val) counterAdd("amk_mod.repair_armor") local armor = db.actor:item_in_slot(6) if armor then last_armor_id=armor:id() last_condition=val armor:set_condition(val) end end local flag_raz=0 -------------------------- local patronov=0 function check_armor() counterAdd("amk_mod.check_armor") local armor = db.actor:item_in_slot(6) local weapon = db.actor:item_in_slot(2) if db.actor:active_slot()==2 and weapon then local tmp if armor then tmp = armor:section() else tmp = "none" end if (not string_find(tmp, "exo")) and weapon:section()=="wpn_m_134" then patronov = weapon:get_ammo_in_magazine() -- вариант 2 db.actor:drop_item(weapon) local tmpw = amk.spawn_item_in_inv("wpn_m_134") db.actor:transfer_item(weapon,db.actor) amk.start_timer("set_patroni", 1, {tmpw.id, patronov}) alife():release(tmpw) amk.send_tip(game.translate_string("wpn-m_134-no_exo_message"),"Minigun",0,8,"gen_info") end end if not armor then last_armor_id=0 return end if armor:id()~=last_armor_id then last_armor_id=armor:id() last_condition=armor:condition() return end -- if last_condition0 and who and IAmAStalker[who:clsid()] then --false для отключения local script if obj and IAmAMonster[obj:clsid()] then script=bind_monster elseif obj and IAmAStalker[obj:clsid()] then script=xr_motivator end if script then local weapon = who:active_item() if not weapon or weapon:section()~="wpn_flame" then return end if string_find(obj:section(), "zomb") and obj.health<0.2 then obj:kill(obj) end script.play_particle(obj, { obj=obj, particle="amk\\flame", bone="bip01_spine1" }) end end end local zombi_skeletons={ "physics\\dead_body\\skelet_combine_pose_03", "physics\\dead_body\\skelet_combine_pose_04", "physics\\dead_body\\skelet_combine_pose_05", "physics\\dead_body\\skelet_torso" } function zomby_blow(obj) counterAdd("amk_mod.zomby_blow") if obj:object("wpn_flame") then amk_particle.amk_particle({ particle="explosions\\explosion_fuelcan", pos=obj:position(), sound=[[weapons\t_rgd5_explosion]] }) local dist = db.actor:position():distance_to(obj:position()) if dist < 5 and db.actor:see(obj) then local h = hit() h.impulse = 0 h.draftsman = db.actor h.direction = vector():set(0,0,0) h:bone("bip01_spine") -- чтобы учитывалась броня h.power = 1/dist h.type = hit.strike --chemical_burn db.actor:hit(h) h.power = 5/dist h.type = hit.chemical_burn db.actor:hit(h) end alife():release(alife():object(obj:id())) return end if obj:section()=="zombie_blow" then amk_particle.amk_particle({ particle="amk\\zomb_explode", pos=obj:position(), sound=[[anomaly\anomaly_body_tear_1]] }) local dist = db.actor:position():distance_to(obj:position()) if dist < 7 and db.actor:see(obj) then local h = hit() h.impulse = 0 h.draftsman = db.actor h.direction = vector():set(0,0,0) h:bone("bip01_spine") -- чтобы учитывалась броня h.power = 1/dist h.type = hit.strike --chemical_burn db.actor:hit(h) h.power = 5/dist h.type = hit.chemical_burn db.actor:hit(h) end local skel = amk.spawn_item("breakable_object",obj:position(),obj:game_vertex_id(),obj:level_vertex_id()) local t = amk.get_breakable_data(skel) t.visual = zombi_skeletons[math_random(#zombi_skeletons)] t.mass = 1.0 t.physic_type = 3 t.skeleton_flags = 1 amk.set_breakable_data(t,skel) alife():release(alife():object(obj:id())) end end --[=[ function rat_tnt(obj) if obj:section()=="rat_tnt" then amk_particle.amk_particle({particle="explosions\\explosion_fuelcan", pos=obj:position(),sound=[[weapons\t_rgd5_explosion]]}) local dist = db.actor:position():distance_to(obj:position()) if dist < 7 and db.actor:see(obj) then local h = hit() h.impulse = 0 h.draftsman = db.actor h.direction = vector():set(0,0,0) h:bone("bip01_spine") -- чтобы учитывалась броня h.power = 5/dist h.type = hit.strike db.actor:hit(h) end alife():release(alife():object(obj:id())) end end ]=] function repair_weapon (st) counterAdd("amk_mod.repair_weapon") -- для совместимости оставлен старый способ с распаковкой local arr if type(st) == "table" then arr = st else arr = amk.unpack_array_from_string(st) end local oid = arr[1] local repbox_health = arr[2] local slot = arr[3] if alife():object(oid)==nil then local repair_coef = 0 local item_in_slot = db.actor:item_in_slot(slot) if repbox_health==1 then repair_coef=0.25 elseif repbox_health<1 then repair_coef=0.2 elseif repbox_health<0.8 then repair_coef=0.15 elseif repbox_health<0.6 then repair_coef=0.1 elseif repbox_health<0.4 then repair_coef=0.05 end --------------------------------------------------------------------------- local rem if item_in_slot == nil then amk.send_tip(game.translate_string("rep_no_weapon_in_slot"),nil,nil,5) rem = amk.spawn_item_in_inv("repbox_s"..slot) amk.start_timer("repbox_cond",0.1, {rem.id, repbox_health} ) else if item_in_slot:condition()>0.95 then amk.send_tip(game.translate_string("rep_not_need"),nil,nil,5) rem = amk.spawn_item_in_inv("repbox_s"..slot) amk.start_timer("repbox_cond",0.1, {rem.id, repbox_health} ) else if item_in_slot:condition()>=0.7 then item_in_slot:set_condition(item_in_slot:condition() + repair_coef) if repbox_health>0.3 then rem = amk.spawn_item_in_inv("repbox_s"..slot) amk.start_timer("repbox_cond",0.1, {rem.id, repbox_health-0.2} ) end else amk.send_tip(game.translate_string("rep_need_big"),nil,nil,5) rem = amk.spawn_item_in_inv("repbox_s"..slot) amk.start_timer("repbox_cond",0.1, {rem.id, repbox_health} ) end end end end end function after_repair_weapon (st) counterAdd("amk_mod.after_repair_weapon") -- для совместимости оставлен старый способ с распаковкой local arr if type(st) == "table" then arr = st else arr = amk.unpack_array_from_string(st) end local oid = arr[1] local repbox_health = arr[2] local lobj = level.object_by_id(oid) if lobj then lobj:set_condition(repbox_health) end end function firebat_ammo() counterAdd("amk_mod.firebat_ammo") local ammo=db.actor:object("ammo_flame") if ammo then db.actor:iterate_inventory( function(dummy,item) if item:section()=="ammo_flame" then alife():release(alife():object(item:id())) end end , db.actor) end end