Перейти к контенту

[SoC] Ковыряемся в файлах


Рекомендуемые сообщения

KURT2013. Довольно редкий вылет, с таким сталкивался когда лечил Толика и рядом тусующиеся слепыши оказались слишком близко, и реакция на них Толика вызвала этот Arguments: LUA error:state_mgr.script:145: C stack overflow. Поставил такую затычку и вроде как вылетов с подобным логом не наблюдал, но не факт, что это панацея, наверно надо искать другие причины, а не затыкать проверкой.

 

--' Эвалуатор, который синхронизирует менеджер.
--' Мы уже в безраличном состоянии idle или нет
class "evaluator_state_mgr_idle" (property_evaluator)
function evaluator_state_mgr_idle:__init(name, state_manager) super (nil, name)
	self.st = state_manager
	self.mgr = nil
end
function evaluator_state_mgr_idle:evaluate()
	local t = self.st.target_state == "idle" and 
		   --not self.st.planner:evaluator(self.st.properties["locked"]):evaluate() and
		   self.st.planner:evaluator(self.st.properties["movement"]):evaluate()	and
		   self.st.planner:evaluator(self.st.properties["animstate"]):evaluate() and
		   self.st.planner:evaluator(self.st.properties["animation"]):evaluate()

	if self.mgr == nil then
		self.mgr = self.object:motivation_action_manager()
	end

	if not self.mgr:initialized() then
		self.st.combat = false
	end

	if t == true then 
		if self.mgr:initialized() and self.mgr:current_action_id() == xr_actions_id.state_mgr + 1 then
			self.st.combat = true
		end
	end
	
	if self.st.combat == true then return true end

	return false
end

Это эвалуатор айдл комбат.

Ссылка на комментарий
45 минут назад, gam сказал:

@gam Довольно редкий вылет, с таким сталкивался когда лечил Толика и рядом тусующиеся слепыши оказались слишком близко, и реакция на них Толика вызвала этот Arguments: LUA error:state_mgr.script:145: C stack overflow. Поставил такую затычку и вроде как вылетов с подобным логом не наблюдал, но не факт, что это панацея, наверно надо искать другие причины, а не затыкать проверкой.

Спасибо за совет, попробуем пока на костылях. 

Изменено пользователем KURT2013

Pir%40t%40s.gif

Ссылка на комментарий

Еще раз здравия желаю. Решил замутить ремкомплекту убирание оружия при использовании по образцу примера с аптечкой отсюда: http://ap-pro.ru/forum/114-3951-1

Функцию прописал, коллбэки прописал, вызовы прописал. При использовании в игре вылет с логом:

Скрытый текст

Expression    : fatal error
Function      : CScriptEngine::lua_error
File          : E:\stalker\sources\trunk\xr_3da\xrGame\script_engine.cpp
Line          : 73
Description   : <no expression>
Arguments     : LUA error: ....r. shadow of chernobyl\gamedata\scripts\xr_s.script:57: table index is nil

Не могу понять, что ему, окаянному, в этой 57 строчке не нравится.

Вот bind_stalker:

Скрытый текст

function init    (obj)
    xr_motivator.AddToMotivator(obj)
end

function actor_init    (npc)
    npc:bind_object(actor_binder(npc))
end

local game_difficulty_by_num = {
    [0] = "gd_novice",
    [1] = "gd_stalker",
    [2] = "gd_veteran",
    [3] = "gd_master"
    }

lasthealth  = 0
lasttime    = 0
post_process = 0
local weapon_hide = false
----------------------------------------------------------------------------------------------------------------------
class "actor_binder" (object_binder)
----------------------------------------------------------------------------------------------------------------------
function actor_binder:__init (obj) super(obj)
    self.bCheckStart = false
    self.weather_manager = level_weathers.WeatherManager()
    self.actor_detector = xr_detector.actor_detector()
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:net_spawn(data)
    printf("actor net spawn")        

    level.show_indicators()

    self.bCheckStart = true
    self.weapon_hide = false -- спрятано или нет оружие при разговоре.
    weapon_hide = false -- устанавливаем глобальный дефолтовый флаг.

    if object_binder.net_spawn(self,data) == false then
        return false
    end

    db.add_actor(self.object)
    
    if self.st.disable_input_time == nil then
        level.enable_input()
    end

    self.weather_manager:reset()
--    game_stats.initialize ()

    if(actor_stats.add_to_ranking~=nil)then
        actor_stats.add_to_ranking(self.object:id())
    end

    --' Загружаем настройки дропа
    death_manager.init_drop_settings()

    return true
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:net_destroy()
    if(actor_stats.remove_from_ranking~=nil)then
        actor_stats.remove_from_ranking(self.object:id())
    end
--    game_stats.shutdown ()
    db.del_actor(self.object)

    sr_light.clean_up ()

    self.object:set_callback(callback.inventory_info, nil)
    self.object:set_callback(callback.article_info, nil)
    self.object:set_callback(callback.on_item_take, nil)
    self.object:set_callback(callback.on_item_drop, nil)
    --self.object:set_callback(callback.actor_sleep, nil)
    self.object:set_callback(callback.task_state, nil)
    self.object:set_callback(callback.level_border_enter, nil)
    self.object:set_callback(callback.level_border_exit, nil)
    self.object:set_callback(callback.take_item_from_box, nil)
    self.object:set_callback(callback.use_object, nil)
    

    if sr_psy_antenna.psy_antenna then
        sr_psy_antenna.psy_antenna:destroy()
        sr_psy_antenna.psy_antenna = false
    end

    xr_sound.stop_all_sound_object()

    object_binder.net_destroy(self)
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:reinit()
    object_binder.reinit(self)
    
    local npc_id = self.object:id()

    db.storage[npc_id] = { }

    self.st = db.storage[npc_id]
    self.st.pstor = nil

    self.next_restrictors_update_time = -10000

    self.object:set_callback(callback.inventory_info, self.info_callback, self)
    self.object:set_callback(callback.article_info, self.article_callback, self)
    self.object:set_callback(callback.on_item_take, self.on_item_take, self)
    self.object:set_callback(callback.on_item_drop, self.on_item_drop, self)
    self.object:set_callback(callback.trade_sell_buy_item, self.on_trade, self) -- for game stats
    --self.object:set_callback(callback.actor_sleep, self.sleep_callback, self)
    self.object:set_callback(callback.task_state, self.task_callback, self)
    --self.object:set_callback(callback.map_location_added, self.map_location_added_callback, self)
    self.object:set_callback(callback.level_border_enter, self.level_border_enter, self)
    self.object:set_callback(callback.level_border_exit, self.level_border_exit, self)
    self.object:set_callback(callback.take_item_from_box, self.take_item_from_box, self)
    self.object:set_callback(callback.use_object, self.use_obj, self)
    self.object:set_callback(callback.use_object, self.use_inventory_item, self)
