-- ----------------------------------------------------------------------------------------------------
-- Общие функции
-- ----------------------------------------------------------------------------------------------------

function disable_ui_elements(actor, npc, p)
    local i, v = 0, 0
    for i, v in pairs(p) do
        if v == "all" then
            db.actor:hide_weapon()
            level.disable_input()
            level.hide_indicators()
            break
        elseif v == "weapon" then
            db.actor:hide_weapon()
        elseif v == "input" then
            level.disable_input()
        elseif v == "hud" then
            level.hide_indicators()
        end
    end
    --printf("xr_effects <disable_ui_elements>")
end

function enable_ui_elements(actor, npc, p)
    local i, v = 0, 0
    for i, v in pairs(p) do
        if v == "all" then
			if ui_mm_opt_creator.get_bool_console("hud_indicators_visible",true) then
				level.show_indicators()
			end
            level.enable_input()
            db.actor:restore_weapon()
            break
        elseif v == "hud" then
			if ui_mm_opt_creator.get_bool_console("hud_indicators_visible",true) then
	            level.show_indicators()
			end
        elseif v == "input" then
            level.enable_input()
        elseif v == "weapon" then
            db.actor:restore_weapon()
        end
    end
end

function disable_ui(actor, npc)
    db.actor:hide_weapon()
    level.disable_input()
    level.hide_indicators()
    --printf("xr_effects <disable_ui>")
end

function enable_ui(actor, npc)
    level.show_indicators()
    level.enable_input()
    db.actor:restore_weapon()
    --printf("xr_effects <enable_ui>")
end

function run_cam_effector(actor, npc, p)
    if p[1] then
        local loop, num = false, (1000 + math.random(100))
        
        if p[2] and type(p[2]) == "number" and p[2] > 0 then
            num = p[2]
        end

        if p[3] and p[3] == "true" then
            loop = true
        end
        
        --level.add_pp_effector(p[1] .. ".ppe", num, loop)
      level.add_cam_effector("camera_effects\\" .. p[1] .. ".anm", num, loop, "")                   
    end
end

function stop_cam_effector(actor, npc, p)
    if p[1] and type(p[1]) == "number" and p[1] > 0 then
        level.remove_cam_effector(p[1])
    end
end

function run_postprocess(actor, npc, p)
    if p[1] then
        local loop, num = false, (2000 + math.random(100))
        
        if p[2] and type(p[2]) == "number" and p[2] > 0 then
            num = p[2]
        end

        if p[3] and p[3] == "true" then
            loop = true
        end
        
        level.add_pp_effector(p[1] .. ".ppe", num, loop)
    end
end

function stop_postprocess(actor, npc, p)
    if p[1] and type(p[1]) == "number" and p[1] > 0 then
        level.remove_pp_effector(p[1])
    end
end

function run_tutorial(actor, npc, p)
  game.start_tutorial(p[1])
end
function run_tutorial_if_newbie(actor, npc, p)
  if has_info("esc_trader_newbie") then
    game.start_tutorial(p[1])
  end
end

function teleport_actor(actor, npc, p)
  local point = patrol(p[1])
  local look = patrol(p[2])
  
  give_info("teleport_started")
  db.actor:set_actor_position(point:point(0))
  local dir = look:point(0):sub(point:point(0))
  db.actor:set_actor_direction(-dir:getH()) 
  give_info("teleport_finished")
end

-----------------------------------------------------------------------------
local drop_point, drop_object = 0, 0
local function drop_object_item(item)
    drop_object:drop_item_and_teleport(item, drop_point)
end

function drop_actor_inventory(actor, npc, p)
    if p[1] then
        drop_point  = patrol(p[1]):point(0)
        drop_object = actor
        actor:inventory_for_each(drop_object_item)
    end
end

-- FIXME: drop_npc_inventory doesn't work
function drop_npc_inventory(actor, npc, p)
    if p[1] then
        drop_point  = patrol(p[1]):point(0)
        drop_object = npc
        npc:inventory_for_each(drop_object_item)
    end
end

function drop_npc_item(actor, npc, p)
    if p[1] then
        local item = npc:object(p[1])
        if item then
        npc:drop_item(item)
    end
    end
end

function drop_npc_items(actor, npc, p)
    local item = 0
  for i, v in pairs(p) do
        item = npc:object(v)
        if item then
        npc:drop_item(item)
        end
    end
end

function give_item(actor, npc, p)
    if p[1] then
        create(p[1], npc:position(), npc:level_vertex_id(), npc:game_vertex_id(), npc:id())
    end
end

function give_items(actor, npc, p)
    local pos, lv_id, gv_id, npc_id = npc:position(), npc:level_vertex_id(), npc:game_vertex_id(), npc:id()
  for i, v in pairs(p) do
        create(v, pos, lv_id, gv_id, npc_id)
    end
end

-- актёр "отдаёт" указанный предмет
function actor_remove_item(actor, npc, p)
	if p[1] and actor:object(p[1]) then
	release(server_object(actor:object(p[1]):id()))
	end
end


function respawner_spawn(actor, npc, p)
    if p[1] then
    se_respawn.spawn(p[1])
    end
end

-- спаун по spawn_story_id - следить чтобы не было дублей, иначе будет вылет
function spawn_story_id(actor, npc, p)
    if p[1] then
	create(ai:spawn_id(p[1]))
    end
end

function play_particle_on_path(actor, npc, p)
    local name = p[1]
    local path = p[2]
    local point_prob = p[3]
    if name == nil or path == nil then
        return
    end

    if point_prob == nil then
        point_prob = 100
    end
    
    local path = patrol(path)
    local count = path:count()
    for a = 0,count-1,1 do   
        local particle = particles_object(name)
        if math.random(100) <= point_prob then
            particle:play_at_pos(path:point(a))
        end
    end   
end


-----------------------------------------------------------------------------
function monster_berserk(actor, npc)
    npc:berserk()
end

function activate_bolt(actor, npc)
  db.actor:activate_slot(5)
end

--[[
send_tip(news_id:sender:sender_id)
    1. news_id
    2. sender*
    3. sender_id*
    * - not necessary
--]]
function send_tip(actor, npc, p)
    sms(p[1], nil, p[2], nil, p[3])
end



--[[
Дать сталкеру небольшой пинок. Например чтоб скинуть его с возвышения.
параметры: actor, npc, p[direction,bone,power,impulse,reverse=false]
    1. direction - если строка, то считается, что это имя пути и в сторону
        первой точки производится толчек. Если же это число, то оно
        рассматривается как story_id персонажа от которого должен поступить хит.
    2. bone - строка. Имя кости, по которой наносится удар.
    3. power - сила удара
    4. impulse - импульс
    5. reverse (true/false) - изменение направления удара. по умолчанию false
--]]
function hit_npc(actor, npc, p)
  local h = hit()
  local rev = p[5] and p[5] == 'true'
  h.draftsman = npc
  h.type = hit.wound
  if type(p[1]) == 'number' then
    local hitter = level_story_object(p[1])
    if not hitter then return end
      if rev then
          h.draftsman = hitter
        h.direction = hitter:position():sub(npc:position())
      else
        h.direction = npc:position():sub(hitter:position())
      end
  else
      if rev then
          h.draftsman = nil
        h.direction = npc:position():sub(patrol(p[1]):point(0))
      else
        h.direction = patrol(p[1]):point(0):sub(npc:position())
      end
  end
  h:bone(p[2])
  h.power = p[3]
  h.impulse = p[4]
  --printf("HIT EFFECT: (%s, %s,%d,%d) health(%s)", npc:name(), p[2], h.power, h.impulse, npc.health)
  npc:hit(h)
end

--[[
Дать обьекту, заданному story_id, хит.
параметры: actor, npc, p[sid,bone,power,impulse,hit_src=npc:position()]
    1. sid - story_id обьекта, по которому наносится хит.
    2. bone - строка. Имя кости, по которой наносится удар.
    3. power - сила удара
    4. impulse - импульс
    5. hit_src - если число, то рассматривается как story_id обьекта, со стороны
        которого наносится хит (он же является и инициатором хита), иначе это
        точка (waypoint), из которой по объекту наносится хит.
        Если не задано, то берется позиция обьекта, из которого была вызвана
        данная функция.
--]]
function hit_obj(actor, npc, p)
  local h = hit()
  local obj = level_story_object(p[1])
  local sid = nil

  if not obj then
--    abort("HIT_OBJ [%s]. Target object does not exist", npc:name())
    return
  end

  h:bone(p[2])
  h.power = p[3]
  h.impulse = p[4]

  if p[5] then
      sid = tonumber(p[5])
      if sid then
          sid = level_story_object(sid)
          if sid then
              h.direction = vector():sub(sid:position(), obj:position())
          end
      end
      if not sid then
          h.direction = vector():sub(patrol(p[5]):point(0), obj:position())
      end
  else
      h.direction = vector():sub(npc:position(), obj:position())
  end

  h.draftsman = sid or npc
  h.type = hit.wound
  obj:hit(h)
end

--[[
Дать сталкеру небольшой пинок после смерти. Аналогично предыдущему, только направление хита теперь
вычисляется через убийцу. Поэтому параметра direction нет.
параметры: actor, npc, p[bone,power,impulse]
FIXME: killer:position() isn't working
--]]
function hit_by_killer(actor, npc, p)
  if not npc then return end
  local t = db.storage[npc:id()].death
  if t == nil or t.killer == -1 then return end
  local killer = db.storage[t.killer]
  if killer == nil then return end
  local p1, p2
  p1 = npc:position()
  p2 = killer:position()
  local h = hit()
  h.draftsman = npc
  h.type = hit.wound
  h.direction = utils.vector_copy_by_val(p1):sub(p2)
  h.bone = p[1]
  h.power = p[2]
  h.impulse = p[3]
  npc:hit(h)
end

function set_friends(actor, npc, p)
    local npc1
  for i, v in pairs(p) do
    npc1 = level_story_object(v)
    if npc1 and npc1:alive() then
      --printf("_bp: %d:set_friends(%d)", npc:id(), npc1:id())
      npc:set_relation(game_object.friend, npc1)
      npc1:set_relation(game_object.friend, npc)
    end
  end
end

function set_enemies(actor, npc, p)
    local npc1
  for i, v in pairs(p) do
    --printf("_bp: set_enemies(%d)", v)
    npc1 = level_story_object(v)
    if npc1 and npc1:alive() then
      npc:set_relation(game_object.enemy, npc1)
      npc1:set_relation(game_object.enemy, npc)
    end
  end
end

-- играть звук в голове актёра
function play_snd(actor, npc, p)
  if p[1] then
    local snd_obj = voice(p[1])
    --snd_obj:play(actor, p[2] or 0, sound_object.s2d)
    snd_obj:play_no_feedback(actor, sound_object.s2d, p[2] or 0, vector(), 1.0)
  end
end

-- играть звук от указанного объекта
function play_snd_from_obj(actor, npc, p)
  if p[1] and p[2] then
    local snd_obj = voice(p[2])
    local obj     = level_story_object(p[1])
        if obj ~= nil then
           printf("can't find object with story id %s", tostring(p[1]))
        
--    snd_obj:play_at_pos(obj, obj:position(), sound_object.s3d)
    snd_obj:play_no_feedback(obj, sound_object.s3d, 0, obj:position(), 1.0)
    end
  end
end

-- играть звук от указанного объекта
function play_snd_now(actor, npc, p)
  xr_sound.set_sound_play(npc, p[1])
end


-- прибавить к указанному счётчику актёра 1
function inc_counter(actor, npc, p)
  if p[1] then
    printf( "inc_counter '%s'", p[1] )
    set_value(p[1], get_value(p[1], 0) + 1)
  end
end

function dec_counter(actor, npc, p)
  if p[1] then
    printf( "dec_counter '%s'", p[1] )
    set_value(p[1], get_value(p[1], 0) - 1)
  end
end


-- переключает камеру на монстра или на актёра
function alien_control( actor, npc, p )
  printf( "alien_control(%s)", p[1] )
  npc:set_alien_control( p[1] == "true" )
end

-- слелать актёра врагом персонажам, которые в онлайне под указанным смартом
function set_gulag_enemy_actor( actor, npc, p )
  if p[1] then
    xr_gulag.setGulagEnemy(p[1], actor)
  end
