e4s-sdk/gamedata/scripts/xr_conditions.script
2026-06-17 23:06:51 +03:00

1731 lines
47 KiB
Text

-- Êàæäàÿ ôóíêöèÿ â ýòîì ôàéëå èñïîëüçóåòñÿ êàê óñëîâèå 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 <see_npc>: [%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