end
----------------------------------------------------------------------------------------------------------------------

function actor_binder:take_item_from_box(box, item)
    local story_id = box:story_id()
    if story_id == nil then
        return
    end

    treasure_manager.take_item_from_box(box, story_id)
--[[    
    local respawner = se_respawn.get_respawner_by_parent(story_id)
    if respawner == nil then
        return
    end
    
    --' Необходимо уменьшить счетчик в респавнере
    respawner:remove_spawned(item:id())

    local smart_terrain = db.strn_by_respawn[respawner:name()]
    if smart_terrain == nil then
        return
    end

    local npc = smart_terrain.gulag:get_nearest_online_obj(db.actor:position())
    if npc ~= nil then
        xr_sound.set_sound_play(npc, "reac_box")
        xr_gulag.setGulagEnemy(smart_terrain:name() , db.actor)        
    end
]]
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:level_border_enter(npc, info_id)
    self.actor_detector:actor_enter()
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:level_border_exit(npc, info_id)
    self.actor_detector:actor_exit()
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:info_callback(npc, info_id)
    printf("*INFO*: npc='%s' id='%s'", npc:name(), info_id)
    --' Сюжет
    level_tasks.proceed(self.object)
    -- Отметки на карте
    level_tasks.process_info_portion(info_id)
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:on_trade (item, sell_bye, money)
    if sell_bye == true then
       game_stats.money_trade_update (money)
    else       
       game_stats.money_trade_update (-money)
    end   
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:article_callback(npc, group, name)
    --printf("article_callback [%s][%s]", group, name)
    if device().precache_frame >1 then return end
    
    if group == "Diary" then
        news_manager.send_encyclopedy("diary", group)
    else
        news_manager.send_encyclopedy("encyclopedy", group)
    end
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:on_item_take (obj)
    level_tasks.proceed(self.object)
    --game_stats.update_take_item (obj, self.object)
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:on_item_drop (obj)
    level_tasks.proceed(self.object)
    --game_stats.update_drop_item (obj, self.object)
end
----------------------------------------------------------------------------------------------------------------------
local item_ = {["medkit"] = true, ["medkit_army"] = true, ["medkit_scientic"] = true,}
function actor_binder:use_obj(obj)
    main_sleep.sleep(obj)
    exp_mod.itemuse(obj)
    if item_[obj:section()] then
        medicine.Rehabilitation(obj)
    end
end
----------------------------------------------------------------------------------------------------------------------

function actor_binder:task_callback(_task, _objective, _state)
    task_manager.task_callback(_task:get_id(), _objective:get_idx(), _state)
    if _objective:get_idx() == 0 then
        if _state == task.fail then
            news_manager.send_task(db.actor, "fail", _task, _objective)
        elseif _state == task.completed then
            task_manager.reward_by_task(_task)
            news_manager.send_task(db.actor, "complete", _task, _objective)
        else
            news_manager.send_task(db.actor, "new", _task, _objective)
        end
    else
        if _task:get_objective(0):get_state() == task.in_progress then
            news_manager.send_task(db.actor, "update", _task, _objective)
        end
    end
end

----------------------------------------------------------------------------------------------------------------------
function actor_binder:map_location_added_callback(spot_type_str, object_id)
    if (false==app_ready()) or (device().precache_frame>1) then return end
    --'news_manager.send_task(db.actor, "new")
end
----------------------------------------------------------------------------------------------------------------------

function actor_binder:use_inventory_item(obj)
    main_sleep.sleep(obj)
    if string.find(obj:section(), "repair_kit") then
        xr_s.register_callback("update", exp_mod.repair_kit_using, {time_global(), 4000})
    end
    exp_mod.itemuse(obj)
    exp_mod.use_snd(obj)
    use_item.CheckSection(obj:section())
end

function actor_binder:update(delta)

xr_s.on_actor_update(delta)

    object_binder.update(self, delta)


    -- DEBUG slowdown
--    slowdown.update()

    local time = time_global()
    
    game_stats.update (delta, self.object)

    -- апдейт погоды
    self.weather_manager:update()
    
    -- апдейт схемы детектора
    self.actor_detector:update()

    -- апдейт звуковой схемы актера
    xr_sound.update_actor()
    
    --' Проверка потери жизни