end

-- принудительное обновление смарта. Использовать только в КРАЙНИХ случаях!!!
-- каждое использование согласовывать со мной. Чугай.
function smart_terrain_force_update(actor, npc, p)
  printf( "xr_effects.smart_terrain_force_update called" )

  if p[1] then
    local gulag = xr_gulag.get_gulag(p[1])

    if gulag then
      gulag.smrttrn:update()
    end
  end
end

------------------------------------------------------------------------------------------------------------------------

-- постпроцесс и влияние удара в морду
function actor_punch(npc)
  if db.actor:position():distance_to_sqr(npc:position()) > 4 then
    return
  end

  local active_slot = db.actor:active_slot()
  if active_slot ~= 1 and
     active_slot ~= 2
  then
    return 
  end

  local active_item = db.actor:active_item()
  if active_item then
    db.actor:drop_item(active_item)
  end
  
  set_inactivate_input_time(30)
  say([[affects\hit_fist]])

  level.add_cam_effector("camera_effects\\fusker.anm", 999, false, "")    
end

-- Принудительное усыпание игрока на радаре.
function force_actor_sleep(npc)
  db.actor:actor_sleep(24, 0)
end


-- забывание обиды
function clearAbuse(npc)
  printf("CLEAR_ABUSE")
  xr_abuse.clear_abuse(npc)
end


---Выключение динамической лампочки (hanging_lamp)
function turn_off(actor, npc, p)
  local obj = level_story_object(p[1])

  if not obj then
    abort("TURN_OFF [%s]. Target object does not exist", npc:name())
    return
  end
  obj:get_hanging_lamp():turn_off()
end
function turn_off_object(actor, npc)
  npc:get_hanging_lamp():turn_off()
end

---Включение динамической лампочки (hanging_lamp)
function turn_on(actor, npc, p)
  local obj = level_story_object(p[1])

  if not obj then
    abort("TURN_ON [%s]. Target object does not exist", npc:name())
    return
  end
  obj:get_hanging_lamp():turn_on()
end
function turn_on_object(actor, npc)
  npc:get_hanging_lamp():turn_on()
end

------------------------------------------------------------------------------------------------

-- Кто-то из участников сценки вступил в бой - теперь нужно пообижать всех на всех
function gar_dm_bandits_fight(actor, npc)
  local novice = level_story_object(104)
  if not novice or not novice:alive() then
    return
  end

  local ignore_actor = distance_between(actor, novice) > 25

  local bandit1 = level_story_object(101)
  if bandit1 then
    novice:set_relation(game_object.enemy, bandit1)
    if not ignore_actor then
      bandit1:set_relation(game_object.enemy, actor)
    end
    bandit1:set_relation(game_object.enemy, novice)
  end

  local bandit2 = level_story_object(102)
  if bandit2 then
    novice:set_relation(game_object.enemy, bandit2)
    if not ignore_actor then
      bandit2:set_relation(game_object.enemy, actor)
    end
    bandit2:set_relation(game_object.enemy, novice)
  end

  local bandit3 = level_story_object(103)
  if bandit3 then
    novice:set_relation(game_object.enemy, bandit3)
    if not ignore_actor then
      bandit3:set_relation(game_object.enemy, actor)
    end
    bandit3:set_relation(game_object.enemy, novice)
  end
end

function gar_dm_bandit_demand(actor, npc)
  printf("_bp: gar_dm_bandit_demand: actor=%s", actor:name())

  if has_info("gar_dm_bandit1_demand") or
     has_info("gar_dm_bandit2_demand") or
     has_info("gar_dm_bandit3_demand") then
    return
  end
  local r = math.random(3)
  if r == 1 then
    give_info("gar_dm_bandit1_demand")
  elseif r == 2 then
    give_info("gar_dm_bandit2_demand")
  else
    give_info("gar_dm_bandit3_demand")
  end
end

function gar_send_dymon_alarm(actor, npc)
  if has_info("gar_start_graveyard") then
    sms("tips_gar_hellcar_alarm", 2, "stalker", 10000)
  end
end

function gar_direction_fire(actor, npc)
  if has_info("gar_hellcar_help") and not has_info("gar_counter_fire") and not has_info("gar_open_fire") then
    sms("gar_direction_fire", 0, "stalker", 0)
  end
end

function gar_hellcar_victory(actor, npc)
  if not has_info("gar_hellcar_tips_end") and has_info("gar_hellcar_help") and not has_info("gar_hellcar_thanks") then
    sms("gar_hellcar_victory", 0, "stalker", 0)
    give_info("gar_hellcar_tips_end")
  end
end

function gar_seryi_victory(actor, npc)
    sms("gar_hellcar_victory", 0, "stalker", 0)
end

function gar_boars_counter(actor, npc)
	local c = get_value("gar_boars_counter", 0)
	if c < 1 then
		sms("gar_actor_looser", 0, "barduty", 0)
		disable_info("gar_free_pass")
		give_info("gar_actor_looser")
	elseif c>5 then
		sms("gar_actor_winner", 0, "barduty", 0)
		give_info("gar_kill_boars_request")
		give_info("gar_free_pass")
	else
		sms("gar_actor_normal", 0, "barduty", 0)
		give_info("gar_kill_boars_request")
	end
end

--' Escape

function play_snd_from_radio(actor, npc)
  local snd_obj = voice([[characters_voice\scenario\escape\wolf_to_rangers_1]])
  local obj   = npc:object("hand_radio")
  if not obj then
	abort("! ERROR esc_wolf lost owned radio!!!")
	return 
  end
  snd_obj:play_no_feedback(obj, sound_object.s3d, 0, obj:position(), 1.0) 
end

function esc_direction_fire(actor, npc)
  if not has_info("esc_fanat_die") then
    sms("esc_direction_fire", 7, "stalker", 0)
  end
end

function esc_fanat_victory(actor, npc)
  if has_info("escape_lager_killers_die") and not has_info("esc_fanat_die") then
    sms("esc_fanat_victory", 0, "stalker", 10000)
  end
end

function esc_return_dv(actor, npc)
    sms("esc_return_dv", 0, "trader", 10)
end



-- function esc_lager_forgive_actor(actor, npc)
--  xr_gulag.setGulagNeutral("esc_lager", db.actor)
-- end

-- function esc_lager_promise_actor(actor, npc)
--  local gulag = xr_gulag.get_gulag_by_name ("esc_lager")
--    if (gulag) then
--       gulag:set_relation (game_object.neutral, actor)
--    end  
-- end

-- function esc_lager_rage_actor(actor, npc)
--  local gulag = xr_gulag.get_gulag_by_name ("esc_lager")
--    if (gulag) then
--       gulag:set_relation (game_object.enemy, actor)
--    end  
-- end

--' garbage

function gar_mapspot_blockpost (actor, npc)
  level_tasks.add_location(115, "green_location", "gar_dolg_blokpost_leader_name")
end


  
function actor_friend(actor, npc)
  printf("_bp: xr_effects: actor_friend(): npc='%s': time=%d", npc:name(), time_global())
  npc:set_relation(game_object.friend, actor)
end

function actor_neutral(actor, npc)
  npc:set_relation(game_object.neutral, actor)
end

function actor_enemy(actor, npc)
	npc:set_relation(game_object.enemy, actor)
end

function give_all_quests(actor, npc)
  --bar_dialogs.quests()
end

function give_rostok_quests(actor, npc)
  bar_dialogs.rostok_quests()
end


-- Вызов этой функции отключит обработчик [combat] боя для персонажа.
-- Используется в случаях, когда все необходимые действия, такие как переключение на другую секцию,
-- уже выполнены, и повторно выполнять их во время боя нельзя (а условия секции [combat] проверяются на каждом
-- апдейте, когда персонаж в бою, если, конечно, не отключены вызовом этой функции).
function disable_combat_handler(actor, npc)
  if db.storage[npc:id()].combat then
    db.storage[npc:id()].combat.enabled = false
  end
  
  if db.storage[npc:id()].mob_combat then
    db.storage[npc:id()].mob_combat.enabled = false
  end
end

-- Вызов этой функции отключит обработчик [combat_ignore] перехвата боя для персонажа.
function disable_combat_ignore_handler(actor, npc)
  if db.storage[npc:id()].combat_ignore then
    db.storage[npc:id()].combat_ignore.enabled = false
  end
end

function log_bp1(actor, npc)
  printf("xr_effects: log_bp1 (actor='%s', npc='%s'", actor:name(), npc:name())
end

function psi_hit_npc(actor, npc,p)
end


function mil_paul_frost_dead (actor, npc)     
    local gulag = xr_gulag.get_gulag_by_name ("mil_freedom")
    if (gulag) then
       gulag:set_relation (game_object.neutral, actor)
    end   
end

function set_freedom_actor_enemy (actor, npc)
    local luk = level_story_object (707)
    this.actor_enemy (actor, luk)
end

function military_dolg_dead (actor, npc)
    -- если нет актера, то вылетаем с грохотом и треском
    if actor == nil then return end

--[[
	
    -- если данные не существуют, то создадим
    local id = actor:id ()
    if db.storage[id] == nil then
       db.storage[id] = {}
    end    
    
    if db.storage[id].mil_dolg_killed == nil then
       db.storage[id].mil_dolg_killed = 0
       db.storage[id].mil_dolg_killed_by_actor = false
    end    
    -- проапдейтим количество мертвых долговцев
    db.storage[id].mil_dolg_killed = db.storage[id].mil_dolg_killed + 1

    --printf ("!!! DOLG STALKER IS DEAD, KILLED %d STALKERS !!!", db.storage[db.actor:id ()].mil_dolg["killed"])

    -- взведем флажок, что мужика замочили мы (нужно для Свободы) 
    local st = db.storage[npc:id ()]
    if st.death.killer == -1 then return end
    if id == st.death.killer then 
       db.storage[id].mil_dolg_killed_by_actor = true
    end
    
    -- если все умерли и была задача мочить снайпера, но сообщать не кому, то
    -- ставим задачу, как не выполненую
    if db.storage[id].mil_dolg_killed == 8 then

]]	
    -- проапдейтим количество мертвых долговцев
    local mil_dolg_killed = get_value("mil_dolg_killed", 0) + 1
    set_value("mil_dolg_killed", mil_dolg_killed)
    if mil_dolg_killed == 8 or xr_gulag.getGulagPopulation("mil_dolg") <= 1 then
       give_info ("mil_dolg_dead")
    end   
    
end

function mil_patrol_death_check (actor, npc)
    if has_info("mil_patrol_man1_dead") and has_info("mil_patrol_man2_dead") and has_info("mil_patrol_man3_dead") then
       give_info ("mil_patrol_dead") 
    end
end

function mil_cook_dead (actor, npc)
    --level_tasks.set_task_state (task.fail, "mil_freedom_rg6_task", 2)
end

function search_gulag_job(actor, npc)
  xr_gulag.resetJob(npc)
end


--------------------------------------------------------- 
-- BAR-ROSTOK
--------------------------------------------------------- 

function bar_freedom_spam_1(actor, npc)
  sms("bar_freedom_spam_1", nil, "killer", nil, 509)
end
function bar_freedom_spam_2(actor, npc)
  sms("bar_freedom_spam_2", nil, "killer", nil, 509)
end
function bar_freedom_spam_3(actor, npc)
  sms("bar_freedom_spam_3", nil, "killer", nil, 509)
end
function bar_freedom_spam_4(actor, npc)
  sms("bar_freedom_spam_4", nil, "killer", nil, 509)
end
function bar_ecolog_spam_1(actor, npc)
  sms("bar_ecolog_spam_1", nil, "ecolog", nil, 503)
end
function bar_ecolog_spam_2(actor, npc)
  sms("bar_ecolog_spam_2", nil, "ecolog", nil, 503)
end
function bar_ecolog_spam_3(actor, npc)
  sms("bar_ecolog_spam_3", nil, "ecolog", nil, 503)
end
function bar_ecolog_spam_4(actor, npc)
  sms("bar_ecolog_spam_4", nil, "ecolog", nil, 503)
end
function bar_ecolog_spam_5(actor, npc)
  if not has_info("bar_heli_scene_volkodav_die") and not has_info("bar_ecolog_saw_chase") then
    sms("bar_freedom_chase", nil, "ecolog", nil, 503)
    give_info("bar_ecolog_saw_chase")
  end
