--[[ modified by Alundaio (original: ???? GSC) -]] function if_actor_powerful(actor, npc) return ((actor:character_reputation()) >= 1499) end function if_actor_not_powerful(actor, npc) return ((actor:character_reputation()) <= 1499) end -- used by tasks in precondition to randomly have it available to give the illusion to player that sim stalkers only sometimes have task function random_chance(actor,npc,p) local r = p and p[1] and tonumber(p[1]) or 50 if (math.random(1,100) < r) then return true end return false end -- checks if a task has stage of equal value -- param 1 - task_id -- param 2 - value function check_task_stage(actor,npc,p) local tm = task_manager.get_task_manager() local task_info = tm.task_info if (task_info[p[1]] and task_info[p[1]].stage == tonumber(p[2])) then --printf("p[1] = %s stage=%s",p[1],p[2]) return true end return false end function is_bounty(actor,npc,p) local id = npc:id() for task_id,npc_id in pairs(axr_task_manager.bounties_by_id) do if (npc_id == id) then return true end end return false end function npc_not_actor(actor,npc,p) return npc:id() ~= 0 or false end function dist_to_task_target_anomaly_le(actor,npc,p) local d = p[1] if not (d) then return false end local name = db.actor and utils.load_var(db.actor,"task_target_anomaly") if not (name) then return false end local anomaly = db.anomaly_by_name[name] if not (anomaly and anomaly.object) then return false end return heli_alife.distance_2d_sqr(npc:position(),anomaly.object:position()) <= tonumber(d)^2 end function has_task_target_anomaly(actor,npc,p) return db.actor and utils.load_var(db.actor,"task_target_anomaly") ~= nil end function actor_has_companion_slot(actor,npc,p) return db.actor and utils.load_var(db.actor,p[1] or "task_companion_slot_1") == nil end --param 1 dist --param 2 smart_name (optional) function check_nearest_smart_dist_le(actor,npc,p) if (smart_terrain.nearest_to_actor_smart.id and smart_terrain.nearest_to_actor_smart.dist > tonumber(p[1])) then return false end local smart = p[2] and SIMBOARD.smarts_by_names[p[2]] if (smart and smart_terrain.nearest_to_actor_smart.id and smart.id == smart_terrain.nearest_to_actor_smart.id) then return true end return false end function check_smart_dist_le(actor,npc,p) local smart = p[2] and SIMBOARD.smarts_by_names[p[2]] if (smart and smart.position:distance_to(npc:position()) <= (tonumber(p[1]) or 0)) then return true end return false end ----------------------- -- Task ----------------------- function has_task(actor,npc,p) local task_info = p[1] and task_manager.get_task_manager().task_info[p[1]] if not (task_info) then return false end return p[2] == nil or task_info.status == p[2] end function has_task_on_stage(actor,npc,p) local task_info = p[1] and task_manager.get_task_manager().task_info[p[1]] if not (task_info) then return false end return task_info.stage == (tonumber(p[2] or 0) or 0) end function has_task_not_completed(actor,npc,p) local task_info = p[1] and task_manager.get_task_manager().task_info[p[1]] if not (task_info) then return false end return task_info.status ~= "completed" and task_info.status ~= "fail" end function has_completed_task_prerequisites(actor,npc,p) if not (p[1]) then return true end local precond = task_manager.task_ini:r_string_ex(p[1],"precondition") if (precond and precond ~= "") then precond = xr_logic.parse_condlist(npc, p[1], "precondition", task_manager.task_ini:r_string_ex(p[1],"precondition") or "true") if (precond == "false") then return false end if (db.actor and xr_logic.pick_section_from_condlist(db.actor, npc, precond) == "false") then return false end end local prereq = task_manager.task_ini:r_string_ex(p[1],"prerequisites") if (prereq == nil or prereq == "") then return true end local tm = task_manager.get_task_manager() local info = tm.task_info if (info[p[1]]) then -- HAS TASK ALREADY! return false end prereq = alun_utils.str_explode(prereq,",") local tsk for i=1,#prereq do tsk = prereq[i] if not (info[tsk]) then --printf("no tsk %s",tsk) return false end if (info[tsk].status ~= "completed" and info[tsk].status ~= "fail") then --printf("task %s not completed %s",task,info[tsk].status) return false end end return true end function dist_to_lvid_ge(actor,npc,p) local vid = tonumber(p[1]) if not (vid) then return false end local position = level.vertex_position(vid) if (npc:position():distance_to_sqr(position) >= tonumber(p[2])) then return true end return false end function dist_to_job_point_le(actor, npc, p) if not (npc) then return false end local smart = xr_gulag.get_npc_smart(npc) if smart == nil then return false end local npc_info = smart.npc_info[npc:id()] if npc_info then local npc_job = npc_info.job if (npc_job) then local alife_task = npc_job.alife_task if alife_task then return npc:position():distance_to_sqr(alife_task:position()) <= p[1]*p[1] end end end return false end function sim_avail(actor,npc,p) local smart = p[1] and SIMBOARD.smarts_by_names[p[1]] if not (smart) then return false end return smart.sim_avail == nil or smart.sim_avail and xr_logic.pick_section_from_condlist(actor, smart, smart.sim_avail) == "true" or false end -- param 1 = smart -- param 2 = section logic (omit 'logic@') -- param 3 = distance function dist_to_obj_on_job_le(actor,npc,p) if not (npc) then return false end local board = SIMBOARD local smart = p[1] and board and board.smarts_by_names[p[1]] if not (smart) then return false end local obj = smart and smart.npc_by_job_section["logic@"..p[2]] obj = obj and (db.storage[obj] and db.storage[obj].object or level.object_by_id(obj)) if not (obj) then return false end return npc:position():distance_to_sqr(obj:position()) <= tonumber(p[3])^2 end function dist_to_job_point_ge(actor, npc, p) if not (npc) then return false end local smart = xr_gulag.get_npc_smart(npc) if smart == nil then return false end local npc_info = smart.npc_info[npc:id()] if npc_info then local npc_job = npc_info.job if (npc_job) then local alife_task = npc_job.alife_task if alife_task then return npc:position():distance_to_sqr(alife_task:position()) >= p[1]*p[1] end end end return false end -- Каждая функция в этом файле используется как условие xr_logic: {=функция !функция} -- Если в функцию необходимо передавать параметры, то: {=функция(парам1:парам2:...) !функция(парам1:парам2:...)} -- Формат: function f(actor, npc). В случае передачи параметров: function f(actor, npc, p). -- ---------------------------------------------------------------------------------------------------- -- Functions for working specifically with combat_ignore_cond -- ---------------------------------------------------------------------------------------------------- -- Match name against all given params (ex. {=check_enemy_name(name1:name2:name3:name4)}) function check_enemy_name (enemy , npc , p) 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_enemy_fighting_actor(enemy,npc) if (enemy:alive() and xr_combat_ignore.fighting_with_actor_npcs[enemy:id()]) then return true end return false end function is_enemy_actor(enemy, npc) return enemy:id() == 0 end function is_enemy_actor_or_companion(enemy,npc) if (IsMonster(enemy)) then return false end if not (npc:relation(enemy) >= game_object.enemy) then return false end local id = enemy:id() if (id == 0) then return true end if (alife():has_info(id,"npcx_is_companion")) then return true end return false end -- current enemy at a distance greater than or equal to the specified Distance -- для combat_ignore -- param 1 - distance^2 function fighting_dist_ge(enemy, npc, p) return enemy:alive() and enemy:position():distance_to_sqr(npc:position()) >= p[1]^2 or false end -- param 1 - distance^2 function fighting_dist_le(enemy, npc, p) return enemy:alive() and enemy:position():distance_to_sqr(npc:position()) <= p[1]^2 or false end -- param 1 zone name function enemy_in_zone(enemy, npc, p) return utils.npc_in_zone(enemy, p[1]) or false end -- param 1 - Community to match function is_enemy_community(enemy,npc,p) return enemy:alive() and character_community(enemy) == p[1] end -- Check for membership to one of the enemy groups (simboard.group_id_by_levels) -- Each Squad spawned is given a group id according to level -- All squads on a certain level will have matching level group ids -- (You can check more than one) function enemy_group(enemy, npc, p) if not (enemy:alive()) then return false end local g = enemy:group() 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 -- see above function is_enemy_same_group(actor,npc) local st = db.storage[npc:id()] local enemy = st and st.enemy_id and (db.storage[st.enemy_id] and db.storage[st.enemy_id].object or level.object_by_id(st.enemy_id)) if (not enemy:alive()) then return false end return enemy:group() == npc:group() end ------------------------------- -- Conditions for enemies before combat_ignore_cond is checked ------------------------------- function see_pure_enemy(actor,npc) local st = db.storage[npc:id()] local enemy = st and st.enemy_id and (db.storage[st.enemy_id] and db.storage[st.enemy_id].object or level.object_by_id(st.enemy_id)) return enemy and enemy:alive() and npc:see(enemy) or false end function pure_enemy_dist_le(actor,npc,p) local st = db.storage[npc:id()] local enemy = st and st.enemy_id and (db.storage[st.enemy_id] and db.storage[st.enemy_id].object or level.object_by_id(st.enemy_id)) return enemy and enemy:alive() and enemy:position():distance_to_sqr(npc:position()) <= p[1]^2 or false end -- Returns true if a NPC's pure enemy (before ignore_cond) occupies a job by section for a given smart -- param 1 is the job section (ie. "logic@walker1") -- param 2 is the smart name. If it's empty it will default to calling NPC's smart function is_enemy_on_job(actor, npc, p) local st = db.storage[npc:id()] local enemy = st and st.enemy_id and (db.storage[st.enemy_id] and db.storage[st.enemy_id].object or level.object_by_id(st.enemy_id)) if (enemy == nil or not enemy:alive()) then return false end local smart if p and p[2] then smart = SIMBOARD:get_smart_by_name(p[2]) else smart = xr_gulag.get_npc_smart(enemy) end if smart == nil then return false end for id,npc_info in pairs(smart.npc_info) do if (npc_info.job and npc_info.job.section == p[1]) then return true end end return false end -- Returns true if enemy's smart equals the given smart -- param 1 is the smart name function enemy_smart(actor, npc, p) local st = db.storage[npc:id()] local enemy = st and st.enemy_id and (db.storage[st.enemy_id] and db.storage[st.enemy_id].object or level.object_by_id(st.enemy_id)) if (enemy == nil or not enemy:alive()) then return false end local smart = xr_gulag.get_npc_smart(enemy) if not (smart) then return false end return p and smart:name() == p[1] end function has_pure_enemy(actor, npc) local st = db.storage[npc:id()] local enemy = st and st.enemy_id and (db.storage[st.enemy_id] and db.storage[st.enemy_id].object or level.object_by_id(st.enemy_id)) return enemy and enemy:alive() or false end -- param 1 - Enemy's Time-in-memory less_than_equal_to function pure_enemy_mem_time_le(actor, npc, p) local st = db.storage[npc:id()] local enemy = st and st.enemy_id and (db.storage[st.enemy_id] and db.storage[st.enemy_id].object or level.object_by_id(st.enemy_id)) return p and p[1] and enemy and enemy:alive() and npc:memory_time(enemy) <= tonumber(p[1]) or false 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 for k,v in pairs(p) do if string.find( npc:name(), v ) then return true end end return false end function check_squad_name (actor , npc , p) local squad = get_object_squad(npc) if not (squad) then return end local sq for k,v in pairs(p) do sq = get_story_squad(v) if (sq and sq.id == squad.id) then return true end end return 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 and 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 printf("Wrong parameter in 'dist_to_actor_le' function!!!") end return d and npc:position():distance_to_sqr(actor:position()) <= tonumber(d)^2 end function dist_to_actor_ge(actor, npc, p) local d = p[1] if d == nil then printf("Wrong parameter in 'dist_to_actor_ge' function!!!") end return d and npc:position():distance_to_sqr(actor:position()) >= tonumber(d)^2 end -- проверка того что npc находится в заданной зоне -- !!! ВЫЗЫВАТЬ ТОЛЬКО ИЗ SPACE RESTRICTOR !!! -- параметры: [sid1:sid2:...] -- !!! НЕКОРРЕКТНО РАБОТАЕТ ДЛЯ ОБЬЕКТОВ В offline'e !!! -- !!! ДЛЯ ГАРАНТИИ ИСПОЛЬЗОВАТЬ one_obj_in_zone !!! function obj_in_zone(actor, zone, p) local sim = alife() for i, v in pairs(p) do local id = get_story_object_id(v) local se_obj = id and alife():object_by_id(id) if se_obj and zone:inside(se_obj.position) then return true end end return false end -- checks if any npc who has jobs at a given smart is in a given zone -- param 1 - smart name -- param 2 - zone name function check_npc_from_gulag_in_zone(actor,npc,p) local smart = p[1] and SIMBOARD.smarts_by_names[p[1]] if not (smart) then return false end local zone = p[2] and db.zone_by_name[p[2]] if not (zone) then return false end for id,se_obj in pairs(smart.npc_info) do if (se_obj.position and zone:inside(se_obj.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 id = get_story_object_id(p[1]) local se_obj = id and alife_object(id) if se_obj then -- npc is online return zone:inside(se_obj.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 id = get_story_object_id(p[1]) local se_obj = id and alife_object(id) local zone = db.zone_by_name[p[2]] if se_obj and zone then -- npc is online return zone:inside(se_obj.position) end return false end function actor_in_zone(actor, npc, p) if not (db.actor) then return false end for i=1,#p do local zone = db.zone_by_name[p[i]] if (zone and zone:inside(db.actor:position())) then return true end end return false end function actor_out_zone(actor, npc, p) return not utils.npc_in_zone(db.actor, p[1]) end function npc_in_zone(actor, npc, p) if not (npc and type(npc.position) == "function") then return false end for i=1,#p do local zone = db.zone_by_name[p[i]] if (zone and zone:inside(npc:position())) then return true end end return false 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 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 printf("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 printf("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 printf("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 sim = alife() for i, v in pairs(p) do local id = get_story_object_id(v) local se_obj = id and sim:object(id) if se_obj and (not IsStalker(nil,se_obj:clsid()) or not se_obj:alive()) then return false end end return true end -- проверка (по story_id) того, что чотя бы один из проверяемых сталкеров жив -- TODO: исправить ситуацию, когда выдается неправильный результат для обьектов, которые -- не успели проспавниться. function is_alive_one(actor, npc, p) local sim = alife() for i, v in pairs(p) do local id = get_story_object_id(v) local se_obj = id and sim:object(id) if se_obj and IsStalker(nil,se_obj:clsid()) and se_obj:alive() then return true end end return false end -- проверка (по story_id) того, что проверяемыq npc жив -- TODO: исправить ситуацию, когда выдается неправильный результат для обьектов, которые -- не успели проспавниться. function is_alive(actor, npc, p) local id if npc == nil or (p and p[1]) then id = get_story_object_id(p[1]) elseif (type(npc.id) == "number") then id = npc.id else id = npc:id() end if npc1 == nil then return false end local se_obj = id and alife_object(id) if se_obj and IsStalker(nil,se_obj:clsid()) and se_obj: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 = utils.load_var(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 = utils.load_var(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 ------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------- -- Функции поддержки безопасности баз function check_smart_alarm_status(actor, npc, p) local smart = p[1] and SIMBOARD:get_smart_by_name(p[1]) return smart and smart:check_alarm() or false end ------------------------------------------------------------------------------------------------------- function has_enemy(actor, npc) local be = npc:best_enemy() return be and be:alive() or false end function has_actor_enemy(actor, npc) local best_enemy = npc:best_enemy() return db.actor and 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()) or false 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] and p[2]) then return game_relations.is_factions_enemies(p[1], p[2]) 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] and p[2]) then return game_relations.is_factions_friends(p[1], p[2]) 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 db.actor and 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 db.actor and 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 printf("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() or false 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()) 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() return killed_by_actor end function actor_has_weapon (actor, npc) local obj = actor:active_item() if (obj and IsWeapon(obj)) then return true end return false end function actor_active_detector(actor, npc, p) local detector_section = p and p[1] if detector_section == nil then printf("Wrong parameters in function 'actor_active_detector'") end local actor_detector = db.actor and 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_night (actor, npc) return db.actor ~= nil and (level.get_time_hours() < 5 or level.get_time_hours() > 19) 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 npc_on_level(actor, npc, p) local sim = alife() local se_obj = p[1] and npc and (type(npc.id) == "function" and sim:object(npc:id()) or npc) if not (se_obj) then return false end local gg = game_graph() if (sim:level_name(gg:vertex(se_obj.m_game_vertex_id):level_id()) == p[1]) then return true 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 printf("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 = SIMBOARD local squad = get_story_squad(story_id) if squad == nil then --printf("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 --printf("There is no squad with id[%s]", tostring(zone_name)) return false end local sim = alife() for k in squad:squad_members() do local se_obj = k.id and sim:object(k.id) if (se_obj and zone:inside(se_obj.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 printf("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 --printf("There is no squad with id[%s]", tostring(story_id)) return false end local obj_by_id = level.object_by_id for k in squad:squad_members() do local npc_obj = k.id and object_by_id(k.id) if (npc_obj and 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 printf("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 --printf("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 --printf("There is no squad with id[%s]", tostring(zone_name)) return false end local sim = alife() for k in squad:squad_members() do local se_obj = k.object or k.id and sim:object(k.id) if (se_obj and zone:inside(se_obj.position)) then return true end end return true end function squads_in_zone_b41(actor, npc, p) local smart = SIMBOARD: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(SIMBOARD.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 squads_in_zone_yan_smart_terrain_6_4(actor, npc, p) local smart = SIMBOARD:get_smart_by_name("yan_smart_terrain_6_4") local zone = db.zone_by_name["yan_smart_terrain_6_4_sr_light"] local al = alife() if zone == nil then return false end if smart == nil then return false end for k,v in pairs(SIMBOARD.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 printf("Wrong parameters") end if not(obj) then return false end --callstack() if IsStalker(obj) or IsMonster(obj) then local squad = obj.group_id and obj.group_id ~= 65535 and alife_object(obj.group_id) if not (squad) then return false end if string.find( squad: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 printf("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 printf("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 and squad:commander_id() == npc_id or squad == nil end function squad_npc_count_ge(actor, npc, p) local story_id = p[1] if story_id == nil then printf("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() if (psi_storm_manager and psi_storm_manager.is_loaded()) then if not (psi_storm_manager.is_finished()) then return false end end if (surge_manager and surge_manager.is_loaded()) then return surge_manager.is_finished() end return true end function surge_started() if (psi_storm_manager and psi_storm_manager.is_loaded() and psi_storm_manager.is_started()) then return true end if (surge_manager and surge_manager.is_loaded() and surge_manager.is_started()) then return true end return false end function surge_kill_all() return surge_manager and surge_manager.is_killing_all() or false end function signal_rocket_flying(actor, npc, p) if p==nil then printf("Signal rocket name is not set!") end if db.signal_light[p[1]] then return db.signal_light[p[1]]:is_flying() else printf("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 printf("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 printf("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 ~= nil and 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 ~= nil and 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() local itm = db.actor ~= nil and db.actor:active_item() if not (itm) then return true end if not (IsWeapon(itm)) then return true end if (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 printf("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 id = db.actor and p and get_story_object_id(p[1]) local se_obj = id and alife_object(id) return se_obj and se_obj.position:distance_to(db.actor:position()) > tonumber(p[2]) or false 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 == 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 return ActorMenu.get_menu_mode() == 4 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 give_info(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 printf("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 printf("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 (db.actor and 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 = get_object_squad(npc) if (squad) then local sim = alife() for k in squad:squad_members() do local se_obj = k.object or k.id and sim:object(k.id) if (se_obj and se_obj.position:distance_to_sqr(actor:position()) < distance) then return true end 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 (db.actor and 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 = get_object_squad(npc) if (squad) then local sim = alife() for k in squad:squad_members() do local se_obj = k.object or k.id and sim:object(k.id) if (se_obj and se_obj.position:distance_to_sqr(actor:position()) < distance) then return true end 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 local squad = get_object_squad(npc) if not (squad) then return false end for k,v in pairs(squads_table) do if squad: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, 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 ------------------------------------------------------------------------------------------------------------------------------------------- -- online only function npc_has_items_to_sell(actor,npc,p) if not (npc) then return false end local id = type(npc.id) == "function" and npc:id() or npc.id local st = db.storage[id] if not (st) then return false end if not (st.has_items_to_sell) then return false end local smart = p and p[1] and SIMBOARD.smarts_by_names[p[1]] if (smart and smart.npc_info[id]) then local job = smart.npc_info[id].job if (job and job.idle and time_global() < job.idle) then return false end end return true end ------------------------------------------------------------------------------------------------------------------------------------------- -- end of STALKER TRADE FUNCTIONS ------------------------------------------------------------------------------------------------------------------------------------------- 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 and 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 -- AtmosFear Psi Storm function psi_storm_complete() return psi_storm_manager.is_finished() end -- Returns true if calling NPC has the surrender flag to actor function npc_surrendered(actor,npc,p) if not (db.actor) then return false end local st = db.storage[npc:id()] return st and st.victim_surrender == db.actor:id() or false end -- Returns true if calling NPC has the surrender flag function npc_surrendered_any(actor,npc,p) local st = db.storage[npc:id()] return st and st.victim_surrender >= 0 and st.victim_surrender < 65534 or false end function actor_class(actor,npc,p) return p and p[1] and axr_misery and axr_misery.ActorClass == p[1] or false end function black_road_enabled(actor,npc,p) return axr_misery and axr_misery.MiseryBlackRoad or false end -- Returns true if a squad behavior equals given -- param 1 is player_id (squad behavior, see _g.script) function squad_behavior(actor,npc,p) local se_npc = type(npc.id) == "function" and alife_object(npc:id()) or npc local squad = se_npc and se_npc.parent_id ~= 65535 and alife_object(se_npc.parent_id) return p and p[1] and squad and squad.player_id == p[1] or false end -- Returns true if a anim state equals given -- param 1 is state function anim_state(actor,npc,p) return p and p[1] and state_mgr.get_state(npc) == p[1] or false end -- Returns if a smart is empty -- param 1 is smart name function smart_empty(actor,npc,p) local board = SIMBOARD local smart = p[1] and board.smarts_by_names[p[1]] if not (smart) then return false end local smart_id = smart.id local sim = alife() for k,v in pairs(board.smarts[smart_id].squads) do if (v.id and sim:object(v.id)) then return false end end return true end function npc_squad_has_enemy(actor,npc,p) local squad = get_object_squad(npc) if not (squad) then return false end local o local object_by_id = level.object_by_id for k in squad:squad_members() do o = k.id and object_by_id(k.id) if (o and o:best_enemy()) then return true end end end -- Returns true if a NPC at a certain smart was hit by calling NPC -- param 1 is smart name function hit_by_enemy_on_smart(actor,npc,p) local id = db.storage[npc:id()].hitted_by local who = id and level.object_by_id(id) if (not who or not who:alive()) then return false end local smart = xr_gulag.get_npc_smart(who) return p and p[1] and smart and smart:name() == p[1] or false end function is_upgrading(actor, npc, p) -- pda.upgrade_closed = not pda.upgrade_closed -- return not pda.upgrade_closed return pda.upgrade_closed end --'----------------------------------------------------------------------------------- --' Minigun support --'----------------------------------------------------------------------------------- function is_minigun_see_actor (actor, npc) local mgun = npc:get_car() return mgun:IsObjectVisible(actor) end function is_minigun_see_current_target(actor,npc,p) local st = npc and db.storage[npc:id()] if not (st) then return false end if not (st.ph_minigun) then return false end if (st.ph_minigun.fire_target == nil or st.ph_minigun.fire_target == "") then return false end if (st.ph_minigun.target_obj == nil or not st.ph_minigun.target_obj:alive()) then return false end return npc:get_car():IsObjectVisible(st.ph_minigun.target_obj) end function squad_hit_by_smart(actor,npc,p) local squad = get_object_squad(npc) if not (squad) then return false end local who,smart local object_by_id = level.object_by_id for k in squad:squad_members() do who = k.id and db.storage[k.id].hitted_by and object_by_id(db.storage[k.id].hitted_by) smart = who and xr_gulag.get_npc_smart(who) if (smart and smart:name() == p[1]) then return true end end return false end function actor_look_away(actor,npc) if not (db.actor) then return false end if (not db.actor:see(npc) or (alun_utils.angle_diff(db.actor:direction(), db.actor:position():sub(npc:position()))<90 and npc:position():distance_to(db.actor:position()) > 2.5) or npc:position():distance_to(db.actor:position())>100) then return true end return false end function between_time(actor,npc,p) return in_time_interval(tonumber(p[1]),tonumber(p[2])) or false end function squad_is_monster(actor,squad,p) return is_squad_monster[squad.player_id] == true end function companion_at_index(actor,npc,p) if (p == nil or p[1] == nil) then return false end local id = db.actor ~= nil and utils.load_var(db.actor,"companion_"..p[1],nil) return id and id == npc:id() or false end function after_first_meet(actor,npc,p) local st = db.storage[npc:id()] if not (st) then return false end return st.after_first_meet == true end function squad_on_actor_map(actor,npc,p) local squad = get_object_squad(npc) if not (squad) then return false end local gg = game_graph() return gg:vertex(alife():actor().m_game_vertex_id):level_id() == gg:vertex(squad.m_game_vertex_id):level_id() end -- Returns true if squad commander's active section equals param 1 -- param 2 - active section (ie. "logic@walker1") function squad_commander_active_section(actor,npc,p) local squad = p[1] and get_object_squad(npc) local st = squad and squad:commander_id() and db.storage[squad:commander_id()] return st and st.active_section == p[1] or false end -- Returns true if a NPC on a given job has a patrol index equalling given -- param 1 is smart name -- param 2 is job section (ie. "logic@walker_1") in this case omit 'logic@' -- param 3 is index -- param 4 is min allowed radius to patrol point -- param 5 is boolean, returns true if job is empty function job_on_point(actor,npc,p) -- p[1] = smart_name p[2] = logic p[3] = index p[4] = less_than_equal_to Distance p[5] = return true if object is dead or doesn't exist local board = SIMBOARD local smart = p[1] and board and board.smarts_by_names[p[1]] local obj = smart and smart.npc_by_job_section["logic@"..p[2]] local st = db.storage[obj] obj = obj and (st and st.object or level.object_by_id(obj)) if not (obj) then return p[5] == "true" end local index = st and st.active_scheme and st.active_scheme == "beh" and utils.load_var(obj,"path_index",nil) or obj:get_current_point_index() if (p[4] and index == tonumber(p[3])) then if (st and st.active_scheme and st.active_scheme == "beh") then if (axr_beh.am_i_reached(obj)) then return true end return false end local path = obj:patrol() local pos = path and patrol(path):point(tonumber(p[3])) local dist = pos and obj:position():distance_to_sqr(pos) return dist <= tonumber(p[4]) end return index == tonumber(p[3]) end -- Checks if npc distance is less than equal to given patrol point -- param 1 is patrol path name -- param 2 is path index -- param 3 is distance less than equal function dist_to_point_le(actor,npc,p) local pat = p[1] and level.patrol_path_exists(p[1]) and patrol(p[1]) if (pat) then local index = p[2] and tonumber(p[2]) or 0 local dist = npc:position():distance_to_sqr(pat:point(index)) return dist <= tonumber(p[3]) end return false end function beh_reached(actor,npc,p) return p[1] and axr_beh.am_i_reached(npc,tonumber(p[1])) or axr_beh.am_i_reached(npc) end -- Returns true if a NPC occupies a given job -- param 1 is smart name -- param 2 is job section (ie. "logic@walker_1") in this case omit 'logic@' -- param 3 is optional check for active_section function obj_on_job(actor,npc,p) local board = SIMBOARD local smart = p[1] and board and board.smarts_by_names[p[1]] local id = smart and smart.npc_by_job_section["logic@"..p[2]] local st = id and db.storage[id] local obj = id and (st and st.object or level.object_by_id(id)) --printf("obj=%s",obj and obj:name()) if not (p[3]) then return obj and obj:alive() or false end return st and st.active_section == p[3] or false end -- Returns true if a NPC sees another NPC on a given job -- param 1 is smart name -- param 2 is job section (ie. "logic@walker_1") in this case omit 'logic@' function see_obj_on_job(actor,npc,p) local board = SIMBOARD local smart = p[1] and board and board.smarts_by_names[p[1]] local obj = smart and smart.npc_by_job_section["logic@"..p[2]] obj = obj and (db.storage[obj] and db.storage[obj].object or level.object_by_id(obj)) return obj and obj:alive() and npc:memory_time(obj) < 5000 or false end -- Returns true if a NPC on a given job is in danger mode -- param 1 is smart name -- param 2 is job section (ie. "logic@walker_1") in this case omit 'logic@' function obj_on_job_danger(actor,npc,p) local board = SIMBOARD local smart = p[1] and board and board.smarts_by_names[p[1]] local obj = smart and smart.npc_by_job_section["logic@"..p[2]] obj = obj and (db.storage[obj] and db.storage[obj].object or level.object_by_id(obj)) return obj and db.storage[obj:id()].danger_flag or false end -- Returns true if a NPC on a given job was hit by calling NPC -- param 1 is smart name -- param 2 is job section (ie. "logic@walker_1") in this case omit 'logic@' function obj_on_job_hit_by(actor,npc,p) local board = SIMBOARD local smart = p[1] and board and board.smarts_by_names[p[1]] local obj = smart and smart.npc_by_job_section["logic@"..p[2]] obj = obj and (db.storage[obj] and db.storage[obj].object or level.object_by_id(obj)) if (not obj and not obj:alive()) then return false end local id = db.storage[obj:id()].hitted_by return id and id == npc:id() or false end -- Returns true if a NPC's on a given job has a given active section -- param 1 is smart name -- param 2 is job section (ie. "logic@walker_1") in this case omit 'logic@' -- param 3 is active section (ie. "walker@walker_1_surge_1") function job_active_section(actor,npc,p) local board = SIMBOARD local smart = p[1] and board and board.smarts_by_names[p[1]] local obj = smart and smart.npc_by_job_section["logic@"..p[2]] obj = obj and (db.storage[obj] and db.storage[obj].object or level.object_by_id(obj)) local st = obj and db.storage[obj:id()] return st and st.active_section == p[3] or false end -- Returns true if ONLY monster-type NPC's occupy a given smart -- param 1 is smart name function is_only_monsters_on_jobs(actor,npc,p) local board = SIMBOARD local smart = p[1] and board and board.smarts_by_names[p[1]] if not (smart) then return false end for id,npc_info in pairs(smart.npc_info) do if (npc_info.stype ~= modules.stype_mobile) then return false end end return true end -- Returns true if ONLY stalkers occuppy a given smart -- param 1 is smart name function is_only_stalkers_on_jobs(actor,npc,p) local board = SIMBOARD local smart = p[1] and board and board.smarts_by_names[p[1]] if not (smart) then return false end for id,npc_info in pairs(smart.npc_info) do if (npc_info.stype == modules.stype_mobile or npc_info.stype == modules.stype_heli) then return false end end return true end -- Returns true if ONLY a given community occupies a given smart -- param 1 is smart name function is_only_community_on_jobs(actor,npc,p) local board = SIMBOARD local smart = p[1] and board and board.smarts_by_names[p[1]] if not (smart) then return false end for id,npc_info in pairs(smart.npc_info) do if (npc_info.se_obj and (npc_info.stype == 0 or npc_info.stype == 1) and npc_info.se_obj:character_community() ~= p[2]) then return false end end return true end function smart_squad_by_faction_in_radius(actor,npc,p) local smart = p[1] and p[2] and p[3] and SIMBOARD.smarts_by_names[p[1]] if not (smart) then return false end local smrt = SIMBOARD.smarts[smart.id] if not (smrt) then return false end for k,squad in pairs(smrt.squads) do if (squad and squad.player_id == p[2] and squad.position:distance_to_sqr(smart.position) <= tonumber(p[3])^2) then return true end end return false end -- Returns true if squads by behavior faction (player_id) of a given count exist at smart out of squads currently entered in smart -- param1 - smart_name -- param2 - greater than equal to number -- param3 - check if stay time is less than equal given seconds -- param4 - include check for squads with scripted target (usually quest squads) -- param5+ - faction aka player_id function smart_stayed_squad_count_ge_by_faction(actor,npc,p) if (#p < 5) then return false end local smart = SIMBOARD.smarts_by_names[p[1]] if not (smart) then return false end local smrt = SIMBOARD.smarts[smart.id] if not (smrt) then return false end local count = 0 for k,squad in pairs(smrt.squads) do if (squad and simulation_objects.is_on_the_same_level(squad, smart) and squad.current_target_id and squad.current_target_id == smart.id and squad.current_action == 1) then if (p[4] == "true" or not squad:get_script_target()) then if (squad.stay_time) and (p[3] == "nil" or game.get_game_time():diffSec(squad.stay_time) <= (tonumber(p[3]) or 0)) then for i=5,#p do if (p[i] == "monster" and is_squad_monster[squad.player_id] or squad.player_id == p[i]) then count = count + 1 if (count >= tonumber(p[2])) then squad.stay_time = game.get_game_time() return true end break end end end end end end return false end -- checks all smarts on actor level with above function -- param1 - greater than equal to number -- param2 - check if stay time is less than equal given seconds -- param3 - allow check for target_smart param for squads; such as scripted target. -- param4+ - faction aka player_id function all_avail_smart_stayed_squad_count_ge_by_faction(actor,npc,p) if (#p >= 4) then for name,v in pairs(SIMBOARD.smarts_by_names) do if (v.online) and (v.sim_avail == nil or v.sim_avail and xr_logic.pick_section_from_condlist(actor, v, v.sim_avail) == "true") then if (smart_stayed_squad_count_ge_by_faction(actor,npc,{name,unpack(p)}) == true) then return true end end end end return false end -- same as above but checks all levels function all_avail_smart_stayed_squad_count_ge_by_faction_ex(actor,npc,p) if (#p >= 4) then local sim = alife() local gg = game_graph() local actor_level = sim:level_name(gg:vertex(sim:actor().m_game_vertex_id):level_id()) for name,v in pairs(SIMBOARD.smarts_by_names) do if (v.sim_avail == nil or v.sim_avail and xr_logic.pick_section_from_condlist(actor, v, v.sim_avail) == "true") then local smart_level = alife():level_name(game_graph():vertex(v.m_game_vertex_id):level_id()) if (v.online or DEACTIVATE_SIM_ON_NON_LINKED_LEVELS ~= true or string.find(simulation_objects.config:r_value(actor_level,"target_maps",0,""),smart_level)) then if (smart_stayed_squad_count_ge_by_faction(actor,npc,{name,unpack(p)}) == true) then return true end end end end end return false end -- Returns true if squads by behavior faction (player_id) of a given count exist at smart out of entire population; including arriving -- param1 - smart_name -- param2 - faction aka player_id -- param3 - greater than equal to number function smart_squad_count_ge_by_faction(actor,npc,p) local smart = p[1] and p[2] and p[3] and SIMBOARD.smarts_by_names[p[1]] if not (smart) then return false end local smrt = SIMBOARD.smarts[smart.id] if not (smrt) then return false end local count = 0 for k,squad in pairs(smrt.squads) do if (squad and squad.player_id == p[2]) then count = count + 1 end end return count >= tonumber(p[4]) end function smart_population_count(actor,npc,p) local smart = p[1] and SIMBOARD.smarts_by_names[p[1]] if not (smart) then return false end return p[2] and SIMBOARD.smarts[smart.id] and SIMBOARD.smarts[smart.id].population == tonumber(p[2]) or false end function smart_population_count_ge(actor,npc,p) local smart = p[1] and SIMBOARD.smarts_by_names[p[1]] if not (smart) then return false end return p[2] and SIMBOARD.smarts[smart.id] and SIMBOARD.smarts[smart.id].population >= tonumber(p[2]) or false end function smart_population_count_le(actor,npc,p) local smart = p[1] and SIMBOARD.smarts_by_names[p[1]] if not (smart) then return false end return p[2] and SIMBOARD.smarts[smart.id] and SIMBOARD.smarts[smart.id].population <= tonumber(p[2]) or false end -- Returns true if any instance of given community occupies a given smart -- param 1 is smart name function is_community_on_jobs(actor,npc,p) local board = SIMBOARD local smart = p[1] and board and board.smarts_by_names[p[1]] if not (smart) then return false end for id,npc_info in pairs(smart.npc_info) do if (npc_info.se_obj and (npc_info.stype == 0 or npc_info.stype == 1) and npc_info.se_obj:character_community() == p[2]) then return true end end return false end function is_community_arriving(actor,npc,p) local board = SIMBOARD local smart = p[1] and board and board.smarts_by_names[p[1]] if not (smart) then return false end for id,se_obj in pairs(smart.arriving_npc) do if (se_obj and IsStalker(se_obj) and se_obj:character_community() == p[2]) then return true end end return false end function community_arriving_dist_ge(actor,npc,p) local board = SIMBOARD local smart = p[1] and board and board.smarts_by_names[p[1]] if not (smart) then return false end local exist for id,se_obj in pairs(smart.arriving_npc) do if (se_obj and IsStalker(se_obj) and se_obj:character_community() == p[2]) then exist = true if (se_obj.position:distance_to_sqr(smart.position) >= tonumber(p[3] or 10000)) then return true end end end -- community does not exist at smart return true if not (exist) then return true end return false end --' SP -- Sidor --------------------------------------- function trade_exchanged(actor, npc) local npc_id = npc:id() return (db.storage[npc_id].mob_trade and db.storage[npc_id].mob_trade.exchanged) --or false end function trading(actor, npc) local npc_id = npc:id() return (db.storage[npc_id].mob_trade and db.storage[npc_id].mob_trade.trading) --or false end function trade_sell_coast_b_1000(actor, npc) return db.storage[npc:id()].mob_trade.sell_coast > 1000 end function trade_sell_coast_b_0_m_1000(actor, npc) return db.storage[npc:id()].mob_trade.sell_coast > 0 and db.storage[npc:id()].mob_trade.sell_coast < 1000 end function trade_buy_coast(actor, npc) return db.storage[npc:id()].mob_trade.buy_coast > 1000 end function trade_all_money(actor, npc) return db.storage[npc:id()].mob_trade.all_money > 2000 end -- Sidor --------------------------------------- --' SP function npc_in_actor_community(actor,npc,p) local comm = character_community(npc) return db.actor and string.find(character_community(db.actor),comm) ~= nil end function actor_community(actor,npc,p) if not (db.actor) then return false end for i=1,#p do if (character_community(db.actor) == p[i]) then return true end end return false end function actor_goodwill_ge(actor,npc,p) if (p[1] and p[2]) then return db.actor and relation_registry.community_goodwill(p[1], db.actor:id()) >= tonumber(p[2]) end return false end function task_giver_alive(actor,npc,p) if not (p[1]) then return false end local tm = task_manager.get_task_manager() local tsk = tm.task_info[p[1]] if not (tsk) then return true end local se_obj = tsk.task_giver_id and alife_object(tsk.task_giver_id) if (se_obj) then if (se_obj:clsid() == clsid.online_offline_group_s) then return true -- if squad exist then atleast 1 npc should be alive elseif (se_obj:alive()) then return true end end return false end function is_a_task_giver(actor,npc,p) local tm = task_manager.get_task_manager() for task_id,tsk in pairs(tm.task_info) do if (tsk.task_giver_id and tsk.task_giver_id == npc:id()) then return true end end return false end -- param1 - smart by name -- param2 - community -- param3 - if true, then it will check_npc_name for that faction (This is used for suitable in logic section) function smart_under_faction_control(actor,npc,p) local board = SIMBOARD local smart = p[1] and board and board.smarts_by_names[p[1]] if not (smart) then return false end if not (smart.faction and smart.faction_controlled) then return false end if not (p[2] and smart.faction == p[2]) then return false end if (p[3] and p[3] == "true") then if npc:name() == nil then return false end local f = { ["stalker"] = "stalker", ["bandit"] = "bandit", ["killer"] = "merc", ["dolg"] = "duty", ["freedom"] = "freedom", ["monolith"] = "monolith", ["ecolog"] = "ecolog", ["csky"] = "csky", ["army"] = "military" } if not (f[p[2]]) then return false end if string.find( npc:name(), f[p[2]] ) then return true end else return true end return false end function smart_under_faction_war(actor,npc,p) local board = SIMBOARD local smart = p[1] and board and board.smarts_by_names[p[1]] if not (smart) then return false end return smart.faction_war_in_progress == true end ------------------------------------------------------------------------------------- -- Special for Radar ------------------------------------------------------------------------------------- function rad_pass_time(actor, npc) return true -- return level.get_time_hours() >= 10 and level.get_time_hours() < 11 end function heli_dist_to_max_bounding_le(actor,npc,p) local heli = npc and npc:get_helicopter() if not (heli) then return false end local d = p[1] and tonumber(p[1]) local dist = d and heli_alife.distance_2d_sqr(npc:position(),level.get_bounding_volume().max) return dist and dist <= d or false end function heavy_pockets_functor(actor,npc,p) return has_alife_info("achieved_heavy_pockets") end ------------------------------------------------------------------------------------ -- Special functions for OLD ARENA ------------------------------------------------------------------------------------ function bar_arena_actor_inside(actor,npc) local t = db.zone_by_name["bar_arena_waiter"] if t and db.actor then if t:inside(db.actor:position()) then return true end end return false end function bar_arena_actor_fight(actor,npc) local t = db.zone_by_name["bar_arena_sr"] local tt = db.zone_by_name["bar_arena_waiter"] if t and tt and db.actor then if t:inside(db.actor:position()) and not tt:inside(db.actor:position()) then return true end end return false end function bar_arena_actor_outside(actor,npc) local t = db.zone_by_name["bar_arena_waiter_out"] if t and db.actor then if t:inside(db.actor:position()) then return true end end return false end function actor_dead(actor, npc) if db.actor and not db.actor:alive() then return true end return false end ------------------------------------------------------------------------------------ -- Special functions for NEW ARENA ------------------------------------------------------------------------------------ function bar_actor_rank_stalker (actor,npc) if db.actor and db.actor:character_rank() > 1499 then return true end return false end function bar_actor_rank_veteran (actor,npc) if db.actor and db.actor:character_rank() > 2999 then return true end return false end function bar_arena_fight_3_end (actor,npc) return has_alife_info("bar_arena_fight_3_stalker_1_die") and has_alife_info("bar_arena_fight_3_stalker_2_die") end function bar_arena_fight_4_end (actor,npc) return has_alife_info("bar_arena_fight_4_stalker_1_die") and has_alife_info("bar_arena_fight_4_stalker_2_die") and has_alife_info("bar_arena_fight_4_stalker_3_die") end function bar_arena_fight_5_end (actor,npc) return has_alife_info("bar_arena_fight_5_stalker_1_die") and has_alife_info("bar_arena_fight_5_stalker_2_die") end function bar_arena_fight_6_end (actor,npc) return has_alife_info("bar_arena_fight_6_stalker_1_die") and has_alife_info("bar_arena_fight_6_stalker_2_die") and has_alife_info("bar_arena_fight_6_stalker_3_die") and has_alife_info("bar_arena_fight_6_stalker_4_die") and has_alife_info("bar_arena_fight_6_stalker_5_die") and has_alife_info("bar_arena_fight_6_stalker_6_die") end function bar_arena_fight_8_end (actor,npc) return has_alife_info("bar_arena_fight_8_stalker_1_die") and has_alife_info("bar_arena_fight_8_stalker_2_die") and has_alife_info("bar_arena_fight_8_stalker_3_die") and has_alife_info("bar_arena_fight_8_stalker_4_die") end function heli_exist_on_level(actor,npc) if (is_empty(db.heli)) then return false end return true end function is_actor_surge_immuned(actor,npc,p) return utils.load_var(db.actor,"surge_immuned",false) == true end function get_start_time_elapsed_ge(actor,npc,p) return p[1] and tonumber(game.get_game_time():diffSec(level.get_start_time())) >= tonumber(p[1]) end function base_defense_is_actor_on_level(actor,npc,p) local name = utils.load_var(db.actor,"base_defense_level") if (name) then return name == level.name() end return true end