-- Каждая функция в этом файле используется как условие xr_logic: {=функция !функция} -- Если в функцию необходимо передавать параметры, то: {=функция(парам1:парам2:...) !функция(парам1:парам2:...)} -- Формат: function f(actor, npc). В случае передачи параметров: function f(actor, npc, p). -- ---------------------------------------------------------------------------------------------------- -- Функции для работы с combat_ignore_cond -- ---------------------------------------------------------------------------------------------------- function is_enemy_actor(enemy, object) return enemy:id() == db.actor:id() end -- текущий враг на расстоянии больше или равном заданному расстоянию -- для combat_ignore function fighting_dist_ge(enemy, npc, p) local d = p[1] return enemy:position():distance_to_sqr(npc:position()) >= d * d end -- расстояние до текущего реального врага меньше или равно заданного значения function fighting_dist_le(enemy, npc, p) local d = p[1] return enemy:position():distance_to_sqr(npc:position()) <= d * d end function enemy_in_zone(enemy, npc, p) local zone = db.zone_by_name[p[1]] if zone == nil then abort("Wrong zone name %s in enemy_in_zone function. NPC [%s]", tostring(p[1]), npc:name()) end return utils.npc_in_zone(enemy, zone) end -- ---------------------------------------------------------------------------------------------------- -- Общие функции -- ---------------------------------------------------------------------------------------------------- -- видим ли мы еще "черный экран" или нет? function black_screen(actor, npc) return device().precache_frame > 1 end --Проверка, встречается ли в имени чувака одна из строк . function check_npc_name (actor , npc , p) if npc:name() == nil then return false end local name_exist = false for k,v in pairs(p) do if string.find( npc:name(), v ) ~= nil then name_exist = true end end return name_exist end function check_enemy_name (actor , npc , p) local enemy_id = db.storage[npc:id()].enemy_id local enemy = db.storage[enemy_id] and db.storage[enemy_id].object local name if enemy and enemy:alive() then name = enemy:name() for i, v in pairs(p) do if string.find( name, v ) ~= nil then return true end end end return false end function is_playing_sound (actor, npc) return xr_sound.sound_table[npc:id()] ~= nil end -- проверка, что актер жив function actor_alive(actor, npc) if db.actor and db.actor:alive() then return true end return false end function see_npc(actor, npc, p) local npc1 = get_story_object(p[1]) if npc and npc1 then --printf("cond : [%s]->[%s]", npc:name(), npc1:name()) return npc:see(npc1) else return false end end function actor_see_npc(actor, npc) return db.actor:see(npc) end function npc_in_actor_frustum(actor, npc) return npc_in_actor_frustrum(npc) end function is_wounded(actor, npc) return xr_wounded.is_wounded(npc) end function dist_to_actor_le(actor, npc, p) local d = p[1] if d == nil then abort("Wrong parameter in 'dist_to_actor_le' function!!!") end return d and npc:position():distance_to_sqr(actor:position()) <= d * d end function dist_to_actor_ge(actor, npc, p) local d = p[1] if d == nil then abort("Wrong parameter in 'dist_to_actor_ge' function!!!") end return d and npc:position():distance_to_sqr(actor:position()) >= d * d end -- Проверка выполняет ли кто указанную работу function is_obj_on_job(actor, npc, p) local smart if p and p[2] then smart = sim_board.get_sim_board():get_smart_by_name(p[2]) else smart = xr_gulag.get_npc_smart(npc) end if smart == nil then return false end for k,v in pairs(smart.npc_info) do local npc_job = smart.job_data[v.job_id] printf("section [%s]", tostring(npc_job.section)) if npc_job.section == p[1] then return true end end return false end -- проверка того что дистанция до обьекта <= заданной -- параметры: [sid,dist] function distance_to_obj_on_job_le(actor, npc, p) local smart = xr_gulag.get_npc_smart(npc) for k,v in pairs(smart.npc_info) do local npc_job = smart.job_data[v.job_id] if npc_job.section == p[1] then return npc:position():distance_to_sqr(v.se_obj.position) <= p[2]*p[2] end end return false end -- проверка того что npc находится в заданной зоне -- !!! ВЫЗЫВАТЬ ТОЛЬКО ИЗ SPACE RESTRICTOR !!! -- параметры: [sid1:sid2:...] -- !!! НЕКОРРЕКТНО РАБОТАЕТ ДЛЯ ОБЬЕКТОВ В offline'e !!! -- !!! ДЛЯ ГАРАНТИИ ИСПОЛЬЗОВАТЬ one_obj_in_zone !!! function obj_in_zone(actor, zone, p) local npc1, i, v = 0, 0, 0 for i, v in pairs(p) do npc1 = get_story_object_id(v) if npc1 and zone:inside(alife():object(npc1).position) then return true end end return false end -- параметры: [sid:def*] def=true|false -- * параметр не обязателен function one_obj_in_zone(actor, zone, p) --local def_offline = (p[2] ~= "false") -- default (true) result if npc in offline local obj1 = get_story_object_id(p[1]) if obj1 then -- npc is online return zone:inside(alife():object(obj1).position) else -- npc is offline return (p[2] ~= "false") -- default (true) result if npc in offline end end function story_obj_in_zone_by_name (actor, npc, p) local obj = get_story_object_id(p[1]) local zone = db.zone_by_name[p[2]] if obj and zone then -- npc is online return zone:inside(alife():object(obj).position) end return false end function actor_in_zone(actor, npc, p) local zone = db.zone_by_name[p[1]] return utils.npc_in_zone(db.actor, zone) end function npc_in_zone(actor, npc, p) local zone = db.zone_by_name[p[1]] if type(npc.id) ~= "function" then npc_obj = db.storage[npc.id] and db.storage[npc.id].object if zone == nil then return true end if npc_obj == nil then return zone:inside(npc.position) end else npc_obj = npc end return utils.npc_in_zone(npc_obj, zone) end -- true, если здоровье npc <= заданному значению -- false в противном случае function health_le(actor, npc, p) return p[1] and npc.health < p[1] end -- true, если здоровье актера <= заданному значению -- false в противном случае function actor_health_le(actor, npc, p) return p[1] and actor.health < p[1] end --[[ -- true, если здоровье вертолёта <= заданному значению -- false в противном случае function heli_health_le(actor, obj, p) return p[1] and obj:get_helicopter():GetfHealth() < p[1] end -- видит ли вертолёт npc (по story id) function heli_see_npc(actor, obj, p) if p[1] then local o = get_story_object( p[1] ) return o ~= nil and obj:get_helicopter():isVisible( o ) else return false end end function heli_see_actor(actor, obj) return actor ~= nil and obj:get_helicopter():isVisible( actor ) end -- Проверка на принадлежность врага к одной из групп -- (можно задавать несколько через двоеточие) function enemy_group(actor, npc, p) local enemy_id = db.storage[npc:id()].enemy_id local enemy = db.storage[enemy_id] and db.storage[enemy_id].object local g = enemy:group() local i, v = 0, 0 for i, v in pairs(p) do if v == g then --printf("_bp: [%s]'s enemy is from group [%d]", npc:name(), v) return true end end return false end function gulag_state(actor, npc, p) if xr_gulag.getGulagState(p[1]) == p[2] then return true end return false end ]]-- function npc_community(actor, npc, p) local npc_obj if p[1] == nil then abort("Wrong number of params in npc_community") end if type(npc.id) ~= "function" then npc_obj = db.storage[npc.id] and db.storage[npc.id].object if npc_obj == nil then return npc:community() == p[1] end else npc_obj = npc end if character_community(npc_obj) == p[1] then return true end return false end --[[ function npc_rank(actor, npc, p) if p[1] == nil then abort("Wrong number of params in npc_rank") end if ranks.get_obj_rank_name(npc) == p[1] then return true end return false end function npc_profile(actor, npc, p) if p[1] == nil then abort("Wrong number of params in npc_profile") end if npc:profile_name() == p[1] then return true end return false end ]]-- -- Проверка того что удар был нанесен кем-то из npc указанных в списке. -- Параметры это story_id персонажей. Можно задавать несколько story_id. function hitted_by(actor, npc, p) local npc1 local t = db.storage[npc:id()].hit if t then for i, v in pairs(p) do npc1 = get_story_object(v) if npc1 and t.who == npc1:id() then return true end end end return false end -- Функция проверки попадания в кость по её индексу.(Проверка только для секции hit) function hitted_on_bone(actor, npc, p) for k,v in pairs (p) do if db.storage[npc:id()].hit.bone_index == npc:get_bone_id(v) then return true end end return false end -- Проверка, что лучшее оружие персонажа - пистолет function best_pistol(actor, npc) local pistol = npc:item_in_slot(1) if pistol ~= nil then return true else return false end end -- Проверка, что персонажу нанесли смертельный хит. Проверять ТОЛЬКО на on_hit function deadly_hit(actor, npc) if db.storage[npc:id()] == nil or db.storage[npc:id()].hit == nil then --printf("deadly hit false") return false end --printf("deadly hit [%s]", tostring(db.storage[npc:id()].hit.deadly_hit == true)) return db.storage[npc:id()].hit.deadly_hit == true end -- Проверка того что персонаж был убит кем-то из npc указанных в списке. -- Параметры это story_id персонажей. Можно задавать несколько story_id. function killed_by(actor, npc, p) local npc1 local t = db.storage[npc:id()].death if t then for i, v in pairs(p) do npc1 = get_story_object(v) if npc1 and t.killer == npc1:id() then printf("_bp: killed_by(%d)", v) return true end end end return false end -- проверка (по story_id) все ли проверяемые сталкеры живы -- TODO: исправить ситуацию, когда выдается неправильный результат для обьектов, которые -- не успели проспавниться. function is_alive_all(actor, npc, p) local npc1 for i, v in pairs(p) do npc1 = get_story_object_id(v) if npc1 == nil then return false end npc1 = alife():object(npc1) if npc1 and (not IsStalker(npc1) or not npc1:alive()) then return false end end return true end -- проверка (по story_id) того, что чотя бы один из проверяемых сталкеров жив -- TODO: исправить ситуацию, когда выдается неправильный результат для обьектов, которые -- не успели проспавниться. function is_alive_one(actor, npc, p) local npc1 for i, v in pairs(p) do npc1 = get_story_object_id(v) if npc1 == nil then return false end npc1 = alife():object(npc1) if npc1 and IsStalker(npc1) and npc1:alive() then return true end end return false end -- проверка (по story_id) того, что проверяемыq npc жив -- TODO: исправить ситуацию, когда выдается неправильный результат для обьектов, которые -- не успели проспавниться. function is_alive(actor, npc, p) local npc1 if npc == nil or (p and p[1]) then npc1 = get_story_object_id(p[1]) elseif (type(npc.id) == "number") then npc1 = npc.id else npc1 = npc:id() end if npc1 == nil then return false end npc1 = alife():object(npc1) if npc1 and IsStalker(npc1) and npc1:alive() then return true end return false end -- проверка (по story_id) все ли проверяемые сталкеры мертвы -- TODO: исправить ситуацию, когда выдается неправильный результат для обьектов, которые -- не успели проспавниться. function is_dead_all(actor, npc, p) local npc1 for i, v in pairs(p) do npc1 = get_story_object(v) if npc1 then if npc1:alive() then return false else printf("_bp: is_dead_all(%d) = true", v) return true end end return false end return true end -- проверка (по story_id) того, что хотя бы один из проверяемых сталкеров мертв -- TODO: исправить ситуацию, когда выдается неправильный результат для обьектов, которые -- не успели проспавниться. function is_dead_one(actor, npc, p) local npc1 for i, v in pairs(p) do npc1 = get_story_object(v) if not npc1 or not npc1:alive() then printf("_bp: is_dead_one(%d) = true", v) return true end end return false end -- проверка (по story_id) того, что хотя бы один из проверяемых сталкеров мертв -- TODO: исправить ситуацию, когда выдается неправильный результат для обьектов, которые -- не успели проспавниться. function is_dead(actor, npc, p) local npc1 npc1 = get_story_object(p[1]) return not npc1 or not npc1:alive() end -- Проверяет , существует ли обьект с заданным стори айди. function story_object_exist(actor, npc, p) local npc1 = get_story_object(p[1]) return npc1 ~= nil end --[[ -- проверка (по story_id) того, что нашим врагом есть хотя бы кото-то один из списка function check_fighting(actor, npc, p) local enemy_id = db.storage[npc:id()].enemy_id local enemy = db.storage[enemy_id] and db.storage[enemy_id].object local sid if enemy and enemy:alive() then sid = enemy:story_id() for i, v in pairs(p) do --printf("_bp: %s.check_fighting(%d)", npc:name(), v) if type(v) == 'number' and sid == v then --printf("TRUE") return true end end end --printf("_bp: check_fighting() = false") return false end ]]-- -- true, если у актёра в инвентаре есть указанный предмет -- false, если нету, либо не задана секция предмета function actor_has_item(actor, npc, p) local story_actor = get_story_object("actor") return p[1] ~= nil and story_actor and story_actor:object( p[1] ) ~= nil end function npc_has_item(actor, npc, p) return p[1] ~= nil and npc:object( p[1] ) ~= nil end -- проверяет наличие заданого количества предметов в инвентаре игрока. function actor_has_item_count(actor, npc, p) local item_section = p[1] local need_count = tonumber(p[2]) local has_count = 0 local function calc(temp, item) --printf("item [%s]",tostring(item:section())) if item:section() == item_section then has_count = has_count + 1 end end actor:iterate_inventory(calc, actor) return has_count >= need_count end -- возвращает true, если в текущей схеме персонажа взведён указанный сигнал. function signal(actor, npc, p) if p[1] then local st = db.storage[npc:id()] local sigs = st[st.active_scheme].signals -- printf( "xr_conditions.signal: npc=%s, scheme=%s", npc:name(), tostring(st.active_scheme) ) return sigs ~= nil and sigs[p[1]] == true else return false end end -- возвращает true, если значение указанного счётчика актёра больше указанного числа function counter_greater(actor, npc, p) if p[1] and p[2] then local c = xr_logic.pstor_retrieve(actor, p[1], 0) -- if c > p[2] then printf("pl: counter [%s] greater [%s]", p[1], p[2]) end return c > p[2] else return false end end function counter_equal(actor, npc, p) if p[1] and p[2] then local c = xr_logic.pstor_retrieve(actor, p[1], 0) return c == p[2] else return false end end --[[ -- определяет нечётность интервала игрового времени. интервал нужно передать в p[1] function odd_time_interval(actor, npc, p) return odd( game.time() / p[1] ) end ]]-- ------------------------------------------------------------------------------------------------------- -- Функции поддержки kamp function _kamp_talk(actor, npc) if xr_kamp.kamp_stalkers[npc:id()] then return xr_kamp.kamp_stalkers[npc:id()] end return false end function _used(actor, npc) return npc:is_talking() end ------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------- local alarm_statuses = { normal = smart_terrain_control.NORMAL, danger = smart_terrain_control.DANGER, alarm = smart_terrain_control.ALARM } -- Функции поддержки безопасности баз function check_smart_alarm_status(actor, npc, p) local smart_name = p[1] local status = alarm_statuses[p[2]] if status == nil then abort("Wrong status[%s] in 'check_smart_alarm_status'", tostring(p[2])) end local smart = sim_board.get_sim_board():get_smart_by_name(smart_name) local smart_control = smart.base_on_actor_control if smart_control == nil then abort("Cannot calculate 'check_smart_alarm_status' for smart %s", tostring(smart_name)) end return smart_control:get_status() == status end ------------------------------------------------------------------------------------------------------- function has_enemy(actor, npc) return npc:best_enemy() ~= nil end function has_actor_enemy(actor, npc) local best_enemy = npc:best_enemy() return best_enemy ~= nil and best_enemy:id() == db.actor:id() end function see_enemy(actor, npc) local enemy = npc:best_enemy() if enemy ~= nil then return npc:see(enemy) end return false end function has_enemy_in_current_loopholes_fov(actor, npc) return npc:in_smart_cover() and npc:best_enemy() ~= nil and npc:in_current_loophole_fov( npc:best_enemy():position()) end function talking(actor, npc) return actor:is_talking() end function npc_talking(actor, npc) return npc:is_talking() end function see_actor(actor, npc) return npc:alive() and npc:see(actor) end function actor_enemy(actor, npc) local t = db.storage[npc:id()].death return npc:relation(actor) == game_object.enemy or (t ~= nil and t.killer == actor:id()) end function actor_friend(actor, npc) return npc:relation(actor) == game_object.friend end function actor_neutral(actor, npc) return npc:relation(actor) == game_object.neutral end function is_factions_enemies(actor, npc, p) if(p[1]~=nil) then return game_relations.is_factions_enemies(character_community(actor), p[1]) else return false end end function is_factions_neutrals(actor, npc, p) return not(is_factions_enemies(actor, npc, p) or is_factions_friends(actor, npc, p)) end function is_factions_friends(actor, npc, p) if(p[1]~=nil) then return game_relations.is_factions_friends(character_community(actor), p[1]) else return false end end function is_faction_enemy_to_actor(actor, npc, p) if(p[1]~=nil) then -- return db.actor:community_goodwill(p[1])<-1000 return relation_registry.community_goodwill(p[1], db.actor:id())<=-1000 else return false end end function is_faction_friend_to_actor(actor, npc, p) if(p[1]~=nil) then -- return db.actor:community_goodwill(p[1])>1000 return relation_registry.community_goodwill(p[1], db.actor:id())>=1000 else return false end end function is_faction_neutral_to_actor(actor, npc, p) return not(is_faction_enemy_to_actor(actor, npc, p) or is_faction_friend_to_actor(actor, npc, p)) end function is_squad_friend_to_actor(actor, npc, p) if(p[1]~=nil) then -- printf("squad check goodwill1 [%s]", p[1]) return game_relations.check_all_squad_members(p[1], "friend") else -- printf("squad check goodwill5 [%s]", p[1]) return false end end function is_squad_enemy_to_actor(actor, npc, p) if not p then abort("Not enough arguments in 'is_squad_enemy_to_actor' funciton!") end for k,v in pairs(p) do -- printf("squad check goodwill1 [%s]", v) if game_relations.check_all_squad_members(v, "enemy") then return true end end return false end function is_squad_neutral_to_actor(actor, npc, p) return not(is_squad_enemy_to_actor(actor, npc, p) or is_squad_friend_to_actor(actor, npc, p)) end -- текущий враг актёр? function fighting_actor(actor, npc) local enemy_id = db.storage[npc:id()].enemy_id local enemy = db.storage[enemy_id] and db.storage[enemy_id].object return enemy and enemy:id() == actor:id() end function hit_by_actor(actor, npc) local t = db.storage[npc:id()].hit local hit_by_actor = (t ~= nil and t.who == actor:id()) printf("_bp: hit_by_actor: %s", if_then_else(hit_by_actor, "true", "false")) return hit_by_actor end function killed_by_actor(actor, npc) local t = db.storage[npc:id()].death local killed_by_actor = t ~= nil and t.killer == actor:id() printf("_bp: killed_by_actor: %s", if_then_else(killed_by_actor, "true", "false")) return killed_by_actor end function actor_has_weapon (actor, npc) local obj = actor:active_item () if obj == nil or isWeapon (obj) == false then return false end return true end function actor_active_detector(actor, npc, p) local detector_section = p and p[1] if detector_section == nil then abort("Wrong parameters in function 'actor_active_detector'") end local actor_detector = db.actor:active_detector() return (actor_detector ~= nil) and actor_detector:section() == detector_section end function heavy_wounded(actor, npc) return xr_wounded.is_heavy_wounded_by_id( npc:id() ) end --[[ Проверка на заданный период времени Время задается в минутах Параметры: (time_shift:period_min) time_shift - периодичность срабатывания period - период срабатывания на котором мы получаем true Примеры: time_period(60:10) - возвращает true каждый час на протяжении первых 10 минут --]] function time_period(actor, npc, p) local tshift, period = p[1], p[2] if tshift ~= nil and period ~= nil and db.actor ~= nil then return tshift > period and level.get_time_minutes() % tshift <= period end return false end function is_rain (actor, npc) return db.actor ~= nil and level.rain_factor() > 0 end function is_heavy_rain (actor, npc) return db.actor ~= nil and level.rain_factor() >= 0.5 end function is_day (actor, npc) return db.actor ~= nil and level.get_time_hours() >= 6 and level.get_time_hours() < 21 end function is_dark_night (actor, npc) return db.actor ~= nil and (level.get_time_hours() < 3 or level.get_time_hours() > 22) end function is_jup_a12_mercs_time (actor, npc) return db.actor ~= nil and (level.get_time_hours() >= 1 and level.get_time_hours() < 5) end function zat_b7_is_night (actor, npc) return db.actor ~= nil and (level.get_time_hours() >= 23 or level.get_time_hours() < 5) end function zat_b7_is_late_attack_time (actor, npc) return db.actor ~= nil and (level.get_time_hours() >= 23 or level.get_time_hours() < 9) end function mob_has_enemy(actor, npc) -- return false if npc == nil then return false end --if npc:get_enemy () then printf ("ENEMY PRESENT") else printf ("ENEMY NOT PRESENT") end return npc:get_enemy() ~= nil end function mob_was_hit(actor, npc) local h = npc:get_monster_hit_info() if h.who and h.time ~= 0 then return true end return false end function actor_on_level(actor, npc, p) for k,v in pairs (p) do --printf("level name: [%s], needed level name: [%s]", level.name(), v`) if v == level.name() then return true end end return false end function treasure_exist(actor, npc, p) --printf("%s %s", actor:name(), npc:name()) return true end --[[ --'----------------------------------------------------------------------------------- --' Cover support --'----------------------------------------------------------------------------------- --' Если возвращает true, то солдаты за каверами начинают стрелять. function cover_attack(actor, npc) --' Берем сквад объекта local squad = get_object_squad(npc) if squad == nil then return false end return squad:cover_attack() end ]]-- --'----------------------------------------------------------------------------------- --' Squad support --'----------------------------------------------------------------------------------- function squad_in_zone(actor, npc, p) local story_id = p[1] local zone_name = p[2] if story_id == nil then abort("Insufficient params in squad_in_zone function. story_id[%s], zone_name[%s]", tostring(story_id), tostring(zone_name)) end if zone_name == nil then zone_name = npc:name() end local sim_board = sim_board.get_sim_board() local squad = get_story_squad(story_id) if squad == nil then --abort("There is no squad with id[%s]", tostring(squad_id)) return false end local zone = db.zone_by_name[zone_name] if zone == nil then --abort("There is no squad with id[%s]", tostring(zone_name)) return false end for k in squad:squad_members() do local position = (db.storage[k.id] and db.storage[k.id].object and db.storage[k.id].object:position()) or k.object.position if zone:inside(position) then return true end end return false end function squad_has_enemy(actor, npc, p) local story_id = p[1] if story_id == nil then abort("Insufficient params in squad_has_enemy function. story_id [%s]", tostring(story_id)) end local squad = get_story_squad(story_id) if squad == nil then --abort("There is no squad with id[%s]", tostring(story_id)) return false end local al = alife() for k in squad:squad_members() do local npc_obj = level.object_by_id(k.object.id) if npc_obj == nil then return false end if npc_obj:best_enemy() ~= nil then return true end end return false end -- Functions for Yantar function squad_in_zone_all(actor, npc, p) local story_id = p[1] local zone_name = p[2] if story_id == nil or zone_name == nil then abort("Insufficient params in squad_in_zone_all function. story_id[%s], zone_name[%s]", tostring(story_id), tostring(zone_name)) end local squad = get_story_squad(story_id) if squad == nil then --abort("There is no squad with id[%s]", tostring(story_id)) return false end local zone = db.zone_by_name[zone_name] if zone == nil then --abort("There is no squad with id[%s]", tostring(zone_name)) return false end local al = alife() for k in squad:squad_members() do local position = (db.storage[k.id] and db.storage[k.id].object and db.storage[k.id].object:position()) or k.object.position if not zone:inside(position) then return false end end return true end function squads_in_zone_b41(actor, npc, p) local smart = sim_board.get_sim_board():get_smart_by_name("jup_b41") local zone = db.zone_by_name["jup_b41_sr_light"] local al = alife() if zone == nil then return false end if smart == nil then return false end for k,v in pairs(sim_board.get_sim_board().smarts[smart.id].squads) do if v ~= nil then for j in v:squad_members() do if not zone:inside(j.object.position) then return false end end end end return true end --' Проверка в таргет кондлисте задания, соответствует ли имя сквада переданному function target_squad_name(actor, obj, p) if p[1] == nil then abort("Wrong parameters") end if not(obj) then return false end --callstack() if IsStalker(obj) or IsMonster(obj) then if alife():object(obj.group_id) == nil then return false end if string.find( alife():object(obj.group_id):section_name(), p[1] ) ~= nil then return true end --return alife():object(obj.group_id):section_name() == p[1] end return obj:section_name() == p[1] end --' Проверка в таргет кондлисте задания, соответствует ли имя смарта переданному function target_smart_name(actor, smart, p) if p[1] == nil then abort("Wrong parameters") end --callstack() return smart:name() == p[1] end --' Проверяет жив ли отряд с указанным ID function squad_exist(actor, npc, p) local story_id = p[1] if story_id == nil then abort("Wrong parameter story_id[%s] in squad_exist function", tostring(story_id)) end local squad = get_story_squad(story_id) -- if squad == nil then -- return false -- end return squad ~= nil -- return squad.squad_power > 0 end function is_squad_commander(actor, npc) if (type(npc.id) == "number") then npc_id = npc.id else npc_id = npc:id() end local squad = get_object_squad(npc) return squad ~= nil and squad:commander_id() == npc_id end function squad_npc_count_ge(actor, npc, p) local story_id = p[1] if story_id == nil then abort("Wrong parameter squad_id[%s] in 'squad_npc_count_ge' function", tostring(squad_id)) end local squad = get_story_squad(story_id) if squad then return squad:npc_count() > tonumber(p[2]) else return false end end function surge_complete() return surge_manager.is_finished() end function surge_started() return surge_manager.is_started() end function surge_kill_all() return surge_manager.is_killing_all() end function signal_rocket_flying(actor, npc, p) if p==nil then abort("Signal rocket name is not set!") end if db.signal_light[p[1]] then return db.signal_light[p[1]]:is_flying() else abort("No such signal rocket: [%s] on level", tostring(p[1])) end return false end function quest_npc_enemy_actor(actor, npc, p) if p[1] == nil then abort("wrong story id") else local obj = get_story_object(p[1]) if obj and IsStalker(obj) then if db.actor and obj:general_goodwill(db.actor)<=-1000 then return true end end end return false end function animpoint_reached(actor, npc) local animpoint_storage = db.storage[npc:id()].animpoint if animpoint_storage == nil then return false end local animpoint_class = animpoint_storage.animpoint return animpoint_class:position_riched() end --[[ function npc_stay_offline(actor, npc, p) if p == nil then abort("Wrong parameter!!!") end if npc and db.actor then if is_smart_in_combat(actor, npc, p) then if npc.position:distance_to(db.actor:position())>=30 or game_relations.get_gulag_relation_actor(p[1], "enemy") then return true end end end return false end ]]-- -- проверка того что дистанция до обьекта >= заданной -- параметры: [sid,dist] function distance_to_obj_ge(actor, npc, p) local npc_id = get_story_object_id(p[1]) local npc1 = npc_id and alife():object(npc_id) if npc1 then return db.actor:position():distance_to_sqr(npc1.position) >= p[2]*p[2] end return false end function distance_to_obj_le(actor, npc, p) local npc_id = get_story_object_id(p[1]) local npc1 = npc_id and alife():object(npc_id) if npc1 then return db.actor:position():distance_to_sqr(npc1.position) < p[2]*p[2] end return false end function in_dest_smart_cover(actor, npc, p) return npc:in_smart_cover() end function active_item(actor, npc, p) if p and p[1] then for k,v in pairs(p) do if actor:item_in_slot(3) ~= nil and actor:item_in_slot(3):section() == v then return true end end end return false end function actor_nomove_nowpn() if (not isWeapon(db.actor:active_item())) or db.actor:is_talking() then return true end return false end function jup_b16_is_zone_active(actor, npc) return has_alife_info(npc:name()) end --Функция проверки состояния видимости кровососа. -- Возможный набор параметров --> story_id:visibility_state(можно вызывать откуда угодно) или visibility_state(если вызывается из кастомдаты кровососа) -- visibility_state --> -- 0 - невидимый -- 1 - полувидимый -- 2 - полностью видимый function check_bloodsucker_state(actor, npc, p) if (p and p[1]) == nil then abort("Wrong parameters in function 'check_bloodsucker_state'!!!") end local state = p[1] if p[2] ~= nil then state = p[2] npc = get_story_object(p[1]) end if npc ~= nil then return npc:get_visibility_state () == tonumber(state) end return false end function dist_to_story_obj_ge(actor, npc, p) local story_id = p and p[1] local story_obj_id = get_story_object_id(story_id) if story_obj_id == nil then return true end local se_obj = alife():object(story_obj_id) return se_obj.position:distance_to(db.actor:position()) > p[2] end function actor_has_nimble_weapon(actor, npc) local need_item = {} need_item["wpn_groza_nimble"] = true need_item["wpn_desert_eagle_nimble"] = true need_item["wpn_fn2000_nimble"] = true need_item["wpn_g36_nimble"] = true need_item["wpn_protecta_nimble"] = true need_item["wpn_mp5_nimble"] = true need_item["wpn_sig220_nimble"] = true need_item["wpn_spas12_nimble"] = true need_item["wpn_usp_nimble"] = true need_item["wpn_vintorez_nimble"] = true need_item["wpn_svu_nimble"] = true need_item["wpn_svd_nimble"] = true for k,v in pairs(need_item) do if actor:object(k) ~= nil then return true end end return false end function actor_has_active_nimble_weapon(actor, npc) local need_item = {} need_item["wpn_groza_nimble"] = true need_item["wpn_desert_eagle_nimble"] = true need_item["wpn_fn2000_nimble"] = true need_item["wpn_g36_nimble"] = true need_item["wpn_protecta_nimble"] = true need_item["wpn_mp5_nimble"] = true need_item["wpn_sig220_nimble"] = true need_item["wpn_spas12_nimble"] = true need_item["wpn_usp_nimble"] = true need_item["wpn_vintorez_nimble"] = true need_item["wpn_svu_nimble"] = true need_item["wpn_svd_nimble"] = true if actor:item_in_slot(2) ~= nil and need_item[actor:item_in_slot(2):section()] == true then return true end if actor:item_in_slot(3) ~= nil and need_item[actor:item_in_slot(3):section()] == true then return true end return false end function jup_b202_inventory_box_empty(actor, npc) local inv_box = get_story_object("jup_b202_actor_treasure") return inv_box:is_inv_box_empty() end --[[ function jup_b46_actor_has_active_science_detector(actor, npc) if actor:item_in_slot(9) ~= nil and actor:item_in_slot(9):section() == "detector_scientific" then return true end return false end ]]-- function is_in_danger(actor, npc, p) if p and p[1] then npc = get_story_object(p[1]) end --printf("npc: [%s] is in danger [%s]", tostring(npc:id()), tostring(db.storage[npc:id()].danger_flag)) return db.storage[npc:id()].danger_flag end function object_exist(actor , npc , p) return get_story_object(p[1]) ~= nil end function squad_curr_action(actor, npc, p) local squad = get_object_squad(npc) return squad.current_action and squad.current_action.name == p[1] end function is_monster_snork(actor, npc) return npc:clsid() == clsid.snork_s end function is_monster_dog(actor, npc) return npc:clsid() == clsid.dog_s end function is_monster_psy_dog(actor, npc) return npc:clsid() == clsid.psy_dog_s end function is_monster_polter(actor, npc) return npc:clsid() == clsid.poltergeist_s end function is_monster_tushkano(actor, npc) return npc:clsid() == clsid.tushkano_s end function is_monster_burer(actor, npc) return npc:clsid() == clsid.burer_s end function is_monster_controller(actor, npc) return npc:clsid() == clsid.controller_s end function is_monster_flesh(actor, npc) return npc:clsid() == clsid.flesh_s end function is_monster_boar(actor, npc) return npc:clsid() == clsid.boar_s end function dead_body_searching(actor, npc) return actor_menu.dead_body_searching end function jup_b47_npc_online(actor, npc, p) -- printf("function jup_b47_npc_online: story_obj[%s]", tostring(p[1])) local story_obj = get_story_object(p[1]) if story_obj == nil then return false end local obj = alife():object(story_obj:id()) return obj ~= nil end function anomaly_has_artefact(actor, npc, p) local az_name = p and p[1] local af_name = p and p[2] local anomal_zone = db.anomaly_by_name[az_name] if anomal_zone == nil then return false end if anomal_zone.spawned_count < 1 then return false end if af_name == nil then local af_table = {} for k,v in pairs(anomal_zone.artefact_ways_by_id) do if alife():object(tonumber(k)) then table.insert(af_table, alife():object(tonumber(k)):section_name()) end end return true, af_table end for k,v in pairs(anomal_zone.artefact_ways_by_id) do if alife():object(tonumber(k)) and af_name == alife():object(tonumber(k)):section_name() then return true end end return false end function zat_b29_anomaly_has_af(actor, npc, p) local az_name = p and p[1] local af_name local anomal_zone = db.anomaly_by_name[az_name] if anomal_zone == nil then return false end if anomal_zone.spawned_count < 1 then return false end for i = 16, 23 do if has_alife_info(dialogs_zaton.zat_b29_infop_bring_table[i]) then af_name = dialogs_zaton.zat_b29_af_table[i] break end end for k,v in pairs(anomal_zone.artefact_ways_by_id) do if alife():object(tonumber(k)) and af_name == alife():object(tonumber(k)):section_name() then db.actor:give_info_portion(az_name) return true end end return false end function jup_b221_who_will_start(actor, npc, p) -- доступные параметры: ability - проверить есть ли доступные темы, choose - выбрать групировку которая начнет перепалку local reachable_theme = {} local faction_table = {} local info_table = { ---------duty [1] = "jup_b25_freedom_flint_gone", [2] = "jup_b25_flint_blame_done_to_duty", [3] = "jup_b4_monolith_squad_in_duty", [4] = "jup_a6_duty_leader_bunker_guards_work", [5] = "jup_a6_duty_leader_employ_work", [6] = "jup_b207_duty_wins", ---------freedom [7] = "jup_b207_freedom_know_about_depot", [8] = "jup_b46_duty_founder_pda_to_freedom", [9] = "jup_b4_monolith_squad_in_freedom", [10] = "jup_a6_freedom_leader_bunker_guards_work", [11] = "jup_a6_freedom_leader_employ_work", [12] = "jup_b207_freedom_wins" } --Составляем таблицу достыпных тем(тлько номера тем). for k,v in pairs(info_table) do if k <= 6 then faction_table[1] = "duty" faction_table[2] = "0" else faction_table[1] = "freedom" faction_table[2] = "6" end if (has_alife_info(v)) and (not has_alife_info("jup_b221_" .. faction_table[1] .. "_main_" .. tostring(k - tonumber(faction_table[2])) .. "_played")) then table.insert(reachable_theme,k) printf("jup_b221_who_will_start: table reachable_theme ------------------------------> [%s]", tostring(k)) end end if (p and p[1]) == nil then abort("No such parameters in function 'jup_b221_who_will_start'") end if tostring(p[1]) == "ability" then return #reachable_theme ~= 0 -- если таблица пуста значит нет доступных тем и ненадо играть сцену elseif tostring(p[1]) == "choose" then ---------Выберем рандомам елемент составленой таблицы и проверим к какой груперовки он пренадлежит :) return reachable_theme[math.random(1, #reachable_theme)] <= 6 -- если меньше 6-ти значит ДОЛГ если больше 6-ти значит СВОБОДА else abort("Wrong parameters in function 'jup_b221_who_will_start'") end end function pas_b400_actor_far_forward(actor, npc) local fwd_obj = get_story_object("pas_b400_fwd") if fwd_obj then if distance_between(fwd_obj, db.actor) > distance_between(fwd_obj, npc) then return false end else return false end local distance = 70 * 70 local self_dist = npc:position():distance_to_sqr(actor:position()) if self_dist < distance then return false end local squad = alife():object(alife():object(npc:id()).group_id) for k in squad:squad_members() do local other_dist = k.object.position:distance_to_sqr(actor:position()) if other_dist < distance then return false end end --printf("npc: [%s], actor is far forward - self_dist [%s] distance [%s]", tostring(npc:name()), self_dist, distance) return true end function pas_b400_actor_far_backward(actor, npc) local bwd_obj = get_story_object("pas_b400_bwd") if bwd_obj then if distance_between(bwd_obj, db.actor) > distance_between(bwd_obj, npc) then return false end else return false end local distance = 70 * 70 local self_dist = npc:position():distance_to_sqr(actor:position()) if self_dist < distance then return false end local squad = alife():object(alife():object(npc:id()).group_id) for k in squad:squad_members() do local other_dist = k.object.position:distance_to_sqr(actor:position()) if other_dist < distance then return false end end --printf("npc: [%s], actor is far backward - self_dist [%s] distance [%s]", tostring(npc:name()), self_dist, distance) return true end function pri_a28_actor_is_far(actor, npc) local distance = 150 * 150 local squad = get_story_squad("pri_a16_military_squad") for k in squad:squad_members() do local npc_dist = k.object.position:distance_to_sqr(actor:position()) if npc_dist < distance then return false end end return true end function check_enemy_smart(actor , npc , p) local enemy_id = db.storage[npc:id()].enemy_id local enemy = db.storage[enemy_id] and db.storage[enemy_id].object if enemy == nil or enemy_id == alife():actor().id then return false end local enemy_smart = xr_gulag.get_npc_smart(enemy) if (enemy_smart ~= nil) and (enemy_smart:name() == p[1]) then return true end return false end function zat_b103_actor_has_needed_food(actor, npc, p) return (dialogs_zaton.zat_b103_actor_has_needed_food(actor, npc)) or (has_alife_info("zat_b103_merc_task_done")) end function zat_b29_rivals_dialog_precond(actor, npc) local squads_table = { "zat_b29_stalker_rival_default_1_squad", "zat_b29_stalker_rival_default_2_squad", "zat_b29_stalker_rival_1_squad", "zat_b29_stalker_rival_2_squad" } local zones_table = { "zat_b29_sr_1", "zat_b29_sr_2", "zat_b29_sr_3", "zat_b29_sr_4", "zat_b29_sr_5", } local f_squad = false for k,v in pairs(squads_table) do if alife():object(alife():object(npc:id()).group_id):section_name() == v then f_squad = true break end end if not f_squad then return false end for k,v in pairs(zones_table) do if utils.npc_in_zone(npc, db.zone_by_name[v]) then return true end end return false end function polter_ignore_actor(actor, npc) return npc:poltergeist_get_actor_ignore() end function burer_gravi_attack(actor, npc) return npc:burer_get_force_gravi_attack() end function burer_anti_aim(actor, npc) return npc:burer_get_force_anti_aim() end function jup_b202_actor_treasure_not_in_steal(actor, npc) local before = ((not has_alife_info("jup_b52_actor_items_can_be_stolen")) and (not has_alife_info("jup_b202_actor_items_returned"))) local after = (has_alife_info("jup_b52_actor_items_can_be_stolen") and has_alife_info("jup_b202_actor_items_returned")) return (before or after) end function jup_b25_senya_spawn_condition(actor, npc) return (has_alife_info("jup_b16_oasis_found") or has_alife_info("zat_b57_bloodsucker_lair_clear") or has_alife_info("jup_b6_complete_end") or has_alife_info("zat_b215_gave_maps")) and has_alife_info("zat_b106_search_soroka") end function jup_b25_flint_gone_condition(actor, npc) return has_alife_info("jup_b25_flint_blame_done_to_duty") or has_alife_info("jup_b25_flint_blame_done_to_freedom") or has_alife_info("zat_b106_found_soroka_done") end ------------------------------------------------------------------------------------------------------------------------------------------- -- STALKER TRADE FUNCTIONS ------------------------------------------------------------------------------------------------------------------------------------------- function has_tradable_stuff(actor, npc) end ------------------------------------------------------------------------------------------------------------------------------------------- -- end of STALKER TRADE FUNCTIONS ------------------------------------------------------------------------------------------------------------------------------------------- pioneer_functor = xr_statistic.pioneer_functor mutant_hunter_functor = xr_statistic.mutant_hunter_functor detective_functor = xr_statistic.detective_functor one_of_the_lads_functor = xr_statistic.one_of_the_lads_functor kingpin_functor = xr_statistic.kingpin_functor herald_of_justice_functor = xr_statistic.herald_of_justice_functor seeker_functor = xr_statistic.seeker_functor battle_systems_master_functor = xr_statistic.battle_systems_master_functor high_tech_master_functor = xr_statistic.high_tech_master_functor skilled_stalker_functor = xr_statistic.skilled_stalker_functor leader_functor = xr_statistic.leader_functor diplomat_functor = xr_statistic.diplomat_functor research_man_functor = xr_statistic.research_man_functor friend_of_duty_functor = xr_statistic.friend_of_duty_functor friend_of_freedom_functor = xr_statistic.friend_of_freedom_functor balance_advocate_functor = xr_statistic.balance_advocate_functor wealthy_functor = xr_statistic.wealthy_functor keeper_of_secrets_functor = xr_statistic.keeper_of_secrets_functor marked_by_zone_functor = xr_statistic.marked_by_zone_functor information_dealer_functor = xr_statistic.information_dealer_functor friend_of_stalkers_functor = xr_statistic.friend_of_stalkers_functor -------------------------------------------------------------------------------- function check_deimos_phase(actor, npc, p) if(p[1] and p[2]) then local obj = db.storage[npc:id()] local delta = sr_deimos.check_intensity_delta(obj) if(p[2]=="increasing" and delta) then return false elseif(p[2]=="decreasing" and not(delta)) then return false end if(p[1]=="disable_bound") then if(p[2]=="increasing") then if not(sr_deimos.check_disable_bound(obj)) then return true end elseif(p[2]=="decreasing") then return sr_deimos.check_disable_bound(obj) end elseif(p[1]=="lower_bound") then if(p[2]=="increasing") then if not(sr_deimos.check_lower_bound(obj)) then return true end elseif(p[2]=="decreasing") then return sr_deimos.check_lower_bound(obj) end elseif(p[1]=="upper_bound") then if(p[2]=="increasing") then if not(sr_deimos.check_upper_bound(obj)) then return true end elseif(p[2]=="decreasing") then return sr_deimos.check_upper_bound(obj) end end end end -------------------------------------------------------------------------------- function actor_in_surge_cover(actor, npc, p) return surge_manager.actor_in_cover() end function is_door_blocked_by_npc(actor, obj) return obj:is_door_blocked_by_npc() end function has_active_tutorial() return game.has_active_tutorial() end function upgrade_hint_kardan(actor, npc, p) local hint_table = {} local can_upgrade = 0 local tools = (p and tonumber(p[1])) or 0 if not has_alife_info("zat_b3_all_instruments_brought") then if not has_alife_info("zat_b3_tech_instrument_1_brought") and (tools == 0 or tools == 1) then table.insert(hint_table, "st_upgr_toolkit_1") elseif tools == 1 then can_upgrade = can_upgrade + 1 end if not has_alife_info("zat_b3_tech_instrument_2_brought") and (tools == 0 or tools == 2) then table.insert(hint_table, "st_upgr_toolkit_2") elseif tools == 2 then can_upgrade = can_upgrade + 1 end if not has_alife_info("zat_b3_tech_instrument_3_brought") and (tools == 0 or tools == 3) then table.insert(hint_table, "st_upgr_toolkit_3") elseif tools == 3 then can_upgrade = can_upgrade + 1 end else can_upgrade = can_upgrade + 1 end if not has_alife_info("zat_b3_tech_see_produce_62") then if (tools == 1) and not has_alife_info("zat_b3_tech_have_one_dose") then table.insert(hint_table, "st_upgr_vodka") elseif (tools ~= 1) and (not has_alife_info("zat_b3_tech_have_couple_dose")) then table.insert(hint_table, "st_upgr_vodka") else can_upgrade = can_upgrade + 1 end else can_upgrade = can_upgrade + 1 end inventory_upgrades.cur_hint = hint_table return can_upgrade >= 2 end