end
function bar_ecolog_hit(actor, npc)
  sms("bar_ecolog_hit", nil, "ecolog", nil, 503)
end
function bar_freedom_spam_5(actor, npc)
  if not has_info("bar_heli_scene_volkodav_die") then
    sms("bar_ecolog_escape", nil, "killer", nil, 509)
  end
end
function bar_freedom_angry_actor(actor,npc)
  if has_info("bar_ecolog_crush_actor_enemy")
  then
    npc:set_relation(game_object.enemy, db.actor)
  end
end
function bar_freedom_defence_ecolog(actor,npc)
  sms("bar_ecolog_attack", nil, "ecolog", nil, 503)
end   
function bar_freedom_angry_actor_notify(actor,npc)
  if has_info("bar_ecolog_crush_actor_enemy") then
    sms("bar_freedom_attack_spy", 4, "killer", nil, 509)
  end
end
function bar_crush_heli_start(actor,npc)
  sms("bar_ecolog_crush_start_heli", nil, "ecolog", nil, 503)
end
function rostok_kruglov_tip_1(actor,npc)
  sms("rostok_kruglov_spam_1", nil, "ecolog", nil, 503)
end
function rostok_kruglov_tip_2(actor,npc)
  sms("rostok_kruglov_spam_2", nil, "ecolog", nil, 503)
  level_tasks.add_location(597, "volkodav_location", "rostok_banda_volkodava")
end
function rostok_kruglov_attract_1(actor,npc)
  xr_sound.set_sound_play(npc, "kruglov_stop_enemy_1")
  local tips_sound = news_manager.send_tip_nosound(db.actor, "bar_freedom_chase", 0, "ecolog")
  if tips_sound ~= nil then
    --' Играем звук забитый
    tips_sound:play(db.actor, 0, sound_object.s2d)
  end
end
function rostok_kruglov_attract_2(actor,npc)
  xr_sound.set_sound_play(npc, "kruglov_stop_enemy_2",3)
  local tips_sound = news_manager.send_tip_nosound(db.actor, "rostok_kruglov_follow_2",3000, "ecolog")
  if tips_sound ~= nil then
    --' Играем звук забитый
    tips_sound:play(db.actor, 0, sound_object.s2d)
  end
end
function rostok_kruglov_ambush(actor,npc)
  xr_sound.set_sound_play(npc, "rostok_kruglov_help_5")
  local tips_sound = news_manager.send_tip_nosound(db.actor, "rostok_kruglov_follow_3", 0, "ecolog")
  if tips_sound ~= nil then
    --' Играем звук забитый
    tips_sound:play(db.actor, 0, sound_object.s2d)
  end
end
function bar_crush_heli_down(actor,npc)
  sms("bar_ecolog_crush_heli_down", 1, "killer", nil, 509)
end
function bar_ecolog_crush_attract_actor(actor,npc)
  if not has_info("bar_heli_scene_professor_die") then
    sms("bar_ecolog_crush_attract_actor", nil, "ecolog")
  end
end
function bar_freedom_attack_attract_actor(actor,npc)
    sms("bar_freedom_attack_attract_actor", nil, "killer")
  end
function bar_freedom_attack_start(actor,npc)
    if not has_info("bar_freedom_defence_ecolog") then
      sms("bar_freedom_attack", nil, "killer", nil, 509)
            give_info("bar_freedom_defence_ecolog")
    end
  end
function bar_arena_hit(actor, npc)
  local h = hit()
  h.power = 0.01
  h.direction = npc:direction()
  h.draftsman = db.actor 
  h.impulse = 1
  h.type = hit.wound
  npc:hit(h)
end
function esc_hit_from_fox(actor, npc)
  local fox = level_story_object (005)
  if fox == nil then
    return
  end
  local h = hit()
  h.power = 0.01
  h.direction = npc:direction()
  h.draftsman = fox 
  h.impulse = 1
  h.type = hit.wound
  npc:hit(h)
end

function bar_territory_logic(actor, npc)
  local level = level.name()
  if  level == "l05_bar" then
    if dialogs.actor_in_dolg(actor,npc) then
      if has_info("bar_dolg_territory_kill") then
        sms("bar_territory_dolg_kill", nil, "dolg", nil, 507)
        xr_gulag.setGulagEnemy("bar_dolg_general", db.actor)
        xr_gulag.setGulagEnemy("bar_dolg_veterans", db.actor)
        xr_gulag.setGulagEnemy("bar_dolg_bunker", db.actor)
		xr_gulag.setGulagEnemy("bar_zastava", db.actor)
		xr_gulag.setGulagEnemy("bar_zastava_2", db.actor)
        xr_gulag.setGulagEnemy("bar_visitors", db.actor)
        return
      end
      if has_info("bar_dolg_territory_3_hit") then
        sms("bar_territory_dolg_3_hit", nil, "dolg", nil, 507)
        xr_gulag.setGulagEnemy("bar_dolg_general", db.actor)
        xr_gulag.setGulagEnemy("bar_dolg_veterans", db.actor)
        xr_gulag.setGulagEnemy("bar_dolg_bunker", db.actor)
		xr_gulag.setGulagEnemy("bar_zastava", db.actor)
		xr_gulag.setGulagEnemy("bar_zastava_2", db.actor)
        return
      end
      if has_info("bar_dolg_territory_2_hit") then
        sms("bar_territory_dolg_2_hit", nil, "dolg", nil, 507)
        return
      end
      if has_info("bar_dolg_territory_1_hit") then
        sms("bar_territory_dolg_1_hit", nil, "dolg", nil, 507)
        return
      end
    else
      if has_info("bar_dolg_territory_kill") then
        give_info("bar_territory_nodolg_kill")
        sms("bar_territory_nodolg_kill", nil, "dolg", nil, 507)
        xr_gulag.setGulagEnemy("bar_dolg_general", db.actor)
        xr_gulag.setGulagEnemy("bar_dolg_veterans", db.actor)
        xr_gulag.setGulagEnemy("bar_dolg_bunker", db.actor)
		xr_gulag.setGulagEnemy("bar_zastava", db.actor)
		xr_gulag.setGulagEnemy("bar_zastava_2", db.actor)
        xr_gulag.setGulagEnemy("bar_visitors", db.actor)
        return
      end
      if has_info("bar_dolg_territory_2_hit") then
        give_info("bar_territory_nodolg_2_hit")
        sms("bar_territory_nodolg_2_hit", nil, "dolg", nil, 507)
        xr_gulag.setGulagEnemy("bar_dolg_general", db.actor)
        xr_gulag.setGulagEnemy("bar_dolg_veterans", db.actor)
        xr_gulag.setGulagEnemy("bar_dolg_bunker", db.actor)
		xr_gulag.setGulagEnemy("bar_zastava", db.actor)
		xr_gulag.setGulagEnemy("bar_zastava_2", db.actor)
        xr_gulag.setGulagEnemy("bar_visitors", db.actor)
        return
      end
      if has_info("bar_dolg_territory_1_hit") then
        give_info("bar_territory_nodolg_1_hit")
        sms("bar_territory_nodolg_1_hit", nil, "dolg", nil, 507)
        return
      end 
    end
  end
  return
end

function bar_psih_come(actor, npc)
  sms("bar_psih_come", nil, "barman")
end

function bar_actor_is_enemy(actor, npc)
      xr_gulag.setGulagEnemy("bar_dolg_general", db.actor)
      xr_gulag.setGulagEnemy("bar_dolg_veterans", db.actor)
      xr_gulag.setGulagEnemy("bar_dolg_bunker", db.actor)
      xr_gulag.setGulagEnemy("bar_visitors", db.actor)
end

function bar_actor_enemy_set (actor, npc)          
    local dog = level_story_object (509)
    if dog ~= nil then
       dog:set_relation (game_object.enemy, db.actor) 
    end   
end

function bar_arena_weapon_spawn ()
  
  local obj = level_story_object (606)
  local spawn_items = {}
  
  for i = 1,100 do
    table.insert( spawn_items, "bandit_outfit")
  end
  
  local k,v = 0,0
  
  for k,v in pairs(spawn_items) do
    create(v, 
            obj:position(),
            obj:level_vertex_id(),  
            obj:game_vertex_id())
  end 
end

local function transfer_object_item(item)
    out_object:transfer_item(item, in_object)
end
function bar_arena_teleport ( actor, npc)
	db.actor:hide_weapon()
	inv_box_1 = level_story_object (573)
	out_object = actor
    in_object  = inv_box_1
    actor:inventory_for_each(transfer_object_item) 
	local spawn_items = {} 
	local spawn_7_state=false
	if  has_info("bar_arena_fight_1") then 
		table.insert(spawn_items, "wpn_pm")
		table.insert(spawn_items, "ammo_9x18_pmm")
		table.insert(spawn_items, "ammo_9x18_pmm")
	--    table.insert(spawn_items, "wpn_knife")
	elseif  has_info("bar_arena_fight_2") then
		table.insert(spawn_items, "wpn_mp5")
		table.insert(spawn_items, "ammo_9x19_pbp")
	--    table.insert(spawn_items, "wpn_knife")    
	elseif  has_info("bar_arena_fight_3") then
		table.insert(spawn_items, "wpn_bm16")
		table.insert(spawn_items, "ammo_12x70_buck")
		table.insert(spawn_items, "ammo_12x70_buck")
	--    table.insert(spawn_items, "wpn_knife")
	elseif  has_info("bar_arena_fight_4") then      
		table.insert(spawn_items, "wpn_ak74")
		table.insert(spawn_items, "ammo_5.45x39_ap")
		table.insert(spawn_items, "ammo_5.45x39_ap")
	--    table.insert(spawn_items, "wpn_knife")
		table.insert(spawn_items, "bandage")
		table.insert(spawn_items, "bandage")
	elseif  has_info("bar_arena_fight_5") then  
		table.insert(spawn_items, "wpn_abakan")
		table.insert(spawn_items, "ammo_5.45x39_ap")
		table.insert(spawn_items, "ammo_5.45x39_ap")
		table.insert(spawn_items, "ammo_5.45x39_ap")
	--    table.insert(spawn_items, "wpn_knife")
		table.insert(spawn_items, "bandage")
		table.insert(spawn_items, "medkit")
		table.insert(spawn_items, "svoboda_light_outfit")
	elseif  has_info("bar_arena_fight_6") then
		table.insert(spawn_items, "wpn_groza")
		table.insert(spawn_items, "ammo_9x39_ap")
		table.insert(spawn_items, "ammo_9x39_ap")
		table.insert(spawn_items, "ammo_9x39_ap")
	--    table.insert(spawn_items, "wpn_knife")
		table.insert(spawn_items, "grenade_f1")
		table.insert(spawn_items, "specops_outfit")
	elseif  has_info("bar_arena_fight_7") then
		table.insert(spawn_items, "wpn_knife")
		table.insert(spawn_items, "bandage")
		table.insert(spawn_items, "grenade_f1")
		table.insert(spawn_items, "grenade_f1")
		--table.insert(spawn_items, "grenade_f1")
		--table.insert(spawn_items, "grenade_f1")
		spawn_7_state=true
	elseif  has_info("bar_arena_fight_8") then
		table.insert(spawn_items, "wpn_g36")
		table.insert(spawn_items, "ammo_5.56x45_ap")
		table.insert(spawn_items, "ammo_5.56x45_ap")
		table.insert(spawn_items, "ammo_5.56x45_ap")
		table.insert(spawn_items, "ammo_5.56x45_ap")
	--    table.insert(spawn_items, "wpn_knife")
	end
    local k,v = 0,0
	local obj
  	for k,v in pairs(spawn_items) do
		obj=create(v,db.actor:position(),db.actor:level_vertex_id(),db.actor:game_vertex_id(),db.actor:id())
		if spawn_7_state and v=="wpn_knife" then
			set_value("wpn_knife_7",obj.id)
		end
	end 
end

