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

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


Halford

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

Здравствуйте, товарищи! Подскажите, будьте добры, по такому делу:
1.Ставил на чистую (с парой правок конфигов по мелочам) ТЧ 1.006 мод на ремкомплект и спальник, мод отсюда: http://stalker-gaming.ru/load/mody_stalker/ten_chernobylja/rem_komplekt_i_spalnyj_meshok/2-1-0-4209;

2.Адаптировал мод на постепенное восстановление при использовании медикаментов отсюда: http://www.amk-team.ru/forum/topic/12674-medicina/

3.Захотелось, чтобы ремкомплект тоже юзался со звуком. С этим как раз и проблема. Звук нашел, переформатнул в ogg, закинул в геймдату, тут все просто, сложность с самим скриптом. Делал все по инструкции со Сталкер Инсайда (http://stalkerin.gameru.net/wiki/index.php?title=Звук_при_использовании_предмета), через отдельный скрипт, в игре при использовании ремкомплекта ничего не происходило. Потом вставил в сам файл ремкомплекта функцию на воспроизведение звука, вызывал ее в функции использования - ноль эмоций. Помещал вызов функции в массив вызова использования спального мешка, ремкомплекта и медикаментов в бинд_сталкере - игра при использовании рема вылетала. Подскажите, кому не трудно, что делаю не так. Прилагаю ссылку на файлы скриптов bind_stalker, exp_mod (скрипт ремкоплекта), use_item (медленная медицина) и, на всякий случай, xr_s: https://yadi.sk/d/rwA-82KO3LvsKK

Название звука inv_repair_kit в папке со звуками медленной медицины item_sounds.

P.S. Заранее извиняюсь за возможные косяки в посте, зарегался специально, чтобы у знающих спросить, в остальном интернете ничего не нашел

Поделиться этим сообщением


Ссылка на сообщение
24 минуты назад, Romann сказал:

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

https://psv4.userapi.com/c816239/u84096488/docs/71e43e38e5bf/1.jpg?extra=u05X22xUvRDavw_LEDDBO-DhibCOhnDYrXxRUIQ3Ufgj9VXDbYE85BvELd_vLSbn6VgNaAIt-9x5nAS92O-dtZRgegfhd8H7WgnxxhKWNqE7zaqpiOnkOw

 

Был бы признателен, если бы указали, что по этому логу можно понять. При нажатии на сохранение или превью намертво виснет уже сам баг репортер, поэтому только инфа со скрина.

Поделиться этим сообщением


Ссылка на сообщение

Граждане, такое дело, после начала новой игры и проигрывания заставки, Сидорович молчит, задание не выдает, самому заговорить с ним нельзя, а дверь из бункера заперта. В геймдату интегрированы моды на спальник, ремкомплект, медленные аптечки и спаун непися через скрипт, все работало, недавно попытался внедрить еще и ружье бм-16, после чего, собсна, Сидор и замолчал после старта игры. Но файлы все перепроверил дважды, все вписано правильно, да и не должно ружье влиять на старт сюжета по идее. Подскажите, с чем может быть связано?

Поделиться этим сообщением


Ссылка на сообщение

Еще раз здравия желаю. Решил замутить ремкомплекту убирание оружия при использовании по образцу примера с аптечкой отсюда: 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

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

Поделиться этим сообщением


Ссылка на сообщение
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
-- -------------------------------------------------- --

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

Поделиться этим сообщением


Ссылка на сообщение

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

Поделиться этим сообщением


Ссылка на сообщение

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

Поделиться этим сообщением


Ссылка на сообщение

И снова здравствуйте. Кто знает - где лежит скрипт, отвечающий за вывод таблички с вопросом при переходе на другую локацию? Прошерстил почти все файлы папки scripts по названию строки с "Перейти на другую локацию?" - ноль эмоций.

Поделиться этим сообщением


Ссылка на сообщение

Ребят, что за жесть вообще. Скряге упорно не желает прописываться бесконечное количество денег, как у остальных торгашей. И в НПСшных параметрах его ковырялся, и в параметрах его, как торгаша - один хрен у него только эти злосчастные 5000 на руках. Баг или все-таки правится как-то?

Поделиться этим сообщением


Ссылка на сообщение

@UnLoaded И в деск_милитари и в деск_свобода прописал <money min="100000" max="100000" infinitive="1"/> после ранга и репутации. В игре в окошке торговли с ним у него в деньгах отображается "--", аля бесконечность, только вот при попытке продать ему что-то дороже 5к пишет "у НПС недостаточно денег".

Поделиться этим сообщением


Ссылка на сообщение

@gam Что с новой игры, что с других сейвов - то же самое. Отображаться бесконечность отображается, но на деле больше 5000 у него нет.

Поделиться этим сообщением


Ссылка на сообщение
1 час назад, Romann сказал:

и в оллспавне прописать

Если дело в этом, то тут я бессилен. Пробовал различные версии компила\декомпила оллспавна, ни одна в упор архив не видит, или видит, но не хочет распаковывать. Все делал по инструкции(ям), так что что-то, скорее всего, с системой. Да и потом решил, что стоит попробовать адаптировать максимум наработок, не использующих оллспавн.

Поделиться этим сообщением


Ссылка на сообщение

Иии снова здравия желаю, мелочный вопросик. Где лежит функция, отвечающая за вывод на экран советов в самом начале игры (аля, чтобы достать бинокль нажмите 5 и т.д., текстовый туториал, проще говоря), и от чего она зависит, от времени или от попадания ГГ в определенную зону на локации?

Поделиться этим сообщением


Ссылка на сообщение

Господа, а есть где функция, моментально "перематывающая" игровое время на сколько нужно вперед? Допустим, в диалоге с проводником вызвал функцию смены уровня, но по игровому времени получается, что он доводит меня до места моментально, а это как-то не комильфо.

Поделиться этим сообщением


Ссылка на сообщение
19 минут назад, Romann сказал:

в схеме сна.

Я там уже искал, функция оттуда либо перематывает время до бесконечности при смене локации, либо, если использовать стоппер, останавливает его насовсем, без прибавки.

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

main_sleep.script

 

...

 

function starter(scale) -- скрипт перемотки на нужное время
    local factor = scale * 2650 -- вычисление времени "пробуждения"
    game.start_tutorial("time_scaling") -- вызов функции перемотки
    level.set_time_factor(factor) -- собственно сама перемотка
end

 

function dreamer() -- отвечает за сны
    level.set_time_factor(basic_time_factor) --остановка перемотки.

...

Это функции от спального мешка. Сначала попытался просто подредачить starter:

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

function time() -- скрипт перемотки на нужное время
    local factor = 1 * 2650 -- вычисление времени "пробуждения"
    game.start_tutorial("time_scaling") -- вызов функции перемотки
    level.set_time_factor(factor) -- собственно сама перемотка
end

При смене локации время перематывалось бесконечно. Решил объединить с куском dreamer'а:

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

function time() -- скрипт перемотки на нужное время
    local factor = 1 * 2650 -- вычисление времени "пробуждения"
    game.start_tutorial("time_scaling") -- вызов функции перемотки
    level.set_time_factor(factor) -- собственно сама перемотка

    level.set_time_factor(basic_time_factor) --остановка перемотки.
end

Время остановилось вообще. После оставил от обоих функций только level.set_time или level.set_time_global с заменой переменной time_global() на нее же, но плюс час, но эти функции он не определяет.

  • Не нравится 1

Поделиться этим сообщением


Ссылка на сообщение

@UnLoaded При вызове исходных функций без изменений и по отдельности происходит ровно то же самое, что и при "попытке писать скрипты наугад". Если бы функции из схемы сна работала и с переходом на локации, я бы наверное не лез в специальную тему, чтобы спросить, где эта самая функция находится, потому что она действительно самый очевидный вариант на проверку. Но т.к. она, очевидно, не подошла, и если этого не было понятно из исходной формулировки вопроса, то я перефразирую: есть ли где-то в файлах игры функция НЕ ИЗ СХЕМЫ СНА, мгновенно перематывающая время на нужный отрезок вперед или же сразу устанавливающая желаемое время? Если имелась в виду какая-то другая схема сна, которая есть в файлах, но не использовалась в оригинальной игре, то пожалуйста, уточните, о какой конкретно схеме идет речь, и где она находится. А если таковой в файлах игры нет вообще, то подскажите, где ее можно найти. Заранее спасибо.

Поделиться этим сообщением


Ссылка на сообщение

@Dennis_Chikin Не могу сказать, нравится она мне или нет, т.к. первый раз вижу такую формулировку. Это из оригинальных файлов? Если да, то моя ошибка, что неправильно понял отвечавшего мне человека и стащил функцию из мода со спальником. Не могли бы уточнить, где эти функции находятся? В любом случае спасибо, при возможности протестирую работоспособность в игре.

  • Не нравится 1

Поделиться этим сообщением


Ссылка на сообщение

Товарищи, подскажите, пожалуйста, возможна ли установка измененной геймдаты на стимовскую версию сталкача? В руководстве к ТЧ в стиме есть список поддерживаемых модов, которые точно можно установить, но насчет других изменений там, к сожалению, ни слова.

Поделиться этим сообщением


Ссылка на сообщение

@BoBaH_671  Я бы и рад не переживать, да только я уже попробовал, и при запуске после заставки THQ безлоговый вылет с прекращением работы XR_3DA.exe :(

Поделиться этим сообщением


Ссылка на сообщение

@BoBaH_671  А шо делал, распаковал геймдату пиратки ТЧ 1.006, играя в нее же постепенно редачил файлы, в основном конфиги и скрипты, добавил пару моделек\текстур\звуков, полноценным модом один фиг не назовешь, но на пиратке все работало прекрасно. Оставил отредаченную геймдату, понес пиратку, поставил ТЧ 1.006 со стима, перенес геймдату в корень: запуск - заставка ТЧК - вылет с прекращением работы XR_3DA. As simple as that. А что еще надо было сделать?

Поделиться этим сообщением


Ссылка на сообщение
  • Недавно просматривали   0 пользователей

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

AMK-Team.ru

×
×
  • Создать...