1731 lines
47 KiB
Text
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
|