function bar_arena_weapon_slot ()
	db.actor:clear_blocked_slots()
	if has_info("bar_arena_fight_1") then  
		db.actor:activate_slot(inventory_slots.PISTOL)
	elseif has_info("bar_arena_fight_2") then 
		db.actor:activate_slot(inventory_slots.SHOTGUN)
	elseif has_info("bar_arena_fight_3") then
		db.actor:activate_slot(inventory_slots.PISTOL)
	elseif has_info("bar_arena_fight_7") then
		db.actor:activate_slot(inventory_slots.KNIFE)
	else
		db.actor:activate_slot(inventory_slots.RIFLE)
	end
end

function bar_arena_teleport_2 ( actor, npc)
	give_info("teleport_started")
    level.add_pp_effector ("blink.ppe", 234, false)       
  
    db.actor:set_actor_position(patrol("t_walk_2"):point(0))
    local dir = patrol("t_look_2"):point(0):sub(patrol("t_walk_2"):point(0))
    db.actor:set_actor_direction(-dir:getH())
	give_info("teleport_finished")
  
  inv_box_2 = level_story_object (574)

	out_object = actor
    in_object  = inv_box_2
    actor:inventory_for_each(transfer_object_item) 
	disable_info("save_prohibited")
end

function barman_give_extra_task (actor, npc)
  if has_info ("agroprom_military_case_done") and not has_info ("bar_darklab_document_start") then
    give_info("barman_job_1")
    return
  elseif has_info ("bar_darklab_document_done") and not has_info ("bar_x16_documents_start") then
    give_info("barman_job_2")
    return
  elseif has_info ("bar_x16_documents_done") and not has_info ("bar_deactivate_radar_start") then
    give_info("barman_job_3")
    return
  end
  return  
end

function trader_extra_task (actor, npc)
  if has_info ("esc_serious_talk") and not has_info ("agroprom_military_case") then
    give_info("trader_job")
    return
  end
  return
end

function scientist_extra_task (actor, npc)
  if has_info ("yan_find_scientist_done") and not has_info ("yan_find_vasilyev_start") then
    give_info("scientist_job")
    return
  end
  return
end

function military_max_dead (actor, npc)
end

function military_lukash_dead (actor, npc)
end

function mil_courier_death (actor, npc)
    give_info ("mil_courier_dead")
    if has_info("mil_leader_quest2_start") then
       if not has_info("mil_courier_visited") then
          level_tasks.set_task_state (task.fail, "mil_courier_job", 1)
       end   
       level_tasks.set_task_state (task.completed, "mil_courier_job", 2)
       level_tasks.set_task_state (task.completed, "mil_courier_job", 0)
    end   
end

function mil_courier_quest_fail (actor, npc)
    if has_info("mil_courier_quest") == false then return end
    level_tasks.set_task_state (task.fail, "mil_courier_job", 0)
    give_info ("mil_courier_quest_failed")
end

function mil_scull_news (actor, npc)
end

function mil_sniper_dead (actor, npc)
    if has_info("mil_dolg_final_task") then
       level_tasks.remove_location (npc:story_id (), "mil_sniper_location")
    end       
end

function mil_actor_enemy_set (actor, npc)
    local sniper = level_story_object (704)
    if sniper ~= nil then
--       sniper:set_relation (game_object.enemy, db.actor)		-- отключен переход Свободы во враги при заходе в запретную зону
    end   
    --xr_gulag.setGulagRelation ("mil_freedom", game_object.enemy, db.actor)    
end


function mil_actor_enemy_reset (actor, npc)
    local sniper = level_story_object (704)
    if sniper ~= nil then
--       sniper:set_relation (game_object.neutral, db.actor)	-- отключен переход Свободы во враги при заходе в запретную зону
    end   
    --xr_gulag.setGulagRelation ("mil_freedom", game_object.neutral, db.actor)    
end

function mil_bomb_explode (actor, npc)
    local source = nil
	local se_obj = story_object (723)  
	if se_obj then
		source = level_object(se_obj.id)
	end

    if source == nil then
       --'abort ("Bomb with story id MIL_BOMB not found")
       return
    end

    local h = hit ();
    h.power = 1000000;
    h.direction = vector():set( 1, 0, 0 );
    h.impulse = 1;
    h.draftsman = source;
    h.type = hit.chemical_burn;
    source:hit (h);
    
    source:explode(0)
end

function mil_set_alarm (actor, npc)
  printf("pl:millitary base is under attack!")
    give_info ("mil_freedom_under_attack")
    
    local skull = level_story_object (708)
    if skull == nil then 
       return 
    end

    this.set_stalker_enemy (702, skull)     -- hit to Max
    this.set_stalker_enemy (707, skull)     -- hit to Lukash
    this.set_stalker_enemy (730, skull)     -- hit to Sniper1
    this.set_stalker_enemy (731, skull)     -- hit to Sniper2
    this.set_stalker_enemy (732, skull)     -- hit to Sniper3
end

function sar2_monolith_explode (actor, npc)
    local monolith = level_story_object (1305)
    if monolith == nil then
       abort ("Object MONOLITH with SID 1305 not found")
    end    
    local h = hit ();
    h.power = 1000;
    h.direction = vector():set( 1, 0, 0 );
    h.impulse = 1;
    h.draftsman = actor;
    h.type = hit.chemical_burn;
    monolith:hit (h);
end

function set_stalker_enemy (sid, draftsman)
    local npc = level_story_object (sid)
    if npc == nil or npc:alive () == false then
       return 
    end    
    local h = hit ()
    h.power = 0
    h.direction = vector():set( 1, 0, 0 )
    h.impulse = 0
    h.draftsman = draftsman
    h.type = hit.strike
    npc:hit (h)
end



function mil_remove_cook_map_spot (actor, npc)
    level_tasks.remove_location (728, "mil_cook_location")
end

function mil_transfer_docs_to_ara (actor, npc)
    --local ara = level_story_object (719)
    --local pavlik = level_story_object (710)
    --if ara == nil or pavlik == nil or pavlik:object ("mil_courier_doc") == nil then
       --return
    --end   
    --ara:transfer_item (pavlik:object ("mil_courier_doc"), pavlik)
end

function mil_emeny_nearest (actor, npc)
    if actor == nil or actor:alive () == false then
       return
    end    

    local gulag = xr_gulag.get_gulag_by_name ("mil_freedom")
    if gulag == nil then return end

    if gulag:npc_is_enemy_to_anybody(actor) then
       give_info ("mil_enemy_nearest")
    end
end


function mil_cap_mapspot (actor, npc)
    local cap = level_story_object (724)
    if cap == nil or cap:alive () == false then
       return 
    end    
    
    if not has_info("mil_fblockpost_spot_set") then
       give_info ("mil_fblockpost_spot") 
       give_info ("mil_fblockpost_spot_set")
       level_tasks.add_location (724, "mil_fblockpost_location")
    end
end

function mil_cap_mapspot_remove (stalker1, stalker2)
    if has_info("mil_fblockpost_spot") then
       level_tasks.remove_location_safe (724, "mil_fblockpost_location")
       disable_info ("mil_fblockpost_spot_remove")
    end      
end

function set_actor_enemy_for_freedom (actor, npc)
    xr_gulag.setGulagEnemy ("mil_freedom", actor)
end


-- GARBAGE

function gar_send_dolg_warning()
  if db.actor then
    if xr_gulag.getGulagPopulation("gar_dolg") > 0 then
      sms("gar_dolg_warning", 0, "dolg")
    end
  end
end


-------------------------------------------------------------------------------------
-- Функции для DarkValley
-------------------------------------------------------------------------------------
function val_escort_guard_death(actor, npc)
    --printf("xr_effects <val_escort_guard_death>: %s.", npc:name())
    local idx = string.sub(npc:name(), -1)
  local t = db.storage[npc:id()].death

    disable_info("val_escort_guard" .. idx .. "_combat")
    give_info("val_escort_guard" .. idx .. "_dead")
    
  if t ~= nil and t.killer == actor:id() then
        give_info("val_escort_actor_helped")
  end
    --"on_info     = %-val_escort_guard1_combat +val_escort_guard1_dead%\n" ..
    --"on_info2    = {=killed_by_actor} %+val_escort_actor_helped%\n" ..
end

function val_escort_guard_hit(actor, npc)
    local idx = string.sub(npc:name(), -1)
  local t = db.storage[npc:id()].hit

  if t ~= nil then
      if t.who == actor:id() then
            give_info("val_escort_combat")
            give_info("val_escort_actor_helped")
            if not has_info("val_escort_nap1_start_combat") then
                give_info("val_escort_captive_enemy")
            end
      else
          local npc1 = level_story_object(406)
          if npc1 ~= nil and t.who == npc1:id() then
                give_info("val_escort_combat")
                give_info("val_escort_nap1_start_combat")
          --else
            --    give_info("val_escort_guard" .. idx .. "_combat")
          end
      end
  end
    --"on_info     = {=hit_by_actor} %+val_escort_combat +val_escort_actor_helped%, %+val_escort_guard1_combat%\n" ..
    --"on_info2    = {+val_escort_combat -val_escort_nap1_start_combat} %+val_escort_captive_enemy%\n" ..
    --"on_info3    = {=hitted_by(406) -val_escort_captive_enemy} %+val_escort_nap1_start_combat%\n" ..
end

function val_escort_guard_combat(actor, npc)
    local idx = string.sub(npc:name(), -1)

    give_info("val_escort_guard" .. idx .. "_combat")
    
    if npc:see(actor) then
        if not has_info("val_escort_nap1_start_combat") then
            give_info("val_escort_captive_enemy")
        end
        give_info("val_escort_combat")
    end
    --"on_info     = %+val_escort_guard1_combat%\n" ..
    --"on_info2    = {=see_actor -val_escort_nap1_start_combat -val_escort_captive_enemy} %+val_escort_captive_enemy%\n" ..
    --"on_info3    = {=see_actor -val_escort_combat} %+val_escort_combat% ;remark@val_escort_guard1_fight\n" ..
end

function val_escort_guard_free(actor, npc)
    --local idx = string.sub(npc:name(), -1)

    give_info("val_escort_guards_free")
    disable_info("val_escort_guard" .. string.sub(npc:name(), -1) .. "_combat")
    --"on_info             = %+val_escort_guards_free -val_escort_guard1_combat%\n"
end


-------------------------------------------------------------------------------------
-- kill
-------------------------------------------------------------------------------------
function killactor (actor, npc)
    npc:set_relation (game_object.enemy, actor)
    --give_info ("mil_bodyguard_kill")
end

function kill(actor, npc)
  npc:kill( npc )
end


-------------------------------------------------------------------------------------
-- Функции для Агропрома
-------------------------------------------------------------------------------------

function agr_krot_sos( actor, npc )
  sms("tips_agr_krot_sos", 0, "krot", 10000 )
end

function agr_krot_sos_1_2( actor, npc )
  if not has_info( "agr_help_krot_start" ) and
     not has_info( "agr_help_krot_done" ) and
     not has_info( "agr_krot_skirmish_start" ) and
     not has_info( "agr_krot_dead" ) and not(agroprom_tasks.agr_actor_enemy())
  then
    give_info( "agr_help_krot_start" )
    sms("tips_agr_krot_sos1", 0, "krot", 7000 )
     sms("tips_krot_soldiers_1", 5, "kostylnuga", 5000, nil, [[characters_voice\scenario\agroprom\krot_soldiers_1]])
      sms("tips_krot_soldiers_2", 8, "kostylnuga", 5000, nil,[[characters_voice\scenario\agroprom\krot_soldiers_2]])
       sms("tips_krot_soldiers_3", 11.5, "kostylnuga", 6000, nil, [[characters_voice\scenario\agroprom\krot_soldiers_3]])
    if has_info( "agr_help_stalkers_defence_dead" ) then
      sms("tips_agr_krot_sos2", 0, "krot", 10000 )
     end
  end
end

function agr_knockdown ()
  say([[affects\tinnitus3a]])
  level.add_cam_effector("camera_effects\\earthquake.anm", 1974, false, "")
end

function agr_contuz (actor, npc)
    local sound_obj_l   = voice( [[affects\psy_blackout_l]] )
        local sound_obj_r   = voice( [[affects\psy_blackout_r]] )
        
    sound_obj_l:play_no_feedback(actor, sound_object.s2d, 0, vector():set(-1, 0, 1), 1.0)
    sound_obj_r:play_no_feedback(actor, sound_object.s2d, 0, vector():set( 1, 0, 1), 1.0)
end