--[[
    if self.object.health - lasthealth > 0.001 or
       self.object.health - lasthealth < -0.001 then
        printf("%f | %f", self.object.health, self.object.health - lasthealth, game.time() - lasttime)
        lasthealth = self.object.health
        lasttime = game.time()
    end
]]    
    -- Обновление отключения ввода с клавиатуры.
    if self.st.disable_input_time ~= nil and
       game.get_game_time():diffSec(self.st.disable_input_time) >= self.st.disable_input_idle
    then
        level.enable_input()
        self.st.disable_input_time = nil
    end
    -- Обновление сна с переносом чувака в указанную позицию
    if self.st.sleep_relocate_time ~= nil and
       game.get_game_time():diffSec(self.st.sleep_relocate_time) >= self.st.sleep_relocate_idle
    then
        self.object:set_actor_position(self.st.sleep_relocate_point)
        local dir = self.st.sleep_relocate_point:sub(self.st.sleep_relocate_look)
        self.object:set_actor_direction(dir:getH())
        self.st.sleep_relocate_time = nil
    end

    -- Апдейт прятание оружия игрока во время диалога
    if weapon_hide == true or self.object:is_talking() then
        if self.weapon_hide == false then
            self.object:hide_weapon()
            self.weapon_hide = true
        end
    else
        if self.weapon_hide == true then
            self.object:restore_weapon()
            self.weapon_hide = false
        end
    end    

    -- обновление рестрикторов, которые под логикой, срабатывает через интервалы времени
    if self.next_restrictors_update_time < time then
        bind_restrictor.actor_update(delta)

        self.next_restrictors_update_time = time + 200

        task_manager.actor_update()
    end

    -- обновление постпроцессов
    if post_process ~= 0 then
        if post_process:update () == true then
           post_process = 0
        end
    end

    -- обновление пси-антенны
    if sr_psy_antenna.psy_antenna then
        sr_psy_antenna.psy_antenna:update(delta)
    end

    --' Вывод сообщения о большой радиации
    if self.object.radiation >= 0.7 then
        local hud = get_hud()
        local custom_static = hud:GetCustomStatic("cs_radiation_danger")
        if custom_static == nil then
            hud:AddCustomStatic("cs_radiation_danger", true)
            hud:GetCustomStatic("cs_radiation_danger"):wnd():SetTextST("st_radiation_danger")
        end
    else
        local hud = get_hud()
        local custom_static = hud:GetCustomStatic("cs_radiation_danger")
        if custom_static ~= nil then
            hud:RemoveCustomStatic("cs_radiation_danger")
        end
    end

 

     if self.bCheckStart then
        printf("SET DEFAULT INFOS")        

        if not has_alife_info("storyline_actor_start") and
           (level.name() == "l01_escape")
        then
            self.object:give_info_portion("storyline_actor_start")
            _G.g_start_avi = true
            printf("*AVI* RUN START AVI")            
        end

--        if not has_alife_info("encyclopedy") then
--            self.object:give_info_portion("encyclopedy")
--        end

        if not has_alife_info("global_dialogs") then
            self.object:give_info_portion("global_dialogs")
        end

        if not has_alife_info("level_changer_icons") then
            self.object:give_info_portion("level_changer_icons")
        end

        level_tasks.add_lchanger_location()

        self.bCheckStart = false        
    end

    if start_add_spawn.load_variable("spawn_test",false)==false then
    start_add_spawn.spawn_test()
    start_add_spawn.save_variable("spawn_test",true)
    end
        
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:save(packet)
    
    local save_treasure_manager = true
    
    printf("actor_binder:save(): self.object:name()='%s'", self.object:name())
    object_binder.save(self, packet)

    --' Сохраняем уровень сложности
    if save_treasure_manager == true then
        packet:w_u8(level.get_game_difficulty() + 128)
    else
        packet:w_u8(level.get_game_difficulty())
    end


    --' Сохраняем данные об отключенном вводе
    if self.st.disable_input_time == nil then
        packet:w_bool(false)
    else
        packer:w_bool(true)
        utils.w_CTime(packet, self.st.disable_input_time)
    end

    xr_logic.pstor_save_all(self.object, packet)
    self.weather_manager:save(packet)

    sr_psy_antenna.save( packet )
    
    if save_treasure_manager == true then
        treasure_manager.save(packet)      
    end                                  

    task_manager.save(packet)
    self.actor_detector:save(packet)    
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:load(reader)
    printf("actor_binder:load(): self.object:name()='%s'", self.object:name())
    object_binder.load(self, reader)
    printf("actor_binder:object_binder.load(): self.object:name()='%s'", self.object:name())

    --' Загружаем уровень сложности
    local game_difficulty = reader:r_u8()
    
    local load_treasure_manager = false      
    if game_difficulty >= 128 then           
        game_difficulty = game_difficulty - 128
        load_treasure_manager = true           
    end                                      

    
    get_console():execute("g_game_difficulty "..game_difficulty_by_num[game_difficulty])

    if reader:r_eof() then
        abort("SAVE FILE IS CORRUPT")
    end

    local stored_input_time = reader:r_u8()
    if stored_input_time == true then
        self.st.disable_input_time = utils.r_CTime(reader)
    end

    xr_logic.pstor_load_all(self.object, reader)
    self.weather_manager:load(reader)

    sr_psy_antenna.load(reader)
    
    if load_treasure_manager == true then
        treasure_manager.load(reader)      
    end                                  

    
    task_manager.load(reader)
    self.actor_detector:load(reader)    
end
----------------------------------------------------------------------------------------------------------------------

--старт префетча звуков
--if string.find(command_line(), "-noprefetch") == nil then
--    sound_prefetch.prefetch_sounds()
--end


-- Weapon functions
function hide_weapon()
    weapon_hide = true
end
function restore_weapon()
    weapon_hide = false
end

// this is test for section iteration
/**
local function test_section_iteration(file_name, section_name)
    printf            ("file    : %s",file_name)
    printf            ("section : %s",section_name)
    
    local            file = ini_file(file_name)
    local            n = file:line_count(section_name)
    printf            ("lines   : %d",n)
    
    local            id, value = "", "", result
    for i=0,n-1 do
        result, id, value    = file:r_line(section_name,i,"","")
        printf        ("line %d : %s = %s",i,id,value)
    end
end


test_section_iteration("system.ltx","space_restrictor")
/**/

Вот скрипт ремнабора с функцией:

Скрытый текст

function itemuse(what)
     local obj_name = what:name()
    if (string.find(obj_name, "repair_kit")) then
        use_repair_kit(what)
    end
end
 
------------------------------------------------------------------------
--- Собственно процесс использования набора
------------------------------------------------------------------------
function use_repair_kit(what)
    local repair_slot_num = 0
 
    local item_in_slot_1 = db.actor:item_in_slot(1)
    local item_in_slot_2 = db.actor:item_in_slot(2)
    local item_in_slot_6 = db.actor:item_in_slot(6)
 
    if (item_in_slot_1 ~= nil) then
        repair_slot_num = 1
    end
 
    if (item_in_slot_2 ~= nil) then
        if (repair_slot_num == 0) then
            repair_slot_num = 2
        elseif (repair_slot_num == 1) then
            if (item_in_slot_1:condition() > item_in_slot_2:condition()) then
                repair_slot_num = 2
            end
        end
    end
 
    if (item_in_slot_6 ~= nil) then
        if (repair_slot_num == 0) then
            repair_slot_num = 6
        elseif  (repair_slot_num == 1) then
            if (item_in_slot_1:condition() > item_in_slot_6:condition()) then
                repair_slot_num = 6
            end
        elseif  (repair_slot_num == 2) then
            if (item_in_slot_2:condition() > item_in_slot_6:condition()) then
                repair_slot_num = 6
            end
        end
    end
 
    if (repair_slot_num == 1) then
        local rep_point = item_in_slot_1:condition() + 10
        if (rep_point > 1) then
            rep_point = 1
        end
        item_in_slot_1:set_condition(rep_point)
    elseif (repair_slot_num == 2) then
        local rep_point = item_in_slot_2:condition() + 10
        if (rep_point > 1) then
            rep_point = 1
        end
        item_in_slot_2:set_condition(rep_point)
    elseif (repair_slot_num == 6) then
        local rep_point = item_in_slot_6:condition() + 10
        if (rep_point > 1) then
            rep_point = 1
        end
        item_in_slot_6:set_condition(rep_point)
    end
end

local tSound ={
repair_kit = "item_sounds\\inv_repair_kit"
}

function use_snd(obj)
    if obj and tSound[obj:section()] then
    local snd = xr_sound.get_safe_sound_object(tSound[obj:section()])
        if snd then
        snd:play_no_feedback(db.actor, sound_object.s2d, 0, vector(), 2.0)
        end
    end

function repair_kit_using(userObj)
       --# Прячем оружие.
          bind_stalker.hide_weapon()
          --# Проверим работает ли ещё таймер?
          --# userObj[1] - время начала работы таймера;
          --# userObj[2] - время работы таймера (мсек)
          if time_global() > userObj[1] + userObj[2] then
           --# Работа таймера закончена - покажем оружие.
           bind_stalker.restore_weapon()
    xr_s.unregister_callback("update", exp_mod.repair_kit_using)
          end
end

end

И вот xr_s с отметкой, где ругается:

Скрытый текст

-- Вспомогательная функция инициализации модуля.
-- Проверяет наличие скрипта с имененм module и вызывает module.init()
local function init_module_if_exists(module)
  if _G[module] and _G[module].init then
    _G[module].init()
  else
    warning("init_module_if_exists: cannot find module "..module)
  end
end

-- Эта функция вызывается при старте игры. Необходимо дать возможность модулям зарегистрировать коллбэки.
function init()
  -- init_module_if_exists("xrs_dyn_weather")
  init_module_if_exists("xrs_dyn_music")
  -- init_module_if_exists("xrs_debug")
end


----------callbacks-----------

local callbacks={
    update={},
    game_load={},
    death={},
    npc_death={},
    monster_death={},
    offline_death={},
    net_spawn={},
    net_destroy={},
    info={},
    item_drop={},
    item_take={},
    item_take_from_box={},
    hit={},
    monster_hit={},
    npc_hit={},
    enemy_see_actor={},
    actor_see_enemy={},
    npc_shot_actor={},
    respawn={},
    use={},
    actor_destroy={},
    main_menu_on={},
    main_menu_off={}
}

function register_callback(name,func,userobj)
  if callbacks[name]==nil then
    abort("register_callback: callback name '%s' is unknown.",name)
  end
  callbacks[name][func]={userobj=userobj} -- Чтобы можно было регистрировать каллбэки с userobj==nil  <-------- РУГАЕТСЯ НА ЭТУ СТРОКУ
end

function unregister_callback(name,func)
  if callbacks[name]==nil then
    abort("register_callback: callback name '%s' is unknown.",name)
  end
  callbacks[name][func]=nil
end

function on_actor_update(delta)
  for func,o in pairs(callbacks.update) do
    func(o.userobj,delta)
  end
end

function on_game_load()
  if db.storage[db.actor:id()].pstor == nil then
    db.storage[db.actor:id()].pstor = {}
  end
    math.randomseed (device():time_global())
  for func,o in pairs(callbacks.game_load) do
    func(o.userobj)
  end  
end

function on_actor_destroy()
  for func,o in pairs(callbacks.actor_destroy) do
    func(o.userobj)
  end  
end

-- Ударили монстра или сталкера
local function on_hit(obj, amount, local_direction, who, bone_index)
  for func,o in pairs(callbacks.hit) do
    func(o.userobj,obj,amount,local_direction,who,bone_index)
  end
end

function on_npc_hit(obj, amount, local_direction, who, bone_index)
  for func,o in pairs(callbacks.npc_hit) do
    func(o.userobj,obj,amount,local_direction,who,bone_index)
  end
  on_hit(obj,amount,local_direction,who,bone_index)
end

function on_monster_hit(obj, amount, local_direction, who, bone_index)
  for func,o in pairs(callbacks.monster_hit) do
    func(o.userobj,obj,amount,local_direction,who,bone_index)
  end
  on_hit(obj,amount,local_direction,who,bone_index)
end

-- проверка на видимость производится раз в секунду
function on_enemy_see_actor(obj,typ)
  for func,o in pairs(callbacks.enemy_see_actor) do
    func(o.userobj,obj,typ)
  end
end
function on_actor_see_enemy(obj,typ)
  for func,o in pairs(callbacks.actor_see_enemy) do
    func(o.userobj,obj,typ)
  end
end

-- непись стрелял в гг
function on_npc_shot_actor(obj)
  for func,o in pairs(callbacks.npc_shot_actor) do
    func(o.userobj,obj)
  end
end

function on_main_menu_on()
  for func,o in pairs(callbacks.main_menu_on) do
    func(o.userobj)
  end