function agr_cam_effect ()
  level.add_cam_effector2("camera_effects\\agroprom_doctor_cam.anm", 123, false, "")

end

function agr_weapon(actor, npc)
  if  actor ~= nil then actor:activate_slot(2)
  end
end
function agr_hold_enemy(actor, npc)
  local gulag = xr_gulag.get_gulag_by_name("agr_factory_hold")
  
  local h  = hit()
  h.power     = 0.01
  h.direction = vector():set( 1, 0, 0 )
  h.draftsman = actor
  h.impulse   = 1
  h.type      = hit.wound
  
  for k, v in pairs(gulag.Object) do
    if v ~= true and level_object( k ) ~= nil then
      v:hit( h )
    end
  end 
end
--------------------------------------------------------- 
-- PRIPYAT
--------------------------------------------------------- 
function pri_zombied_in_combat_inc(actor, npc)
    gulag_pripyat.zombied_in_combat[npc:name()] = true
    --printf("effect <pri>: zombied in combat(%s) inc.", npc:name())
end

function pri_zombied_in_combat_dec(actor, npc)
    gulag_pripyat.zombied_in_combat[npc:name()] = nil
    --printf("effect <pri>: zombied in combat(%s) dec.", npc:name())
end

function pri_drop_rpg_ammo(actor, npc)
    local item = npc:object("ammo_og-7b")
    if item then
        npc:drop_item(item)
    else
        printf("xr_effects <pri_drop_rpg_ammo>: there is no [ammo_og-7b] in [%s] inventory", npc:name())
    end
end

function pri_give_ammo_og7b(actor, npc)
    create("ammo_og-7b", npc:position(), npc:level_vertex_id(), npc:game_vertex_id(), npc:id())
    create("ammo_og-7b", npc:position(), npc:level_vertex_id(), npc:game_vertex_id(), npc:id())
end

-------------------------------------------------------------------------------------
-- Функции для работы с вертолётами
-------------------------------------------------------------------------------------
function heli_set_enemy_actor(actor, npc)
  local st = db.storage[npc:id()]
  if not st.combat.enemy_id and actor:alive() then
    st.combat.enemy_id = actor:id()

    heli_snd.play_snd( st, heli_snd.snd_see_enemy, 1 )
  end 
end

function heli_set_enemy(actor, npc, p)
  local st  = db.storage[npc:id()]
  local obj = level_story_object( p[1] )

  if not st.combat.enemy_id and obj:alive() then
    st.combat.enemy_id = obj:id()

    heli_snd.play_snd( st, heli_snd.snd_see_enemy, 1 )
  end
end

function heli_clear_enemy(actor, npc)
    db.storage[npc:id()].combat:forget_enemy()
end

function heli_start_flame(actor, npc)
  bind_heli.heli_start_flame( npc )
end

function heli_die(actor, npc)
	bind_heli.heli_die( npc )
end


-------------------------------------------------------------------------------------
-- Функции для работы с погодными эффектами
-------------------------------------------------------------------------------------
function start_small_reject (actor, npc)
	local hours_type=amk_mod.blowout_hours()
	level.set_weather_fx("surge_aes_"..hours_type)
	level.add_pp_effector ("vibros_p.ppe", 1974, false)
	this.aes_earthshake (npc)
end

function start_full_reject (actor, npc)
	local hours_type=amk_mod.blowout_hours()
	level.set_weather_fx("surge_aes_"..hours_type)
    level.remove_pp_effector (1974)
    level.add_pp_effector ("vibros.ppe", 1974, false)
end


function aes_grenade_explode (actor, npc)
    local obj = level_story_object (1101)
    if obj == nil then return end
    local h = hit ();
    h.power = 1000;
    h.direction = vector():set (1, 0, 0);
    h.impulse = 1;
    h.draftsman = obj;
    h.type = hit.chemical_burn;
    obj:hit (h);
end

function aes_kill_actor (actor, npc)
    if actor ~= nil and actor.health > 0 then 
       actor:kill (actor)
    end   
end

function set_sidorovich_animation (npc)
    local sidor = level_story_object (1118)
    if sidor == nil then
       abort ("SIDOROVICH NOT FOUND !!!")
    end
    sidor:play_cycle ("wonder", true)
end

function aes_zombie_hit1 (npc)
    --local npc = level_story_object (1119)
    --local force = vector ():set (0, 0, 0.02)
    --local pshell = npc:get_physics_shell ()
    
    --local joint = pshell:get_joint_by_bone_name ("head2")
    --joint:set_max_force_and_velocity (0.5 + math.random (), 0.1 * -1, 0)
    --joint:set_max_force_and_velocity (0.5 + math.random(), 0.1 * -1,  2)
    
    --local npc = level_story_object (1119)
    --local force = vector ():set (0, 0, 50)
    --local pshell = npc:get_physics_shell ()
    --local element = pshell:get_element_by_bone_name ("foot_right")
    --element:apply_force (force.x, force.y, force.z)
    
    -- foot_right, foot_left, left_hand, right_hand
        
    
    --local dir = npc:direction ()
    --dir.y = 0.0
    --dir:normalize ()
  --npc:set_const_force (dir, 2000, 3)
  
    --npc = level_story_object (1120)
    --dir = npc:direction ()
    --dir.y = 0.0
    --dir:normalize ()   
  --npc:set_const_force (dir, 2000, 3)
  
    --npc = level_story_object (1121)
    --dir = npc:direction ()
    --dir.y = 0.0
    --dir:normalize ()   
  --npc:set_const_force (dir, 2000, 3)
  
    --npc = level_story_object (1122)
    --dir = npc:direction ()
    --dir.y = 0.0
    --dir:normalize ()   
  --npc:set_const_force (dir, 2000, 3)
  
    --npc = level_story_object (1123)
    --dir = npc:direction ()
    --dir.y = 0.0
    --dir:normalize ()   
  --npc:set_const_force (dir, 2000, 3)
end

function aes_zombie_hit2 (npc)
    --local npc = level_story_object (1119)
    --local force = vector ():set (0, 0, 50)
    --local pshell = npc:get_physics_shell ()
    --local element = pshell:get_element_by_bone_name ("foot_right")
    --element:apply_force (force.x, force.y, force.z)
    
    
    --local npc = level_story_object (1119)
    --local force = vector ():set (0, 0, 0.02)
    --local pshell = npc:get_physics_shell ()
    
    --local joint = pshell:get_joint_by_bone_name ("head2")
    --joint:set_max_force_and_velocity (0.5 + math.random (), 0.1 * 1, 0)
    --joint:set_max_force_and_velocity (0.5 + math.random(), 0.1 * 1,  2)
                --self.dir_x_axis  = self.dir_x_axis * (-1)
                --self.dir_z_axis = self.dir_z_axis * (-1)
                --self.time    = screen:time_global() + math.random(800, 1000)
        --end
    
    --local element = pshell:get_element_by_bone_name ("foot_right")
    --element:apply_force (force.x, force.y, force.z)
    --local npc = level_story_object (1119)
    --local dir = npc:direction ()
    --dir.y = 0.0
    --dir.x = -dir.x
    --dir.z = -dir.z
    --dir:normalize ()
  --npc:set_const_force (dir, 2000, 3)
  
    --npc = level_story_object (1120)
    --dir = npc:direction ()
    --dir.y = 0.0
    --dir.x = -dir.x
    --dir.z = -dir.z
    --dir:normalize ()   
  --npc:set_const_force (dir, 2000, 3)
  
    --npc = level_story_object (1121)
    --dir = npc:direction ()
    --dir.y = 0.0
    --dir.x = -dir.x
    --dir.z = -dir.z
    --dir:normalize ()   
  --npc:set_const_force (dir, 2000, 3)
  
    --npc = level_story_object (1122)
    --dir = npc:direction ()
    --dir.y = 0.0
    --dir.x = -dir.x
    --dir.z = -dir.z
    --dir:normalize ()   
  --npc:set_const_force (dir, 2000, 3)
  
    --npc = level_story_object (1123)
    --dir = npc:direction ()
    --dir.x = -dir.x
    --dir.z = -dir.z
    --dir.y = 0.0
    --dir:normalize ()   
  --npc:set_const_force (dir, 2000, 3)
end

-- постпроцесс и влияние удара в морду
function aes_earthshake (npc)
  say([[ambient\earthquake]])
  level.add_cam_effector("camera_effects\\earthquake.anm", 1974, false, "")
end

function vovan_camera_test (npc)
  level.add_cam_effector("camera_effects\\test.anm", "")                    
end
-------------------------------------------------------------------------------------
-- Функции для Янтаря
----------------------------------------------------------------------------------
function yan_actor_sleep (actor, npc)
  give_info("teleport_started")
  db.actor:set_actor_position(patrol("yan_actor_sleep"):point(0))
  local dir = patrol("yan_actor_sleep"):point(1):sub(patrol("yan_actor_sleep"):point(0))
  db.actor:set_actor_direction(-dir:getH())
  give_info("teleport_finished")
end

function yan_actor_sleep_1 (actor, npc)
  give_info("teleport_started")
  db.actor:set_actor_position(patrol("yan_actor_sleep_1"):point(0))
  local dir = patrol("yan_actor_sleep_1"):point(1):sub(patrol("yan_actor_sleep_1"):point(0))
  db.actor:set_actor_direction(-dir:getH())
  give_info("teleport_finished")
end

function yan_dream_voices (actor, npc)
        local sound_obj_l   = voice( [[characters_voice\scenario\yantar\dream_talk_l]] )
        local sound_obj_r   = voice( [[characters_voice\scenario\yantar\dream_talk_r]] )
        
    sound_obj_l:play_no_feedback(actor, sound_object.s2d, 0, vector():set(-1, 0, 1), 1.0)
    sound_obj_r:play_no_feedback(actor, sound_object.s2d, 0, vector():set( 1, 0, 1), 1.0)
end

function yan_gluk (actor, npc)
    
    local sound_obj_l   = voice( [[affects\psy_blackout_l]] )
        local sound_obj_r   = voice( [[affects\psy_blackout_r]] )
        
    sound_obj_l:play_no_feedback(actor, sound_object.s2d, 0, vector():set(-1, 0, 1), 1.0)
    sound_obj_r:play_no_feedback(actor, sound_object.s2d, 0, vector():set( 1, 0, 1), 1.0)
  level.add_cam_effector("camera_effects\\earthquake.anm", 1974, false, "")

end
function x18_gluk (actor, npc)
    level.add_pp_effector ("blink.ppe", 234, false)
    local sound_obj_l   = voice( [[affects\psy_blackout_l]] )
        local sound_obj_r   = voice( [[affects\psy_blackout_r]] )
        local snd_obj     = voice( [[affects\tinnitus3a]] )
    snd_obj:play_no_feedback(db.actor, sound_object.s2d, 0, vector(), 1.0)
    sound_obj_l:play_no_feedback(actor, sound_object.s2d, 0, vector():set(-1, 0, 1), 1.0)
    sound_obj_r:play_no_feedback(actor, sound_object.s2d, 0, vector():set( 1, 0, 1), 1.0)
  level.add_cam_effector("camera_effects\\earthquake.anm", 1974, false, "")

end



function yan_sleep_not_relocate (actor, npc)
    db.actor:actor_sleep(0, 180)
end
function yantar_kruglov_talk(actor,npc)
  xr_sound.set_sound_play(npc, "rostok_kruglov_help_6")
end

function yantar_professor_spam_1 (actor, npc)
    sms("general_ecolog_tip_1", nil, "saharov", nil, 902)
end

function yantar_professor_spam_2 (actor, npc)
    sms("general_ecolog_tip_2", nil, "saharov", nil, 902)
end

function yantar_vasilyev_spam (actor, npc)
    sms("storyline_vasilyev_tip", nil, "ecolog", nil, 903)
end
function yan_saharov_message (actor, npc)
    sms("yan_saharov_message", nil, "saharov", nil, 902)
    give_info("labx16_find")
end

function yan_saharov_message_2 (actor, npc)
    sms("yan_saharov_message_2", nil, "saharov", nil, 902)
end
function yan_saharov_message_3 (actor, npc)
    sms("yan_saharov_message_3", nil, "saharov", nil, 902)
end
function yan_ghost_pda (actor, npc)
    if has_info("agr_find_gunslinger_cache_final") then 
        give_info("yan_provodnik_spawn")
    end
    sms("storyline_ghost_tip", nil, "prizrak")
end

function start_yantar_dream(actor, npc)
  game.start_tutorial("yantar_dream")
end

function end_yantar_dream(actor, npc)
  give_info("yantar_find_ghost_task_start")
  give_info("strelok_taynik_pda0_start")
  give_info("foto_strelok_start")
  snp.x16_1()		-- snp
end
-----------------------------radar
function rad_sos_spam(actor, npc)
  sms("tips_rad_sos_suicide", nil, "stalker", nil, 1004)
end


function monolith_generator_hit (actor, npc)
    printf ("ON GENERATOR HIT !!!")
end


function start_x18_dream(actor, npc)
  game.start_tutorial("x18_dream")
end
function end_x18_dream(actor, npc)
  give_info("dar_x18_dream")
end

--[[---------------- ролик перед фриплеем с расстрелом осознания ---------------]]
function aes_final_movie(actor, npc)
 -- game.start_tutorial("mov_refuse_osoznanie")
end
--[[--------------------------------- lsclon -----------------------------------]]

function start_kursk_dream(actor, npc)
  game.start_tutorial("kursk_dream")
end

function start_death_machine_dream(actor, npc)
  game.start_tutorial("death_machine_dream")
end

function start_vzlet_generators(actor, npc)
  game.start_tutorial("vzlet_generators")
end

function start_vzlet_bolota(actor, npc)
  game.start_tutorial("vzlet_bolota")
end

function start_dolg_dream(actor, npc)
  game.start_tutorial("dolg_dream")
end

function start_finish_dopa_dream(actor, npc)
--  game.start_tutorial("finish_dopa_dream")
end
------------------------------------------------------------------------------------
-- Функции для Радара
------------------------------------------------------------------------------------
function rad_psi_hit (actor, npc)
  level.add_pp_effector ("radar_psi.ppe", 2006, false)
end

function start_radar_dream(actor, npc)
  game.start_tutorial("radar_dream")
end

function end_radar_dream(actor, npc)
  give_info("bun_patrol_start")
end
------------------------------------------------------------------------------------
-- Функции для саркофага
------------------------------------------------------------------------------------
function destroy_monolith_generator(actor, npc)
    local source = nil
	local se_obj = story_object(1305)  
	if se_obj then
		source = level_object(se_obj.id)
	end

    if source == nil then
       abort ("MONOLITH GENERATOR story id 1305 not found")
       return
    end

    local h = hit ();
    h.power = 1000000;
    h.direction = vector():set( 1, 0, 0 );
    h.impulse = 1;
    h.draftsman = source;
    h.type = hit.chemical_burn;
    source:hit (h);        
end

function game_credits(actor, npc)
  db.gameover_credits_started = true
  game.start_tutorial("credits_seq")
end

function game_over(actor, npc)
  if db.gameover_credits_started ~= true then
    return
  end
--  console:execute("disconnect")
  console:execute("main_menu on")
end

function after_credits(actor, npc)
  if db.gameover_credits_started ~= true then
    return
  end
  console:execute("disconnect")
end


function pri_game_over(actor, npc)
--  console:execute("disconnect")
  console:execute("main_menu on")
end

function esc_init_dialod ()
  local trader = level_story_object(003)
  db.actor:run_talk_dialog(trader)
end

function oso_init_dialod ()
  -- local oso = level_story_object(1307)
  -- db.actor:run_talk_dialog(oso)
end
-- DELME:only for presentation!

function actor_inventory_by_levels ()
  local level = level.name()
    local spawn_items = {}
    local start_point = ""
    
  if level == "l03_agroprom" then
    start_point = "agr_start_actor" 
  elseif level == "l05_bar" then
    start_point = "bar_way_if_reject_to_gar"      
  elseif level == "l08_yantar" then
    start_point = "yan_start_actor"     
  elseif  level == "l11_pripyat" then
    start_point = "pri_way_if_reject_to_rad"  
  end
  give_info("teleport_started")
  db.actor:set_actor_position(patrol(start_point):point(0))
  local dir = patrol(start_point):point(1):sub(patrol(start_point):point(0))
  db.actor:set_actor_direction(-dir:getH())
  give_info("teleport_finished")
  
end

function presentation_tutorial ()
end

function presentation_task ()
end

function change_leader(actor, npc)
  if xr_gulag.getGulagPopulation(823) == 0 then
    give_info("pri_followers_all_dead")
  end
end

function on_tutor_gameover_stop()
--  console:execute("disconnect")
  console:execute("main_menu on")
end

-- удаление объекта из его логики
function release_obj(actor, npc)
	local sobj = server_object(npc:id())
	if sobj then
		release(sobj, true)
	end
end

------------------------------------------------------- ARENA_EXTENSION_MOD--------------------------------------------------------

function aem_draw()
	db.actor:set_character_community("trader",0,0)
	aem_lights.draw()
end

function aem_win()
	aem_lights.win()
end

function aem_foul()
	aem_lights.foul()
end

function aem_death(actor, npc, p)
	Arena:on_death(npc, p[1])
end

function aem_finish()
	Arena:finish()
end

function switch(actor, npc)
	if has_info("aem_go_bar") then
		npc:add_restrictions("bar_restrictor", "")
	-- else
		-- npc:remove_all_restrictions()
	end
end

------------------------------------------------------- ARENA_EXTENSION_MOD-----------------------------------------

---------------------------------
-- Телепорты 
---------------------------------
-- удаляем телепорты
function delete_teleport2(story_id)
local obj_id = get_value("m_teleport_6", -1, true)
local se_obj = server_object(obj_id)
if se_obj then
  release(se_obj, true)
end
sms("delete_teleport2_0", nil, nil, 30000)
end 

function delete_teleport3(story_id)
local obj_id = get_value("m_teleport_26", -1, true)
local se_obj = server_object(obj_id)
if se_obj then
  release(se_obj, true)
end
sms("delete_teleport3_0", nil, nil, 30000)
end 

-- спавним телепорты
function spawn_teleport26()
    local se_obj = create("m_teleport_26",xyz(-111.23854064941,-14.067569732666,-31.287431716919),478,780)
	set_value("m_teleport_26", se_obj.id)	
end

function spawn_teleport27()
    local se_obj = create("m_teleport_27",xyz(-38.85717010498,-4.5971913337708,-1.880425453186),4689,731)
	set_value("m_teleport_27", se_obj.id)
	
	se_obj = create("space_restrictor",xyz(-42.986083984375,-6.233211517334,-37.656509399414),4573,735)
	local custom = "[logic]\n"..
	"active = sr_idle\n"..
	"[sr_idle]\n"..
	"on_actor_inside = {+have_info1} nil %=delete_m_teleport_27%"
	se_obj:set_ini_lua_string(custom)
	se_obj:add_shape(1.0)
	
	give_info("teleport_started")
	db.actor:set_actor_position(xyz(-39.117069244385,-4.8768610954285,-41.140972137451))
	give_info("teleport_finished")
end
function delete_m_teleport_27()
	local obj_id = get_value("m_teleport_27", -1, true)
	local se_obj = server_object(obj_id)
	if se_obj then
		sms("delete_m_teleport_27_0", nil, nil, 30000)
		release(se_obj, true)
	end
end

function spawn_teleport6()
    local se_obj = create("m_teleport_6",xyz(-76.897171020508,2.4566078186035,-110.1841506958),3005,797)
set_value("m_teleport_6", se_obj.id)
end

-- звук в схроне Стрелка
function play_zvuk() 
  	say([[intro\intro_kill_l]])
end

-- инфопоршин после телепортации от входа
function info1() 
  	sms("info1_0", nil, nil, 30000)
	give_info("have_info1")
end

-- звук при спавне сакера
function play_zvuk2() 
  	say([[monsters\bloodsucker\bloodsucker_script_attack_0]])
end

function spawn_krovosos()
local obj = create("bloodsucker_normal",xyz(-113.27488708496,-16.462959289551,-53.749374389648),351,757)
end

function spawn_krovosos2()
local obj = create("bloodsucker_normal",xyz(-105.32235717773,-16.462980270386,-18.557649612427),1111,710) 
end

--------------
--рестрикторы 
--------------
-- в подземелье агропрома
function create_sr3() 
local se_obj = create("space_restrictor",xyz(-95.296127319336,-16.464744567871,-4.9873023033142),1998,761)
local custom = "[logic]\n"..
"active = sr_idle\n"..
"[sr_idle]\n"..
"on_actor_inside = {+have_info1} nil %=play_zvuk2 =spawn_krovosos2%"
se_obj:set_ini_lua_string(custom)
se_obj:add_shape(1.0)
end 

function create_sr4() 
local se_obj = create("space_restrictor",xyz(-103.36071777344,-16.213626861572,-44.560150146484),1241,755)
local custom = "[logic]\n"..
"active = sr_idle\n"..
"[sr_idle]\n"..
"on_actor_inside = {+have_info1} nil %=play_zvuk2 =spawn_krovosos%"
se_obj:set_ini_lua_string(custom)
se_obj:add_shape(1.0)
end

function create_sr5() 
local se_obj = create("space_restrictor",xyz(-72.414398193359,2.4857983589172,-116.41065979004),3256,797)
local custom = "[logic]\n"..
"active = sr_idle\n"..
"[sr_idle]\n"..
"on_actor_inside = {+have_info1} nil %=delete_teleport2 =spawn_teleport26 =create_sr3 =create_sr4 =create_sr6%"
se_obj:set_ini_lua_string(custom)
se_obj:add_shape(6.0)
end 

function create_sr6() 
local se_obj = create("space_restrictor",xyz(-113.44139862061,-14.169027328491,-29.277599334717),369,780)
local custom = "[logic]\n"..
"active = sr_idle\n"..
"[sr_idle]\n"..
"on_actor_inside = {+have_info1} nil %=delete_teleport3 =spawn_teleport27%"
se_obj:set_ini_lua_string(custom)
se_obj:add_shape(10.0)
end 

-- в Х18
function create_sr8() 
local se_obj = create("space_restrictor",xyz(-0.8382523059845,-10.815600395203,-9.8239765167236),2672,1134)
local custom = "[logic]\n"..
"active = sr_idle\n"..
"[sr_idle]\n"..
"on_actor_inside = {+info_restriction} nil %=play_zvuk4%"
se_obj:set_ini_lua_string(custom)
se_obj:add_shape(8.5)
end 

function create_sr9() 
local se_obj = create("space_restrictor",xyz(-0.64052796363831,-10.764112472534,-10.320294380188),2670,1133)
local custom = "[logic]\n"..
"active = sr_idle\n"..
"[sr_idle]\n"..
"on_actor_inside = {+info_restriction} nil %=play_zvuk5%"
se_obj:set_ini_lua_string(custom)
se_obj:add_shape(7.5)
end 

function play_zvuk3() 
  	say([[ambient\random\rnd_moan1]])
end

function play_zvuk4() 
  	say([[ambient\random\rnd_fallscream]])
end

function play_zvuk5() 
  	say([[monsters\bloodsucker\bloodsucker_script_attack_0]])
end

function spawn_krovosos3()
	create("bloodsucker_strong",xyz(-2.0031547546387,-10.815952301025,26.333080291748),2460,1145) 
end
function spawn_krovosos4()
	create("bloodsucker_strong",xyz(-2.2437686920166,-10.817986488342,10.569171905518),2438,1143) 
end
function spawn_krovosos5()
	create("bloodsucker_strong",xyz(-2.6273674964905,-10.818544387817,-1.5016434192657),2329,1143)
end
function spawn_krovosos6()
	create("bloodsucker_strong",xyz(-6.3397164344788,-10.814113616943,-5.9057211875916),1956,1150)
end

-- Янтарь
function spawn_teleport31()
   local se_obj = create("m_teleport_31",xyz(-28.138628005981,0.70888710021973,-51.528060913086),23720,1527)
set_value("m_teleport_31", se_obj.id)
end

function spawn_teleport32()
    local se_obj = create("m_teleport_32",xyz(-27.691612243652,0.30473950505257,22.615579605103),23064,1527)
set_value("m_teleport_32", se_obj.id)
end