end

function on_main_menu_off()
  for func,o in pairs(callbacks.main_menu_off) do
    func(o.userobj)
  end
end

function on_item_drop(obj)
  for func,o in pairs(callbacks.item_drop) do
    func(o.userobj,obj)
  end
end

-----------methods-----------

--записываем переменную
function save_variable(vn, value)
  if value==nil then
    del_variable(vn)
  else
    xr_logic.pstor_store(db.actor, vn, value)
  end
end

--загружаем переменную
function load_variable(vn, value_if_not_found)
  return xr_logic.pstor_retrieve(db.actor, vn, value_if_not_found)
end

--удаляем переменную
function del_variable(vn)
  if db.storage[db.actor:id()].pstor[vn] then
    db.storage[db.actor:id()].pstor[vn] = nil
  end
end

function warning(msg,...)
  log(string.format(msg,...))
end

function notice(msg,...)
  log(string.format(msg,...))
  if xrs_debug.debug_on then
    get_console():execute("flush")
  end
end

--выпарсиваем секцию инифайла в табличку
function parse_ini_section_to_array(ini,section)
    local tmp=nil
    if ini and ini:section_exist(section) then
        tmp={}
        local result, id, value = nil, nil, nil
        for a=0,ini:line_count(section)-1 do
            result, id, value = ini:r_line(section,a,"","")
            if id~=nil and trim(id)~="" and trim(id)~=nil then
                tmp[trim(id)]=trim(value)
            end
        end
    end
    return tmp
end

--обрезаем пробельные символы в начале и в конце строки
function trim (s)
    return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
end

--разбиваем строку по разделителям
function str_explode(div,str,clear)
    local t={}
    local cpt = string.find (str, div, 1, true)
    if cpt then
        repeat
            if clear then
                table.insert( t, trim(string.sub(str, 1, cpt-1)) )
            else
                table.insert( t, string.sub(str, 1, cpt-1) )
            end
            str = string.sub( str, cpt+string.len(div) )
            cpt = string.find (str, div, 1, true)
        until cpt==nil
    end
    if clear then
        table.insert(t, trim(str))
    else
        table.insert(t, str)
    end
    return t
end

Объясните, люди добрые, шо ему нужно.

Ссылка на комментарий

SWEAW. Похоже вы забыли в модуле xr_s зарегистрировать свой калбек use_object в таблице local callbacks. Имхо.

Возможно я ошибаюсь, но модуль на мой взгляд сомнений не вызывает.:)

Ссылка на комментарий
36 минут назад, gam сказал:

забыли в модуле xr_s зарегистрировать свой калбек use_object в таблице local callbacks

На всякий случай зарегистрировал, вылет с таким же логом, только ошибка теперь, ессно, на строчку ниже.
Меня вот еще почему это так напрягает: до этого адаптировал мод на медленную медицину, который использует те же вызовы\отзывы коллбэков, но там все работает.

Вот его скрипт:

Скрытый текст

-- -------------------------------------------------- --
-- -------------- MEDICINE RC ver. 1.0 -------------- --
-- -------------------------------------------------- --
-- Модуль с реакциями на использование "съедобных" предметов.
--   Убирание оружия при использовании;
--   Медленное восстановление параметров;
--   Запрет на использование подряд нескольких предметов (аптечки, бинт, антирад);
--   Прерывание восстановления здоровья при получении критического хита;
-- -------------------------------------------------- --
-- Create by ColR_iT
-- 25/03/2013
-- Update: 04/07/2013
-- Thanks: Charsi, Gun12, malandrinus
-- -------------------------------------------------- --
-- -------------------------------------------------- --
-- NOTE:
-- Для работы требуется xr_s.script за авторством xStream. (Я использовал от ЗП 1.6.0.2)
-- -------------------------------------------------- --

-- -------------------------------------------------- --
-- НАСТРАЕВЫЕМЫЕ ПАРАМЕТРЫ
-- -------------------------------------------------- --
-- Вкл/Выкл убвирание оружия.
local hide = true
-- Частота апдейта в секундах. Чем меньше, тем плавнее будет восстанавливаться параметры.
-- Не рекомендуется ставить меньше 0.1 секунды.
local refreshRate = 0.5
-- Вкл/Выкл прерывание восстановления здоровья при получении хита.
local abortHP = true
-- Значение критического хита.
local criticalValueHP = 0.15
-- Вкл/Выкл сообщение о том, что запрещено повторно использовать предмет.
local showMessage = false
-- -------------------------------------------------- --
-- Также настройке поддаются параметры в таблице itemParam расположенной ниже,
-- при этом желаетльно знать, что менять и как.
-- -------------------------------------------------- --

-- -------------------------------------------------- --
-- Кешируем актора, дабы по несколько раз не обращаться в табличку.
local actor = db.actor
-- Табичка будет хранить сколько нужно восстановить определенного паарметра
-- и как долго это нужно делать.
local restore = {
    ["health"]        = {howMuch = 0, timeRestore = 0},
    ["psy_health"]    = {howMuch = 0, timeRestore = 0},
    ["radiation"]    = {howMuch = 0, timeRestore = 0},
    ["power"]        = {howMuch = 0, timeRestore = 0},
}
-- Табличка для хранения используемых предметов.
local usingItem = {}
-- Флажок будет свидетельствовать получение критического хита.
local extraCase = 0

-- Функция обновления параметров актора.
-- Возвращает функцию, которая в зависимости от переданныз данных
-- будет восстанавливать сторого определенный параметр.
function RestoreParam()
    -- Время следующего апдейта.
    local timeUpdate = 0
    return function(data)
        -- Текущее время.
        local timeNow = time_global()
        -- Нужно ли обновлять парамтр?
        if timeNow >= timeUpdate then
            -- Вычисляем время следующего апдейта.
            timeUpdate = timeNow + refreshRate * 1000
            -- Определим получили ли мы критический хит здоровья.
            extraCase = data.lastValue and (abortHP and (data.lastValue - actor[data.nameParam] > criticalValueHP)) and -1 or 0
            -- Если вышло время...
            if (timeNow >= data.timeRestore * 1000 + data.time) or
               -- или в случае, когда обновляем здоровье, мы получили критический хит, то...
               (extraCase == -1) then
                -- убираем функцию из апдейта, обнуляем данные в табличке restore
                -- и заканчиваем обновлять кокретный параметр, переданный в качестве параметра.
                xr_s.unregister_callback("update", use_item["Restore_"..data.nameParam])
                restore[data.nameParam].howMuch = 0
                restore[data.nameParam].timeRestore = 0
                return
            end
            -- Обновляем параметр.
            actor[data.nameParam] = data.howMuch * refreshRate / data.timeRestore
            -- Запоминаем сколько ещё осталось восстановить.
            restore[data.nameParam].howMuch = restore[data.nameParam].howMuch - (data.howMuch * refreshRate / data.timeRestore)
            -- Запоминаем время, которое ещё нужно восстанавливать.
            restore[data.nameParam].timeRestore = restore[data.nameParam].timeRestore - refreshRate
            -- И в случае если восстанавливаем здоровье, запоминаем последнее значение.
            if data.lastValue then data.lastValue = actor[data.nameParam] end
        end
    end
end
-- Функция обновления здоровья.
Restore_health        = RestoreParam()
-- Функция обновления пси-здоровья.
Restore_psy_health    = RestoreParam()
-- Функция обновления радиации.
Restore_radiation    = RestoreParam()
-- Функция обновления выносливости.
Restore_power        = RestoreParam()

-- Функция блокировки для запрета повторного использования предметов.
-- Возвращает функцию, которая запрещает использование конкретного предмета,
-- в зависимости от того, что было переданно в качестве параметра.
function Ban()
    return function(data)
        -- Если время уже вышло или
        -- мы получили критический хит то...
        if time_global() >= data.time + data.timeReusing or (extraCase == -1 and data.name == "health") then
            -- отключим "блокировку" от апдейта
            -- и удалим используемый предмет из таблички, для повторного использования оного.
            xr_s.unregister_callback("update", use_item["Ban_"..data.name])
            usingItem[data.name] = nil
        end
    end
end
-- Запрет на использование аптечек.
Ban_medkit    = Ban()
-- Запрет на использование антирада.
Ban_antirad    = Ban()
-- Запрет на использование бинта.
Ban_bandage    = Ban()

-- Wondering, what it is?
local hard = false

-- Таблица с параметрами для каждого предмета.
-- Описание параметров:
-- howMuch        - сколько нужно восстановить определённого параметра;
-- timeRestore    - время, которое этот параметр нужно восстанавливать;
-- timeHideWpn    - время на которое нужно убрать оружие;
-- notRepeatUse    - запрещено использовать предмет повторно;
-- timeReusing    - время, через которое предмет можно использовать вновь;
-- sound        - звук при использовании;
local itemParam = {
-- -------------------------------------------------- --
-- Аптечки
-- -------------------------------------------------- --
    ["medkit"]            = {
        health             = {
            howMuch        = hard and ((1.0 - actor.health) * 0.25) or 0.25,
            timeRestore = 5,
        },
        psy_health        = {
            howMuch        = 0.03,
            timeRestore    = 5,
        },
        power            = {
            howMuch        = -0.1,
            timeRestore = 5,
        },
        timeHideWpn        = 4000,
        notRepeatUse    = true,
        timeReusing        = 5000,
        sound            = "inv_med",
        name            = "medkit",
    },
    ["medkit_army"]        = {
        health             = {
            howMuch        = hard and ((1.0 - actor.health) * 0.55) or 0.55,
            timeRestore = 9,
        },
        psy_health        = {
            howMuch        = 0.08,
            timeRestore    = 6,
        },
        radiation        = {
            howMuch        = hard and ((0 - db.actor.radiation) * 0.2) or -0.2,
            timeRestore = 6,
        },
        power            = {
            howMuch        = -0.15,
            timeRestore = 6,
        },
        timeHideWpn        = 4000,
        notRepeatUse    = true,
        timeReusing        = 9000,
        sound            = "inv_med",
        name            = "medkit",
    },
    ["medkit_scientic"]    = {
        health             = {
            howMuch        = hard and ((1.0 - actor.health) * 0.85) or 0.85,
            timeRestore = 14,
        },
        psy_health        = {
            howMuch        = 0.13,
            timeRestore    = 9,
        },
        radiation        = {
            howMuch        = hard and ((0 - db.actor.radiation) * 0.5) or -0.5,
            timeRestore = 9,
        },
        power            = {
            howMuch        = -0.2,
            timeRestore = 9,
        },
        timeHideWpn        = 4000,
        notRepeatUse    = true,
        timeReusing        = 14000,
        sound            = "inv_med",
        name            = "medkit",
    },
-- -------------------------------------------------- --
-- Бинт
-- -------------------------------------------------- --
    ["bandage"]            = {
        power            = {
            howMuch        = -0.25,
            timeRestore = 5,
        },
        timeHideWpn        = 4000,
        notRepeatUse    = true,
        timeReusing        = 3000,
        sound            = "inv_bandage",
        name            = "bandage",    
    },
-- -------------------------------------------------- --
-- Антирад
-- -------------------------------------------------- --
    ["antirad"]            = {
        radiation        = {
            howMuch        = -1.0,
            timeRestore = 15,
        },
        power            = {
            howMuch        = -0.3,
            timeRestore = 10,
        },
        timeHideWpn        = 3000,
        notRepeatUse    = true,
        timeReusing        = 20000,
        sound            = "inv_pills",
        name            = "antirad",
    },
-- -------------------------------------------------- --
-- Водка
-- -------------------------------------------------- --
    ["vodka"]            = {
        health             = {
            howMuch        = hard and ((1.0 - actor.health) * 0.03) or 0.03,
            timeRestore = 4,
        },
        psy_health        = {
            howMuch        = 0.15,
            timeRestore    = 9,
        },
        radiation        = {
            howMuch        = hard and ((0 - db.actor.radiation) * 0.1) or -0.1,
            timeRestore = 6,
        },
        power            = {
            howMuch        = -0.2,
            timeRestore = 9,
        },
        timeHideWpn        = 5000,
        sound            = "inv_vodka",
    },
-- -------------------------------------------------- --
-- Энергетик
-- -------------------------------------------------- --
    ["energy_drink"]    = {
        power            = {
            howMuch        = 1.0,
            timeRestore = 15,
        },
        timeHideWpn        = 3000,
        sound            = "inv_softdrink",
    },
-- -------------------------------------------------- --
-- Еда
-- -------------------------------------------------- --
    ["conserva"]        = {
        power            = {
            howMuch        = 0.2,
            timeRestore = 12,
        },
        timeHideWpn        = 4000,
        sound            = "inv_food_conserva",
    },
    ["kolbasa"]            = {
        power            = {
            howMuch        = 0.15,
            timeRestore = 10,
        },
        timeHideWpn        = 3000,
        sound            = "inv_food1",
    },
    ["bread"]            = {
        power            = {
            howMuch        = 0.1,
            timeRestore = 8,
        },
        timeHideWpn        = 3000,
        sound            = "inv_food",
    },
-- -------------------------------------------------- --
}