function spawn_teleport33()
    local se_obj = create("m_teleport_33",xyz(-27.159645080566,-0.040736228227615,-140.54766845703),23720,1527)
set_value("m_teleport_33", se_obj.id)
end

function spawn_teleport34()
    local se_obj = create("m_teleport_34",xyz(-13.03503036499,0.089942842721939,-80.229797363281),77962,1513)
set_value("m_teleport_34", se_obj.id)
end

function spawn_controller()
	create("m_controller_normal",xyz(-10.052182197571,0.22448572516441,27.419820785522),77986,1512)
end

function create_sr13() 
local se_obj = create("space_restrictor",xyz(41.420497894287,0.23940727114677,-101.4430847168),77962,1513)
local custom = "[logic]\n"..
"active = sr_idle\n"..
"[sr_idle]\n"..
"on_actor_inside = {+info_restriction} nil %=spawn_chimera2 =spawn_chimera%"
se_obj:set_ini_lua_string(custom)
se_obj:add_shape(10.0)
end 

function spawn_chimera()
	create("chimera_strong",xyz(88.911819458008,-0.04115504026413,-73.805587768555),77962,1513)
end
function spawn_chimera2()
	create("chimera_strong",xyz(-19.945352554321,-0.17231740057468,-140.34425354004),77962,1513)
end

-- Х-10
function play_zvuk6() 
  	say([[ambient\random\rnd_ratchant]])
end

function new_inventory11()
local obj = create("m_inventory_box11",xyz(-30.228071212769,-21.02052116394,58.902126312256),2490,2748)
map_spot(obj.id, "treasure", "Cache")
sms("Received a tip on the cache", nil, nil, 10000)
end

function x_10_clean_teleports()
	local teleports={
		["m_teleport_54"]=true,
		["m_teleport_53"]=true,
		["m_teleport_52"]=true,
		["m_teleport_51"]=true,
		["m_teleport_50"]=true,
		["m_teleport_49"]=true,
		["m_teleport_48"]=true,
		["m_teleport_47"]=true,
		["m_teleport_46"]=true,
		["m_teleport_45"]=true,
		["m_teleport_44"]=true,
		["m_teleport_43"]=true,
		["m_teleport_42"]=true,
		["m_teleport_41"]=true,
		["m_teleport_40"]=true,
		["m_teleport_39"]=true,
		["m_teleport_38"]=true,
		["m_teleport_37"]=true,
		["m_teleport_35"]=true
	}
 	for tp_name,rel in pairs(teleports) do
		x_10_clean_teleport(tp_name)
	end
end

function x_10_clean_teleport(tp_name)
	local tp_id=get_value(tp_name, -1, true)
	if tp_id==-1 then return end
	level.iterate_level_objects(function(obj)
		if obj:id()~=0 and (isMonster(obj) or isStalker(obj)) then
			obj:remove_restrictions("",tp_name..tp_id)
		end
	end)
	local se_obj = server_object(tp_id)
	if se_obj then
		release(se_obj)
	end
end

function spawn_teleport35()
    local se_obj = create("m_teleport_35",xyz(-40.398349761963,-21.837560653687,56.543983459473),1324,2737)
	set_value("m_teleport_35", se_obj.id)		  
end

function delete_teleport35(story_id)
	x_10_clean_teleport("m_teleport_35")
end 

function spawn_teleport36()
    local se_obj = create("m_teleport_36",xyz(-30.385196685791,-21.020092010498,55.938106536865),1962,2738)
	set_value("m_teleport_36", se_obj.id)		  
end

function delete_teleport36(story_id)
	x_10_clean_teleport("m_teleport_36")
end 

function create_sr15() 
	local se_obj = create("space_restrictor",xyz(-19.994720458984,-9.5514478683472,-35.59744644165),3400,2665)
	se_obj:set_ini_lua_string(
		"[logic]\n"..
		"active = sr_idle\n"..
		"[sr_idle]\n"..
		"on_actor_inside = {+info_restriction} nil %=delete_teleport36 =play_zvuk6 =spawn_teleport37 =spawn_teleport38 =spawn_teleport39 =spawn_teleport41 =spawn_teleport42 =create_sr16 =create_sr17%"
	)
	se_obj:add_shape(2)
end 

function spawn_teleport37()
    local se_obj = create("m_teleport_37",xyz(-19.987188339233,-9.5004644393921,-27.889524459839),3411,2665)
	set_value("m_teleport_37", se_obj.id)		  
end

function delete_teleport37(story_id)
	x_10_clean_teleport("m_teleport_37")
end 

function spawn_teleport38()
    local se_obj = create("m_teleport_38",xyz(-20.023223876953,-9.5004854202271,-43.679775238037),3389,2665)
	set_value("m_teleport_38", se_obj.id)		  
end

function delete_teleport38(story_id)
	x_10_clean_teleport("m_teleport_38")
end 

function spawn_teleport39()
    local se_obj = create("m_teleport_39",xyz(-20.102291107178,-9.391640663147,-6.6342015266418),3445,2666)
	set_value("m_teleport_39", se_obj.id)		  
end

function delete_teleport39(story_id)
	x_10_clean_teleport("m_teleport_39")
end 

function spawn_teleport40()
	if not has_info("net_teleport6") then
		local se_obj = create("m_teleport_40",xyz(-6.7612886428833,-7.3805675506592,-56.52018737793),4518,2663)
		set_value("m_teleport_40", se_obj.id)		  
	end
end

function clean_teleport40()
	local ktd=has_info("kostya_x10_taynik_done")
	if has_value("m_teleport_40") and ktd then
		del_value("m_teleport_40")
	end
	for i=1,65534 do
		local obj = server_object(i)
		if obj and obj:section_name()=="m_teleport_40"  then
			if ktd then
				release(obj)
			end
		end
	end 
end

function delete_teleport40(story_id)
	x_10_clean_teleport("m_teleport_40")
end 

function create_sr16() 
	local se_obj = create("space_restrictor",xyz(-1.298624753952,-7.4522504806519,-73.977745056152),5456,2661)
	se_obj:set_ini_lua_string(
		"[logic]\n"..
		"active = sr_idle\n"..
		"[sr_idle]\n"..
		"on_actor_inside = {+info_restriction} nil %=spawn_teleport40%"
	)
	se_obj:add_shape(2)
end 

function spawn_teleport41()
    local se_obj = create("m_teleport_41",xyz(-30.603868484497,-8.9784269332886,19.563804626465),2243,2780)
	set_value("m_teleport_41", se_obj.id)		  
end

function delete_teleport41(story_id)
	x_10_clean_teleport("m_teleport_41")
end 

function spawn_teleport42()
    local se_obj = create("m_teleport_42",xyz(-32.942707061768,-9.4474973678589,1.0606206655502),2026,2669)
	set_value("m_teleport_42", se_obj.id)		  
end

function delete_teleport42(story_id)
	x_10_clean_teleport("m_teleport_42")
end 

function create_sr17() 
	local se_obj = create("space_restrictor",xyz(-32.942707061768,-9.4474973678589,1.0606206655502),2026,2669)
	se_obj:set_ini_lua_string(
		"[logic]\n"..
		"active = sr_idle\n"..
		"[sr_idle]\n"..
		"on_actor_inside = {+info_restriction} nil %=create_sr18 =spawn_teleport54 =spawn_teleport53 =spawn_teleport52 =spawn_teleport51 =spawn_teleport50 =spawn_teleport49 =spawn_teleport48 =spawn_teleport43 =spawn_teleport44 =spawn_teleport45 =spawn_teleport46 =spawn_teleport47%"
	)
	se_obj:add_shape(2)
end 

function spawn_teleport43()
    local se_obj = create("m_teleport_43",xyz(-48.170837402344,-23.529655456543,0.87714487314224),1004,2787)
	set_value("m_teleport_43", se_obj.id)		  
end

function delete_teleport43(story_id)
	x_10_clean_teleport("m_teleport_43")
end 

function spawn_teleport44()
    local se_obj = create("m_teleport_44",xyz(-52.187408447266,-23.582466125488,-7.2188229560852),772,2712)
	set_value("m_teleport_44", se_obj.id)		  
end

function delete_teleport44(story_id)
	x_10_clean_teleport("m_teleport_44")
end 

function spawn_teleport45()
    local se_obj = create("m_teleport_45",xyz(-45.096000671387,-23.522695541382,-12.440341949463),1109,2789)
	set_value("m_teleport_45", se_obj.id)		  
end

function delete_teleport45(story_id)
	x_10_clean_teleport("m_teleport_45")
end 

function spawn_teleport46()
    local se_obj = create("m_teleport_46",xyz(-18.216438293457,-21.836561203003,41.694786071777),3815,2785)
	set_value("m_teleport_46", se_obj.id)		  
end

function delete_teleport46(story_id)
	x_10_clean_teleport("m_teleport_46")
end 

function spawn_teleport47()
    local se_obj = create("m_teleport_47",xyz(-57.305168151855,-21.859325408936,40.726039886475),454,2728)
	set_value("m_teleport_47", se_obj.id)		  
end

function delete_teleport47(story_id)
	x_10_clean_teleport("m_teleport_47")
end 

function spawn_teleport48()
    local se_obj = create("m_teleport_48",xyz(-49.594337463379,-23.536252975464,56.616313934326),929,2735)
	set_value("m_teleport_48", se_obj.id)		  
end

function delete_teleport48(story_id)
	x_10_clean_teleport("m_teleport_48")
end 

function spawn_teleport49()
    local se_obj = create("m_teleport_49",xyz(-17.414360046387,-21.840921401978,55.660831451416),3850,2751)
	set_value("m_teleport_49", se_obj.id)		  
end

function delete_teleport49(story_id)
	x_10_clean_teleport("m_teleport_49")
end 

function spawn_teleport50()
    local se_obj = create("m_teleport_50",xyz(-64.259719848633,-21.895231246948,30.609943389893),113,2725)
	set_value("m_teleport_50", se_obj.id)		  
end

function delete_teleport50(story_id)
	x_10_clean_teleport("m_teleport_50")
end 

function spawn_teleport51()
    local se_obj = create("m_teleport_51",xyz(-52.363986968994,-23.589921951294,-13.084785461426),765,2788)
	set_value("m_teleport_51", se_obj.id)		  
end

function delete_teleport51(story_id)
	x_10_clean_teleport("m_teleport_51")
end 

function spawn_teleport52()
    local se_obj = create("m_teleport_52",xyz(-52.968780517578,-23.594024658203,-2.0381298065186),749,2715)
	set_value("m_teleport_52", se_obj.id)		  
end

function delete_teleport52(story_id)
	x_10_clean_teleport("m_teleport_52")
end 

function spawn_teleport53()
    local se_obj = create("m_teleport_53",xyz(3.5164728164673,-21.845838546753,41.598541259766),6991,2755)
	set_value("m_teleport_53", se_obj.id)		  
end

function delete_teleport53(story_id)
	x_10_clean_teleport("m_teleport_53")
end 

function spawn_teleport54()
    local se_obj = create("m_teleport_54",xyz(-6.4082336425781,-21.823808670044,55.724376678467),4658,2752)
	set_value("m_teleport_54", se_obj.id)		  
end

function delete_teleport54(story_id)
	x_10_clean_teleport("m_teleport_54")
end 

function create_sr18() 
	local se_obj = create("space_restrictor",xyz(-30.385196685791,-21.020092010498,55.938106536865),1962,2738)
	se_obj:set_ini_lua_string(
		"[logic]\n"..
		"active = sr_idle\n"..
		"[sr_idle]\n"..
		"on_actor_inside = {+info_restriction} nil %=play_zvuk6 =x_10_clean_teleports%"
	)
	se_obj:add_shape(2)
end 

function strelok_taynik_pda1_found()
	if not has_info("strelok_taynik_stop") then 
		give_info("strelok_taynik_pda1_found")
	end
end
function strelok_taynik_pda1_3_1_sr1_found()
      sms("%c[sender]"..translate("name_doktor")..":\\n%c[sms_red]"..translate("sms_doctor_strelok_taynik_pda1_3_1_sr1_found_0"), nil, nil, 30000, nil, [[sms\doctor\strelok_taynik_pda1_3_1_sr1_found]])
	  kostya_dialog.spawn_s_teleport1_3_1()
  	  local obj = create("s_inventory_box1_3",xyz(52.041854858398,31.642507553101,42.142894744873),163917,2222)
	  map_spot(obj.id, "treasure", "Cache")
	  sms("Received a tip on the cache", nil, nil, 10000)
end
function strelok_taynik_pda1_3_2_sr1_found()
      sms("%c[sender]"..translate("name_doktor")..":\\n%c[sms_red]"..translate("sms_doctor_strelok_taynik_pda1_3_2_sr1_found_0"), nil, nil, 30000, nil, [[sms\doctor\strelok_taynik_pda1_3_2_sr1_found]])
	  kostya_dialog.spawn_s_teleport1_3_2()
  	  local obj = create("s_inventory_box1_4",xyz(-114.90951538086,13.623062133789,29.111806869507),7528,2253)
	  map_spot(obj.id, "treasure", "Cache")
	  sms("Received a tip on the cache", nil, nil, 10000)
end
function strelok_taynik_pda1_4_sr1_found()
      sms("%c[sender]"..translate("name_strelok")..":\\n%c[sms_red]"..translate("sms_strelok_strelok_taynik_pda1_4_sr1_found_0"), nil, nil, 30000, nil, [[sms\strelok\strelok_taynik_pda1_4_sr1_found]])
	  spawn_restrictor.strelok_taynik_pda1_5_sr1()
  	  local obj = create("s_inventory_box1_5",xyz(43.850688934326,11.827602386475,42.415019989014),155636,2225)
	  map_spot(obj.id, "treasure", "Cache")
	  sms("Received a tip on the cache", nil, nil, 10000)
end
function strelok_taynik_pda1_5_sr1_found()
      sms("%c[sender]"..translate("name_doktor")..":\\n%c[sms_red]"..translate("sms_doctor_strelok_taynik_pda1_5_sr1_found_0"), nil, nil, 30000, nil, [[sms\doctor\strelok_taynik_pda1_5_sr1_found]])
	  kostya_dialog.spawn_s_teleport1_5()
end

function strelok_taynik_pda4_found()
	if not has_info("strelok_taynik_stop") then 
		give_info("strelok_taynik_pda4_found")
	end
end

function strelok_taynik_pda6_found()
	if not has_info("strelok_taynik_pda6_found") then
		dialogs.dialog_count("strelok_taynik_pda6_found", 3)
		this.play_zvuk_ts6()
	end
end

function strelok_taynik_pda7_found()
	if not has_info("strelok_taynik_stop") then 
		give_info("strelok_taynik_pda7_found")
		if has_info("strelok_taynik_pda0_start") and not has_info("strelok_taynik_pda0_done") then 
			local obj = create("s_inventory_box0",xyz(-7.4699913978577,33.87616333008,-28.289289703369),9159,2027)
			map_spot(obj.id, "treasure", "Cache")
			sms("Received a tip on the cache", nil, nil, 10000)
		end
	end
end

function stdt1_found()
	local obj = create("y_inventory_box1",xyz(37.365467071533,4.3789763450623,-46.555194854736),220653,1091)
	map_spot(obj.id, "treasure", "Cache")
	sms("Received a tip on the cache", nil, nil, 10000)
	give_info("stdt1_found")
end

function play_zvuk_ts6()
	if has_info("strelok_taynik_pda6_found3") then
		this.play_zvuk_ts6_3()
		local obj = create("s_inventory_box6",xyz(-177.86285400391,48.186073303223,-538.17407226563),130423,3088)
		map_spot(obj.id, "treasure", "Cache")
		sms("Received a tip on the cache", nil, nil, 10000)
		give_info("strelok_taynik_pda6_found")
	elseif has_info("strelok_taynik_pda6_found2") then 
		this.play_zvuk_ts6_2()
	elseif has_info("strelok_taynik_pda6_found1") then 
		this.play_zvuk_ts6_1()
	end
end
function play_zvuk_ts6_1() 
  	say([[monsters\crow\idle_0]])
end
function play_zvuk_ts6_2() 
  	say([[monsters\crow\idle_2]])
end
function play_zvuk_ts6_3() 
  	say([[monsters\crow\idle_1]])
end

function kostya_taynik_pda1_found()
	local obj = create("t_inventory_box1_5",xyz(96.974411010742,11.827695846558,42.394226074219),206874,2222)
	map_spot(obj.id, "treasure", "Climber's Cache")
	obj = create("t_inventory_box1_4",xyz(90.680656433105,8.6427192687988,42.393600463867),201451,2222)
	map_spot(obj.id, "treasure", "Climber's Cache")
	obj = create("t_inventory_box1_3",xyz(90.678909301758,5.4578070640564,42.393135070801),201451,2222)
	map_spot(obj.id, "treasure", "Climber's Cache")
	obj = create("t_inventory_box1_2",xyz(43.849678039551,2.2733302116394,30.84397315979),155625,2225)
	map_spot(obj.id, "treasure", "Climber's Cache")
	sms("Получена наводка на тайник", nil, nil, 10000)
	taynik_spawn.t_new_inventory1_1()
	give_info("kostya_taynik_pda1_found")
end

function kostya_taynik_pda10_found()
	sms("%c[sender]"..translate("name_starii_zhil")..":\\n%c[sms_red]"..translate("kostya_taynik_pda10_found_0_0"), nil, nil, 10000, nil, [[sms\starii_zhil\kostya_taynik_pda10_found]])
	give_info("kostya_taynik_pda10_found")
end

function ktdt1_found()
	local obj = create("x_inventory_box1",xyz(-59.969673156738,11.509243011475,81.595413208008),41679,2208)
	map_spot(obj.id, "treasure", "Cache")
	sms("Received a tip on the cache", nil, nil, 10000)
	give_info("ktdt1_found")
end

function ktdt2_found()
	give_info("ktdt2_found")
end

function ktdt3_found()
	give_info("ktdt3_found")
end

function bitvakl_done()
	give_info("bitvakl_done")
end

-- взносы
function vzn12_restr()
	give_info("vzn_temp1")
end

function tm_sr1_do()
	release_teleport("tm_teleport_1")
	release_teleport("tm_teleport_2")
	local se_obj = create("tm_teleport_2_1",xyz(3.8692383766174,83.598213195801,6.2937459945679),3107,2417)
	set_value("tm_teleport_2_1", se_obj.id)		  
	se_obj = create("tm_teleport_2_2",xyz(47.255016326904,83.597991943359,6.3332266807556),8323,2417)
	set_value("tm_teleport_2_2", se_obj.id)		  
	spawn_restrictor.tm_sr2()
	give_info("tm_find_sr1")
end
function tm_sr2_do()
	release_teleport("tm_teleport_2_1")
	release_teleport("tm_teleport_2_2")
	se_obj = create("tm_teleport_3",xyz(100.69927215576,65.480911254883,-40.074703216553),7836,2417)
	set_value("tm_teleport_3", se_obj.id)		  
	spawn_restrictor.tm_sr3()
	give_info("tm_find_sr2")
end
function tm_sr3_do()
	release_teleport("tm_teleport_3")
	sms("%c[sender]"..translate("name_dragunov")..":\\n%c[sms_red]"..translate("tm_sr3_do_0_0"), nil, "dragunof", 10000, nil, [[sms\dragunov\tm_sr3_do]])
	local se_obj = create("tm_teleport_3",xyz(100.75973510742,65.48218536377,10.895936012268),6048,2417)
	set_value("tm_teleport_3", se_obj.id)		  
	spawn_restrictor.tm_sr4()
	give_info("tm_find_sr3")
end
function tm_sr4_do()
	release_teleport("tm_teleport_3")
	sms("%c[sender]"..translate("name_dragunov")..":\\n%c[sms_red]"..translate("tm_sr4_do_0_0"), nil, "dragunof", 10000, nil, [[sms\dragunov\tm_sr4_do]])
	local se_obj = create("tm_teleport_4",xyz(5.685697555542,66.706192016602,37.231788635254),3443,2417)
	set_value("tm_teleport_4", se_obj.id)		  
	give_info("tm_find_sr4")
end

-- "универсальная" функция спавна ТП
-- spawn_nano_tel(p), где p соотв. нужной строке таблицы в volazar_tbl_tel.script
function spawn_nano_tel(actor, npc, p)
    local v = volazar_tbl_tel["volazar_tel"]()
	local a = v[p[1]]
      volazar_tbl_tel.volazar_nano_tel(a.s, a.x, a.y, a.z, a.gv, a.lv)
end

-- "универсальная" функция спавна рестриктора
-- spawn_nano_restr(p), где p соотв. нужной строке таблицы в volazar_tbl_restr.script
function spawn_nano_restr(actor, npc, p)
    local v = volazar_tbl_restr["volazar_restr"]()
	local a = v[p[1]]
      volazar_tbl_restr.volazar_nano_restr(a.x, a.y, a.z, a.gv, a.lv, a.lg, a.sz)
end

-- "универсальная" функция спавна предмета
-- spawn_nano_stash(p), где p соотв. нужной строке таблицы в volazar_spawn_other.script
function spawn_nano_stash(actor, npc, p)
    local v = volazar_spawn_other["volazar_other"]()
	local a = v[p[1]]
      volazar_spawn_other.vso(a.s, a.x, a.y, a.z, a.gv, a.lv)
end

-- Oksana579 biorobot
function sms_fritz_code()
  sms("%c[green]"..translate("name_strelok")..":\\n%c[255,255,255,0]"..translate("sms_code"), 0, nil, 20000)
  give_info("info_biorobot_message_send")
end

function nemec_vrag(community1, community2) 
relation_registry.set_community_goodwill ("dolg", "actor", -2000) 
end
-- Oksana579 biorobot end

function play_anim(actor, npc, p)
	if not p or not p[1] then return end
	npc:play_cycle(p[1], true)
end

--======================= Шахматист 2 =======================--

function chess_sleeping()
	return chess.sleeping()
end
-- зажигаем костры
function light_up_campfire(actor, npc)
 local obj = alife():create("zone_flame_small", npc:position() , npc:level_vertex_id(), npc:game_vertex_id())
 if db.actor:dont_has_info("info_light_up_campfire_2") then
  level.map_remove_object_spot(npc:id(), "green_location")
 end
end
-- телепорт
function jup_elza_teleport()
 level.add_pp_effector ("teleport.ppe", 2006, false)
 db.actor:set_actor_position(vector():set(-396.41137695313,11.416479110718,-9.0520620346069),50635,3708)
 db.actor:set_actor_direction(-(vector():set(-0.998,0,0.044)):getH())
end
-- белая вспышка
function vizov_efect_1()
level.add_pp_effector("teleport.ppe", 2007, false)
end
-- гашение экрана
function vizov_efect_3()
level.add_pp_effector("radar_wake.ppe", 2007, false)
end
-- цветной экран
function vizov_efect_5()
level.add_pp_effector("proba_test.ppe", 2007, false)
end
-- обзор бара
function vizov_efect_2()
level.add_cam_effector("camera_effects\\cut_scene1.anm", 25, false, "")
end
-- землетрясение
function vizov_efect_4()
level.add_cam_effector("camera_effects\\earthquake.anm", 25, false, "")
end
-- белая вспышка молнии
function vizov_efect_6()
level.add_pp_effector("blink.ppe", 2007, false)
end
-- Прометей
function bomb_detonate()
 local h = hit()
 h.power = 1000
 h.impulse = 0
 h.draftsman = db.actor
 h.direction = vector():set(0,0,0)
 h.type = hit.fire_wound

 for i = 1, 65534 do
  local obj = level.object_by_id(i)
  if obj and obj:section() == "chess_bomb_set" then
   obj:hit(h)
  end
 end
end

function bomb_no_spot(actor, restr)
 level.map_remove_object_spot(restr:id(), "crlc_bomb")
end

function set_bomb(actor, obj)
   local obj = alife():create("chess_bomb_set", obj:position(), obj:level_vertex_id(), obj:game_vertex_id())
end

function prometheus_death()
	local count = xr_logic.pstor_retrieve(db.actor, "prometheus", 0) + 1
	if count < 31 then
		xr_logic.pstor_store(db.actor, "prometheus", count)
	else
		db.storage[db.actor:id()].pstor["prometheus"] = nil
		db.actor:give_info_portion("info_post_flashcard_done")
	end
end