-- Проверяем нужный ли предмет мы использоваил.
-- Вызывать из колбека на юз актора.
function CheckSection(itemSection)
    if itemParam[itemSection] then
        use_item.Rehabilitation(itemSection)
    end
end

-- Табличка правильных окончаний текста сообщений.
local nameItem = {medkit = "й аптечки", bandage = "го бинта", antirad = "го антирада"}


local function Formula(a,b)
    return math.abs(a) < math.abs(b) and (a / 3 + b) or (b / 3 + a)
end
-- Время, на которое спрятано оружие.
local hiddenTime = 0

-- Функция для запуска нужных эффектов:
-- убирание оружия, запрет на повторное использование, медленное восстановление.
-- В качестве параметра принимает имя секции использованного предмета.
function Rehabilitation(itemSection)
    -- Хешируем табличку параметров для предмета с указанной секцией.
    local IP = itemParam[itemSection]
    
    -- Нужно ли прятать оружие и не спрятано ли оно уже?
    if hide and hiddenTime < IP.timeHideWpn then
        -- Нужно - прячим.
        xr_s.register_callback("update", use_item.HideWeapon, {timeHideWpn = IP.timeHideWpn, time = time_global()})
    end


    -- Играем звук поедания.
    PlaySound (IP.sound)


    -- Проверим какие параметры нужно восстанавливать.
    for whatRestore, paramRestore in pairs(restore) do
    -- whatRestore    - имя параметра;
    -- paramRestore    - табличка со значениями сколько и как долго восстанавливать.
        -- Проверим, а нужно ли восстанавливать параметр?
        if IP[whatRestore] then
            -- Нужно, поэтому...
            -- Определим сколько нужно восстановить
            paramRestore.howMuch = (paramRestore.howMuch ~= 0) and Formula(paramRestore.howMuch, IP[whatRestore].howMuch) or IP[whatRestore].howMuch
            -- и как долго это нужно делать.
            paramRestore.timeRestore = paramRestore.timeRestore > IP[whatRestore].timeRestore and paramRestore.timeRestore or IP[whatRestore].timeRestore
            -- Запускаем функцию восстановления определённого параметра.
            xr_s.register_callback("update", use_item["Restore_"..whatRestore], {howMuch = restore[whatRestore].howMuch, timeRestore = restore[whatRestore].timeRestore, nameParam = whatRestore, time = time_global(), lastValue = whatRestore == "health" and actor.health or nil})
        end
    end
end

-- Время, которое оружие будет спрятано.
local timeWpnUpdate = 0
-- Функция убирания оружия.
-- Обновляется раз в секунду.
function HideWeapon(data)
    -- Текущее время.
    local timeNow = time_global()
    -- Нужно ли произвести обновление?
    if timeNow >= timeWpnUpdate then
        -- Определим время следующего апдейта.
        timeWpnUpdate = timeNow + 1000
        -- Если орижие ещё не спрятано - спрячем его.
        if hiddenTime == 0 then
            bind_stalker.hide_weapon()
        end
        -- Определим время, на которое оружие будет спрятано.
        hiddenTime = data.time + data.timeHideWpn - timeNow
        -- Если время вышло или мы получили критический хит, то...
        if timeNow >= data.time + data.timeHideWpn or extraCase == -1 then
            -- восстановим оружие, убирём функцию из аптдейта и обнулим время.
            bind_stalker.restore_weapon()
            xr_s.unregister_callback("update", use_item.HideWeapon)
            hiddenTime = 0
            return
        end
    end
end

-- Функция для проигрывания звука в "голове" актора.
function PlaySound(sound)
    -- Имя папки со звуками, относительно папки gamedata\sounds.
    local soundsFolder = "item_sounds"
    local soundObj = sound_object(soundsFolder..[[\]]..sound)
    soundObj:play_no_feedback(actor, sound_object.s2d, 0, vector(), 1.0)
end
-- -------------------------------------------------- --

Просмотрел пару десятков раз на предмет отличий в вызове\отключении - так и не понял, в чем я косячу в своих функциях.

Ссылка на комментарий
1 час назад, SWEAW сказал:

function actor_binder:update(delta)

xr_s.on_actor_update(delta)

    object_binder.update(self, delta)

 

Посмотрите вашу адаптацию по тщательней. Проверил медицину и все работает, правда на чистой игре.

 

А модуль xr_s регистрировать как это у вас, я бы не рекомендовал, попробуйте сделать хоть так:

 

Бинд_сталкер скрипт.

function actor_binder:update(delta)

    object_binder.update(self, delta)

xr_s.on_actor_update(delta)

Изменено пользователем gam
  • Согласен 1
Ссылка на комментарий

Еще раз здравствуйте. Добавил в свою солянку: Stalker Map Pack 1+ "Blowout mod" + "Moon&Diary Repair Mod".

Так же добавил спальный мешок, как написано в этой статье https://yadi.sk/i/CQXOeDXI3GGA9A

И теперь возникает неприятный баг " ГГ не используя мешок, сам по себе засыпает! Иногда, даже во время боя. В чем может быть проблема?

Pir%40t%40s.gif

Ссылка на комментарий

И снова здравствуйте. Вопрос - как в ТЧ отключить автоматически выдаваемые задания (защитить сталкеров на свалке, убить наемников на дикой территории и т.п.)? В очень древней местной теме http://www.amk-team.ru/forum/topic/19-ubiraem-avtomaticheskie-kvesty/?page=1 все ссылки на файлы давно не актуальны, а в самих сообщениях никакой конкретики по редактированию файлов.

Ссылка на комментарий

Сталкеры, здравствуйте! Извините, если пишу не по теме, но хотелось бы попросить, чтобы кто-нибудь меня научил делать откат с патча 1.0006 до патча 1.0004. Вроде бы, можно вручную это как-то сделать, но насколько знаю, нужна будет папка bin от игры с патчем 1.0004, для замены. Может, найдётся у кого чистая, без изменений? И желательно, чтобы без StarForce. Уже 2 дня убил на то, чтобы самостоятельно в интернете какие-то даунгрейды и NoCD найти, но на половине сайтов либо ссылки сдохли, на другой половине туфта какая-то, после установки который либо вылеты, либо ещё чего. Очень хочется уже спокойно всё разрулить и пойти играть в новый мод.
P.S. Игра у меня лицензионная, с диска. Конечно кто-то скажет, что проще скачать SoC 1.0000 с торрента, и уже на неё 4-ый патч навернуть, но торрентами я не пользуюсь, да и смысл, когда диск есть. 

Ссылка на комментарий
Только что, Barbarian сказал:

откат с патча 1.0006 до патча 1.0004

Что-то было. Удалить bin, dbb, dbc, dbd. Потом разархивировать архив.

https://yadi.sk/d/WdlOyq1i3M3Cps

  • Спасибо 1
Ссылка на комментарий

@Barbarian Универсальный диспетчер патчей от Starter`a - https://cloud.mail.ru/public/6TA9/HYubBB2vp

Ридми в архиве, там всё просто, откат с любого на любой патч, хоть с 0 до 6, хоть обратно. Делается за 7-8 секунд.

  • Полезно 1

"Кругом зомби.....у меня кончаются патроны...."

Ссылка на комментарий

@SWEAW , в файле config/misc/task_manager.ltx закомментируй (поставь ; в начале строки) все строки с параметром init_condition.

  • Спасибо 1
  • Нравится 1
  • Согласен 1

Аддон для ОП-2.09.2: Яндекс/Google/GitHub

naxac.gif

Ссылка на комментарий

Кто знает как называется профиль бандита который сидить в разрушенном здании, перед претворяющимся бандитом? И как называется конфиг нпс на агропроме, который говорит: эй мужик помоги мне, военные собираются перебить группу Крота

Ссылка на комментарий
3 часа назад, Stalker Nest сказал:

профиль бандита который сидить в разрушенном здании, перед претворяющимся бандитом

Из character_desc_garbage.xml

 

    <specific_character id="gar_bandit_novice_wounded" team_default = "1">

 

3 часа назад, Stalker Nest сказал:

И как называется конфиг нпс на агропроме

Поясни, что понимать под словом "конфиг"?

Сталкер - наше всё!

Ссылка на комментарий
3 часа назад, Stalker Nest сказал:

И как называется конфиг нпс на агропроме, который говорит: эй мужик помоги мне, военные собираются перебить группу Крота

Называется он так

section_name = stalker
name = agr_defector_stalker1
character_profile = agr_stalker_general

 

Сразу скажу, не вздумай прописать ему любой другой ствол кроме обреза. Зависнет напрочь. Проверено - 100 %. У него анимация, именно на обрез рассчитана.

Или, если будешь спавнить другую пушку, пиши в ремарке другую анимацию. Его логика сидит в оллспавне.

  • Согласен 3
  • Полезно 1

"Кругом зомби.....у меня кончаются патроны...."

Ссылка на комментарий

И снова здравствуйте, сталкеры. Подскажите, кто в курсе, где можно (и можно ли вообще) поменять состояние выпадающего с трупов оружия? И зависит ли оно от ранга убитого сталкера, или генерируется в одном диапазоне для всех? Заранее спасибо.

Ссылка на комментарий
29 минут назад, SWEAW сказал:

состояние выпадающего с трупов оружия

death_manager.script 

найти:

"Тут надо уменьшить кондишн оружия"

  • Спасибо 1
Ссылка на комментарий
15 часов назад, BFG сказал:

Сразу скажу, не вздумай прописать ему любой другой ствол кроме обреза. Зависнет напрочь. Проверено - 100 %. У него анимация, именно на обрез рассчитана.

А кто нить разбирался как эту анимацию поправить ? Как-то не верится, что в анимации зашито намертво использование именно обреза. И это случаем не из оперы про mp_ranks.ltx ?

Ссылка на комментарий
В 14.08.2017 в 08:16, KURT2013 сказал:

добавил спальный мешок, как написано в этой статье https://yadi.sk/i/CQXOeDXI3GGA9A

 

Сделал как описано в статье, глюков вроде указанных:

 

В 14.08.2017 в 08:16, KURT2013 сказал:

 

И теперь возникает неприятный баг " ГГ не используя мешок, сам по себе засыпает! Иногда, даже во время боя. В чем может быть проблема?

 

не заметил. Если вдруг понадобиться, вот поделка по этой статье:

https://yadi.sk/d/LvUXAOqv3M67Bs

 

Проверялось на чистой ТЧ с 6 патчем.

 

  • Спасибо 1
Ссылка на комментарий

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

    • Ни один зарегистрированный пользователь не просматривает эту страницу.
×
×
  • Создать...