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

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


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

AndreySol

(вашими же словами) Извините, но Вы похоже ответы на ваш вопрос слишком поверхностно прочитали ...

В своем ответе ColR_iT вам дал информацию, какой фцнкцией в конечном итоге ставятся метки и по какому аргументу, т.е. по игровому идентификатору (ID).

Ваша путаница в понятиях и попытки домысливания ... вам же и не дают получить ответы на свои вопросы.

Да, в приведенном примере для Сидоровича, ваши умозаключения в принципе верны, за исключением последних звеньев цепочки:

В game_story_ids.ltx прописаны не сами story_id об'ектам, а соответствия УЖЕ присвоенных об'ектам идентификаторов с их текстовыми идентификаторами для именно таск-менеджера.

003 - прописанный Сидоровичу в all.spawn'e идентификатор story_id, т.е. Сидорович в игре появляется уже с этим идентификатором. Менеджер заданий по "Escape_Trader" определяет, что искомый story_id == 3 и ищет в игре об'ект с этим идентификатором, получая от функции id_by_sid его игровой идентификатор (ID)? на который и ставит метку соответствующего типа (blue_location) и с пояснением (hint).

В товем же случае, заспавненный тобою НПС не имеет персонального story_id (числа!) и твои любые записи в game_story_ids.ltx ни к чему не приводят. Точнее твоя запись для "Escape_Technic" скорее всего указывает на уже занятый какой-нибудь аномалией (иль чем другим) идентификатор ...

Т.о. твое предположение "что менеджер заданий просто не может правильно связать story_id" верно и, если хочешь чтобы на НПС ставилась метка - или позаботься ему присвоить его story_id (нет-пакетами) или ставь "ручками" по его игровому ID? получаемому при его спавне.

Как ставить нет-пакетами смотри в модах, т.к. конкретика зависит от модуля/функций для работы с нет-пакетами (о вариантах десятки раз писАлось).

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

Закоментировал дефолтную выдачу тайников в xr_motivator.Сделал скрипт с флешками,после активации которой выдаеться нужный тайник.(связка через таблицу секция флешки=имя тайника).Но в момент активации тайник помечаеться на карте,но его содержимое спавниться у актора.Вот код скрипта treasure_manager

-- Адаптация под нужды мода Panzyuza

local treasure_manager = nil

function parse_spawns(line)
    local ret = {}
    if not line then
        return ret --/>
    end

    --' если default-ов больше, чем значений в ini, то забить недостающие последним значением из ini
    local t = se_respawn.parse_names(line)
    local n = #t        
    local k = 1
    while k <= n do
        local spawn = {}
        spawn.section = t[k]
        -- Проверяем что это не последняя запись
        if t[k+1] ~= nil then
            local p = tonumber(t[k+1])
            -- проверяем что вторым числом задана вероятность, а не другая секция спавну
            if p then
                -- забиваем число
                spawn.prob = p
                k = k + 2
            else
                -- забиваем дефолт 1
                spawn.prob = 1
                k = k + 1
            end
        else
            spawn.prob = 1
            k = k + 1
        end
        table.insert(ret, spawn)
    end
    return ret
end


class "CTreasure"
function CTreasure:__init()
    --' На конструкторе вычитываем LTX и создаем заготовки квестов.
    self.ini = ini_file("misc\\treasure_manager.ltx")

    --' Итерируемся по всем настройкам фраз
    if not self.ini:section_exist("list") then
        abort("There is no section [list] in treasure_manager.ltx")
    end
    local n = self.ini:line_count("list")
    local id, value = "",""

    --' начальная установка
    self.treasure_info = {}

    for i=0,n-1 do
        result, id, value    = self.ini:r_line("list",i,"","")
        
        self.treasure_info[id] = {}

        self.treasure_info[id].target        = utils.cfg_get_number(self.ini, id, "target", nil, true)
        self.treasure_info[id].name            = utils.cfg_get_string(self.ini, id, "name", nil, true, "")
        self.treasure_info[id].description    = utils.cfg_get_string(self.ini, id, "description", nil, true, "")
        self.treasure_info[id].items        = parse_spawns(utils.cfg_get_string(self.ini, id, "items", nil, true, ""))

        local community    = parse_names(utils.cfg_get_string(self.ini, id, "community", nil, false, "", "stalker, bandit, dolg, freedom"))
        self.treasure_info[id].community = {}
        for k,v in pairs(community) do
            self.treasure_info[id].community[v] = true
        end


        if self.treasure_info[id].items == nil then
            abort("cant find 'items' in %s", id)
        end

        self.treasure_info[id].condlist        = xr_logic.parse_condlist(db.actor, "treasure_manager", "condlist", utils.cfg_get_string(self.ini, id, "condlist", nil, false, "", ""))
        
        --' Отметим тайник как новый
        self.treasure_info[id].active = false
        self.treasure_info[id].done = false

        --print_table(self.treasure_info)
    end

    --' Вспомогательные таблицы для облегчения поиска
    self.treasure_by_target = {}
    for k,v in pairs(self.treasure_info) do
        self.treasure_by_target[v.target] = k    
    end

    self.loss_workaround_queue = {}
end
--' Юзание инициатора (возможность выдать тайник)
function CTreasure:use(npc)
    printf("TREASURE USE")
        --if (npc and db.actor) then
        --avs_mod.lootmoney(npc)
    --end
    --' Проверим, не вызывались ли мы уже для этого объекта. 
    local se_obj = alife():object(npc:id())
    if not se_obj or se_obj.treasure_processed == true then
        return --/ Объект уже проверялся
    end
    se_obj.treasure_processed = true

        --' У военных тайник получить нельзя.
    if npc:character_community() == "military" then 
        return
    end

        --' Чем больше значение, тем меньше вероятность.
    local rarets = 80
    if math.random(100) < rarets then 
        return
    end

    --' Нужно рандомно выбрать один из тайников.
    local avail = {}
    local tr_sum = 0
    for k,v in pairs(self.treasure_info) do
        if v.done == false then
            local treasure_prob = xr_logic.pick_section_from_condlist(db.actor, npc, v.condlist)

            if treasure_prob == "" or treasure_prob == nil then
                treasure_prob = 0
            end

            if tonumber(treasure_prob) >= 0 and
            v.community[npc:character_community()] == true and
            v.active == false
            then
                if tonumber(treasure_prob) == 100 then
                    self:give_treasure(k)
                else
                    table.insert(avail, {k = k, prob = treasure_prob})
                    tr_sum = tr_sum + treasure_prob
                end
            end
        end
    end

    if tr_sum == 0 then
        return
    end

    local tr_w = math.random(tr_sum)
    for k,v in pairs(avail) do
        tr_w = tr_w - v.prob
        if tr_w <= 0 then
            --' Выдать тайник
            self:give_treasure(v.k)
            break
        end
    end
end
--' Сохранение
function CTreasure:check()
    --' Проверка тайников
    for k,v in pairs(self.treasure_info) do
        self:give_treasure(k) --/ выдать тайник
    end
end
--' Выдача тайника
function CTreasure:give_treasure(k)
    local v = self.treasure_info[k]
    local sim = alife()
    local obj = sim:story_object(v.target)
    if obj ~= nil then
        news_manager.send_treasure(v.name)

        --' Пометить на карте        
        local text = "%c[255,238,155,23]"..game.translate_string(v.name).."\\n".."%c[default]"..game.translate_string(v.description)
        level.map_add_object_spot_ser(obj.id, "treasure", text)

        --' Сгенерить вещи
        --'
        --' Из-за какого-то дефекта в xrGame.dll тайник потеряет
        --' сгенерированное содержимое в следующей ситуации:
        --'  1) получена ссылка на тайник, который находится в online;
        --'  2) игрок сохраняется и загружается;
        --'  3) между 1 и 2 не было переводов тайника в offline хотя бы раз.
        --' Для предотвращения этого создаём вещи у актёра, запоминаем
        --' идентификаторы, а в вызове actor_binder:update() переносим их
        --' в нужный ящик.
        local item_ids = {}
        local pos, lvid, gvid, pid, new_obj
        local need_workaround = level.object_by_id(obj.id) ~= nil
        if need_workaround then
            pos = db.actor:position()
            lvid = db.actor:level_vertex_id()
            gvid = db.actor:game_vertex_id()
            pid = db.actor:id()
        else
            pos = obj.position
            lvid = obj.m_level_vertex_id
            gvid = obj.m_game_vertex_id
            pid = obj.id
        end
        for kk,vv in pairs(v.items) do
            if ammo_section[vv.section] == true then
                local left, box_size = vv.prob, system_ini():r_u32(vv.section, "box_size")
                while left > box_size do
                    new_obj = sim:create_ammo(vv.section, pos, lvid, gvid, pid, box_size)
                    table.insert(item_ids, new_obj.id)
                    left = left - box_size
                end
                if left > 0 then
                    new_obj = sim:create_ammo(vv.section, pos, lvid, gvid, pid, left)
                    table.insert(item_ids, new_obj.id)
                end
            else
                for i=1,vv.prob do
                    new_obj = sim:create(vv.section, pos, lvid, gvid, pid)
                    table.insert(item_ids, new_obj.id)
                end
            end
        end
        if need_workaround then
            self.loss_workaround_queue[v.target] = item_ids
        end
        
        --' Пометим тайник как выданный
        self.treasure_info[k].active = true
        self.treasure_info[k].done = true
    else
        printf("TREASURE %s, target doesnt exist", k)
    end
end
--' Перенос содержимого для предотвращения возможной потери
function CTreasure:loss_workaround()
    for k,v in pairs(self.loss_workaround_queue) do
        box = level_object_by_sid(k)
        if box == nil then
            abort("inv box nil")
        end
        dbglog("loss_workaround:box=%d", k)
        for kk,vv in ipairs(v) do
                        local lobj = level.object_by_id(vv)
            if lobj then
            printf("transfering items: "..lobj:section())
            db.actor:transfer_item(lobj, box)
                        end
        end
    end
    self.loss_workaround_queue = {}
end
--' Снимаем отметку с тайника
function CTreasure:treasure_empty(box, box_story_id)
    local k = self.treasure_by_target[box_story_id]

    if not (k and self.treasure_info[k]) then
        return --/>
    end

    self.treasure_info[k].active = false
    level.map_remove_object_spot(box:id(), "treasure")
end
--' Сохранение
function CTreasure:save(p)
    --' Сохраняем размер таблицы
    local size = 0
    for k,v in pairs(self.treasure_info) do
        size = size + 1
    end
    p:w_u16(size)
    for k,v in pairs(self.treasure_info) do
        p:w_u16(v.target)
        p:w_bool(v.active)
        p:w_bool(v.done)
    end
end
--' Загрузка
function CTreasure:load(p)
    local t = p:r_u16()
    for i = 1,t do
        local k = self.treasure_by_target[p:r_u16()]
        self.treasure_info[k].active = p:r_bool()
        self.treasure_info[k].done = p:r_bool()
    end
end


function get_treasure_manager()
    if treasure_manager == nil then
        treasure_manager = CTreasure()
    end
    return treasure_manager
end

function take_item_from_box(box, box_story_id)
    if box:is_inv_box_empty() == true then
        get_treasure_manager():treasure_empty(box, box_story_id)
    end
end

function save(p)
    get_treasure_manager():save(p)
end
function load(p)
    get_treasure_manager():load(p)
end
function clear_treasure_manager()
    treasure_manager = nil
end

Наверно это из за функции, которая предотвращает потерю тайника и переносит содержимое.Как можно исправить данную проблему?И при правке стандартных тайников что нужно написать в данной переменной?Число 10 или 5?

condlist = {=npc_rank(novice)} 3

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

panzyuza, скрипты нужно писать/править понимая собственно строки и их назначение. По сути, скрипт - сценарий(!), которым ты (как модмейкер) обясняешь что и как должно произойти в программе, а сама программа только вопдощает то, что ей задали и никакой "отсебятины".

Смотрим твой скрипт:

--' Выдача тайника
function CTreasure:give_treasure(k)

- проблемная функция

  local obj = sim:story_object(v.target)

- получаем об'ект тайника (ящик/...)

    local pos, lvid, gvid, [b]pid[/b], new_obj
    local need_workaround = level.object_by_id(obj.id) ~= nil --/ некий флаг того, что тайник в онлайне, т.е. на текущей локации
    if need_workaround then
      ...
      pid = db.actor:id() --/??? спавнить актору???

- сам же задаешь спавн актору в рюкзак если тайник на текущей локации.

Т.о. скрипт тупо делает то, что ты же ему и задал.

 

Ну а для condlist = {=npc_rank(novice)} 3 - последнее число - это вероятность (в %) заспавнить тайник при обыске соответствующего трупа и какова она должна быть решаешь именно ты.

Однако, судя по тому что ты нечто наковырял в мотиваторе (о чем му только гадать можем), то до этого у тебя может и не доходить.

Кстати, в мотиваторе не комментировать что-то нужно, а немного подправить код ...

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

Хочу в свою солянку добавить смарт мародер мод. Все совместил. Игра жалуется на bind_stalker.script, вот лог:

Expression    : fatal error
Function      : CScriptEngine::lua_error
File          : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp
Line          : 73
Description   : <no expression>
Arguments     : LUA error: ...ое Издание\shoc\gamedata\scripts\bind_stalker.script:61: attempt to index global 'death_manager' (a nil value)

 

 

Можете помочь совместить два bind_stalker-а?

 

Добавлено через 23 мин.:

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()

    funcs.on_game_load()

    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)

    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)
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
----------------------------------------------------------------------------------------------------------------------

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: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        
    funcs.on_actor_update()
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 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"
    }

local post_time = 0
lasthealth  = 0
lasttime    = 0
post_process = 0
local weapon_hide = false
-->> Dynamic campfire mod
local scan_flag
local upd_time
--<< Dynamic campfire mod
----------------------------------------------------------------------------------------------------------------------
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()
    ogsm_freeplay.mark_lc()    
    ogsm_funcs.on_game_load()
    if xrs_ai then xrs_ai.actor_net_spawn(self) end
    ui_main_menu.start()
    -- added by xmk
    -- Новости(фильтр левелов)
    news_main.filter()

    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)

    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)
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)

    --======================================================================
    _Sin_Linking.Sin_Info_callback(npc, 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
----------------------------------------------------------------------------------------------------------------------
    
-- dunin ammo
    local ammo_aggregation = true
    local ps_need_update = false

function actor_binder:on_item_take (obj)
    if obj:clsid() ~= clsid.wpn_ammo then
    level_tasks.proceed(self.object)
    --=============================================================================
    _Sin_Linking.Sin_On_item_take (obj)
    --=============================================================================
    if xrs_ai then xrs_ai.actor_item_take(obj) end
    else --obj:clsid() == clsid.wpn_ammo
        if ammo_aggregation then
            if dunin_ammo.on_take(obj) then
                ps_need_update = true
            end
        end
    end
    --game_stats.update_take_item (obj, self.object)
    dunin_ammo.on_take(obj)
    
end
----------------------------------------------------------------------------------------------------------------------
function actor_binder:on_item_drop (obj)
    player_ogg.lose_item(obj)
    level_tasks.proceed(self.object)
    --=============================================================================
    _Sin_Linking.Sin_On_item_drop (obj)
    --=============================================================================
    --game_stats.update_drop_item (obj, self.object)
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:update(delta)
    object_binder.update(self, delta)
    //hud_med.HudShowMed()
    effect_blood.wounded_pp_update()
    timer_in_hud.show_time()
    -- 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()
    nd_news_main_data.show_news_main()
    -- перепаковщик патронов
        dunin_ammo.on_update()
    
    --' Проверка потери жизни
--[[
    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_time < time then
        post_time = time + 250

        if sleep_manager.is_sleep_active() and xr_conditions.actor_dead() then
            xr_logic.issue_event(db.actor, db.storage[db.actor:id()]["ar_sleep"], "update")
        end

        sleep_manager.update(delta)
    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

    -- UI Radiation Mod additions
    if (ui_rad and self.object) then
        ui_rad.update(self.object)
    end
    -- UI Radiation Mod additions


    -- dunin ammo end
    
    if self.bCheckStart then
        printf("SET DEFAULT INFOS")        

        if not has_alife_info("storyline_actor_start") and
           (level.name() == "l01_escape")
        then
          --=============================================================================
          _Sin_Linking.Sin_Start()
          --=============================================================================
            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        

--================================================================================
====================================
    _Sin_Linking.Sin_Update(delta)
--================================================================================
====================================

    --if not self.particle then
    --    self.particle = particles_object([[weather\water]])
    --    self.particle:play_at_pos(self.object:position())
    --else
        --self.particle:move_to(self.object:position():add(vector():set(0,1,0)),vector():set(0,0,0))
    --end
    
    if xrs_ai then xrs_ai.actor_update(delta) end

    ogsm_funcs.on_actor_update()
    --added by xmk
    -- Новости
    news_main_data.show_news_main()

    -->> Dynamic campfire mod
    if scan_flag == nil then
        scan_flag = 1
        local lvl = level.name()
        local exc_tbl = {
            ["zone_flame_small_0002"] = {"l05_bar"},
            ["zone_flame_small_0005"] = {"l06_rostok"},
            ["zone_flame_small_0006"] = {"l06_rostok"},
            ["zone_flame_small_0007"] = {"l06_rostok"},
            ["zone_flame_small_0008"] = {"l06_rostok"},
            ["zone_flame_small_0010"] = {"l06_rostok"},
            ["zone_flame_small_0012"] = {"l11_pripyat"},
            ["zone_flame_small_0013"] = {"l11_pripyat"},
            ["zone_flame_small_0024"] = {"l11_pripyat"},
            ["zone_flame_small_0025"] = {"l11_pripyat"},
            ["lights_camp_fire_omni_r1_r2_0002"] = {"l05_bar"},
            ["lights_camp_fire_omni_r1_r2_0011"] = {"l11_pripyat"},
            ["lights_camp_fire_omni_r1_r2_0012"] = {"l11_pripyat"},
            ["lights_camp_fire_omni_r1_r2_0031"] = {"l08_yantar"}
--            МОЖЕТ БЫТЬ ТАК:    ["zone_flame_small_9999"] = {"l01_escapel02_garbagel05_barl07_military"},
--            МОЖЕТ БЫТЬ ТАК:    ["lights_camp_fire_omni_r1_r2_9999"] = {"l01_escapel02_garbagel05_barl07_military"}
        }
        for id=1, 65535 do
            local obj = level.object_by_id(id)
            if obj then
                local name = obj:name()
                local exc_obj = exc_tbl[name]
                if exc_obj and string.find(exc_obj[1], lvl) then
--                    printf("EXEPTIONS: OBJ:[%s] LEVELS:[%s]", name, exc_obj[1])
                else
                    if obj:section() == "zone_flame_small" then
                        table.insert(xr_kamp.lvl_objs, obj)
                        obj:disable_anomaly()
                    elseif string.find(name, "r1_r2") then
                        table.insert(xr_kamp.lvl_objs, obj)
                        obj:get_hanging_lamp():turn_off()
                    -- Масляные горелки (требуется доп. правка particles.xr)
--                    elseif string.find(name, "light_gas") then
--                        obj:get_hanging_lamp():turn_off()
                    end
                end
            end
        end
    end
    if upd_time == nil then
        upd_time = time + 10000
    elseif upd_time < time then
        upd_time = time + 10000
        xr_kamp.update(time)
    end
    --<< Dynamic campfire mod
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)    
    --==================================================
    _Sin_Linking.Sin_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)    

    --================================================
    _Sin_Linking.Sin_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")
/**/

 

 

Одна из возможных причин данного вылета, это синтаксическая ошибка в файле death_manager.script, проверяй чекером.

ColR_iT

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

WurDalaK.gif

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

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

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

 

Вурдалак

Он меня постоянно выручает script Syntax Checker.rar

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

Народ, хочу сделать так, чтобы мп-5 9х18 на свалке спавнилась в трупе в новом состоянии? Я так понял, ее надо добавить как исключение в death_manager, как это сделать?

Изменено пользователем Morder07
Ссылка на комментарий

Здравствуйте. Поставил мод, все устаривает кроме нового черно-белого ПНВ. Нашел в gamedata такую строку

[effector_nightvision_good]
pp_eff_name = nightvision_good.ppe
pp_eff_cyclic = 1

Файл nightvision_good.ppe состоит из чего то нечитаемого. Как вернуть оригинальный эффект?

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

ТЧ v 1.0005

С логикой НПСов пытаюсь разбираться, что оно такое и с чем ее кушают. Есть НПС, спауню скриптово у входа в бункер Сидоровича. Прописываю ему:

[smart_terrains]
none = true;-- Чтоб не захватывался гулагами --

[logic]
active = kamp
;active = remark
danger = danger_ignore

[danger_ignore]
ignore_distance = 50

[kamp]
center_point = camp_point
path_walk = camp_point_task
def_state_moving = sprint;run

[remark]
anim = wait
no_move = true

 

Судя по тому, что прочитал о схеме "kamp" на Stalkerin, непись должен согласно указанному в 'def_state_moving' дойти до точки 'center_point' и затем там устроится и сидеть обычным бездельником. Вот только идет он куда попало и судя по всему под прописанную ему логику не попадает. Если сменить активную схему на 'remark' - то все вроде в порядке - НПС стоит как вкопаный, с ним можно поговорить\поторговать.

Что-то я не так делаю, подскажите, что ?

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

AndreySol, почитай про логику повнимательнее и не стОит сводить все к упрощениям.

 

'def_state_moving' - будет ли идти спешить иль бежать к точке кампа, т.е. вид перемещания, котрорый в твоем случае как раз не "идти", а нестись сломя голову (sprint);

'center_point' - само название говорит что это центральная точка для посиделок (точнее это может быть и путь из нескольких точек) и неписи вообще-то должны не до center_point идти, а до площади в которой эта 0-ая точка расположена, где и "рассаживаются".

Естественно, координаты (вертексы) center_point должны соответствовать той локации, где должны быть посиделки.

Т.к. ты не дал информации по секции твоего center_point - гадай сам, не может узнать где эта точка, не может до нее дойти, т.к. на др.локации иль еще чего ...

Параметр path_walk для схемы kamp вообще не требуется, т.е. это по сути "мусор".

 

Ну а ремарк он и в африке ремарк, самая "тупая в использовании" схема, т.е. ума для ее задействования не требуется. ;-)

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

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

Artos, позволь не согласится. по поводу "сорности" параметра path_walk.

Задание этого значения позволит НПС, после приёма на работу и первом её выполнении, придти именно в эту точку. Это очень полезно для этой схемы, поскольку позволяет избежать ситуации, когда НПС приходит на точку center_point установленной в центре костра.

Убедится в этом можно заглянув в файл xr_gulag.script в метод get_job_path_name (248-256 строки оригинального файла).

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

ColR_iT, можно и не соглашаться ... но зачем мешать "котлеты с мухами" и/или подменять понятия?

При чем тут гулаг/работы/костры? Схема kamp и ее параметр center_point не означают посиделки именно у костра, и сами посиделки не обязательно - работа какого-то гулага.

Во-первых, мои слова относятся к контексту вопроса, в котором: [smart_terrains] none = true;-- Чтоб не захватывался гулагами , что означает отсутствие каких-либо "работ";

Во-вторых, схема kamp и камп-менеджер не читают параметр path_walk и все "походы" и рассаживания неписей к кампам никак не подчиняются (иль изменяются) подобным параметром.

И, как уже дал ранее в ответе, неписи идут НЕ в точку, а в некую область ограниченную радиусом и с центром расчитанным ОТ заданной 0-точки center_point.

Ну и в третьих, если бы была завязка на гулаги и работы - то и был бы совершенно иной разговор, где и имена для center_point и path_walk завязаны на имя смарта ...

P.S. И даже указанные тобою строки скрипта гулагов собственно подтверждают, что для "не попадания непися в костер" должен бы просто доополнительный путь center_point_task, который не нуждается в указании в конфиге схемы, т.к. смарт автоматом его читает и цепляет из самого названия center_point. Т.е. этот доп.путь должен просто присутствовать в all.spawn'е и указывать не на костровую точку ...

 

Т.о. подтветждаю свои слова о "мусоре" в конфиге схемы kamp в контексте заданного вопроса.

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

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

Могу ошибаться, но помоему схема kamp, относится к универсальным гулагам со всеми вытекающими(названия работ и путей должны начинатся с имени смарта).А конкретно к автору вопроса, если он должен сидеть у костра в деревне, то проще добавить эксклюзивную работу в список работ гулага деревни, ну и соответсвенно своего нпс туда прописать,тогда в аллспан лезть не придется(хотя в деревне несколько кемппоинтов, но их координаты и имена, опять же можно узнать из аллспавна)

Я хотел сказать, что не знаю примеров в игре, использования логики kamp как отдельной - это или название универсального гулага или работа в смарте.

Изменено пользователем gruber
Ссылка на комментарий

Artos, всё же прописанную логику непосредственно в custom_data, тоже можно считать работой. И, к примеру, если в логике есть переход на схему kamp, на которую НПС уйдёт и окажется в оффлайне, то он придёт как раз в точку center_point, а если это костёр, то исход очевиден. Поэтому указание параметра path_walk позволит избежать таковой ситуации. И кроме как в схеме kamp сочетание использования этих двух параметров является бесполезным.

 

gruber, это почему же схема kamp относится только к гулагам, да ещё и универсальным? Ничего подобного!

Это такая эе самостоятельная схема, как и walker, и camper, и другие. Она и в modules.script прописана. А то, что она в игре не используется в качестве самостоятельной (в не гулага), так это ничего и не значит. К тому же это оказывается не так. Вот пример со Складов, где схема kamp используется в custom_data НПС:

[4972]
; cse_abstract properties
section_name = stalker
name = mil_freedom_member0001
position = -178.503997802734,-16.9659557342529,352.31005859375
direction = 0,0,0

; cse_alife_trader_abstract properties
money = 5000
character_profile = mil_Svoboda_stukach

; cse_alife_object properties
game_vertex_id = 1828
distance = 24.5
level_vertex_id = 144846
object_flags = 0xfffff7ff
custom_data = <<END
[logic]
active = walker0
on_death = death
combat_ignore = combat_ignore

[walker0]
path_walk = mil_freedom_courier_wait_path
path_look = mil_freedom_courier_wait_look
on_actor_dist_le = 12 | %=killactor%
on_info = {+mil_actor_in_khutor_zone} walker1

[walker1]
path_walk = mil_freedom_stukach_walk4
path_look = mil_freedom_stukach_look4
on_actor_dist_le_nvis = 12 | %=killactor%
on_signal = arrive | remark1
combat_ignore_cond = {=check_fighting(712:713:714:719)} false

[remark1]
no_rotate = true
no_move = true
anim = wait_rac
snd = mil_pavlik_to_ara
on_signal = sound_end | %+mil_courier_call% remark2
on_actor_dist_le_nvis = 12 | %=killactor%
target = mil_courier_look_point, 0
combat_ignore_cond = {=check_fighting(712:713:714:719)} false

[remark2]
anim = guard
on_info = {+mil_ara_end} kamp1
on_actor_dist_le_nvis = 12 | %=killactor%
target = mil_courier_look_point, 0
combat_ignore_cond = {=check_fighting(712:713:714:719)} false

[kamp1]
center_point = mil_freedom_khutor_center
meet_enable = true
meet_dialog = mil_dolg_relax_dialog
danger = danger
path_walk = mil_freedom_khutor_center_task
radius = 3
on_actor_dist_le_nvis = 12 | %=killactor%
combat_ignore_cond = {=check_fighting(712:713:714:719)} false


[death]
on_info = %+mil_courier_dead =mil_paul_frost_dead +sar2_death_33%

[danger]
ignore_distance = 0


[smart_terrains]
none = true

[spawn]
conserva = 2
medkit = 2
hand_radio


[spawner]
cond = {+mil_leader_quest2_start}
END
story_id = 710

; cse_visual properties
visual_name = actors\svoboda\stalker_sv_rukzak_1

; cse_alife_creature_abstract properties
g_team = 11
g_squad = 9
g_group = 0
health = 2
dynamic_out_restrictions = 
dynamic_in_restrictions = 

upd:health = 2
upd:timestamp = 0
upd:creature_flags = 0
upd:position = -178.503997802734,-16.9659557342529,352.31005859375
upd:o_model = 0
upd:o_torso = 0,0,0
upd:g_team = 11
upd:g_squad = 9
upd:g_group = 0

; cse_alife_monster_abstract properties
base_out_restrictors = mil_bandit_restrictor
base_in_restrictors = mil_mines_restrictor,mil_freedom_wall_restrictor

upd:next_game_vertex_id = 65535
upd:prev_game_vertex_id = 65535
upd:distance_from_point = 0
upd:distance_to_point = 0

; cse_alife_human_abstract properties
predicate5 = 2,0,2,2,0
predicate4 = 1,0,1,2

; cse_ph_skeleton properties

upd:start_dialog = 

; se_stalker properties

 

Изменено пользователем ColR_iT
Ссылка на комментарий

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

 

В шапке темы, есть ссылка на "шпаргалку", скачай и смотри, там описаны практически все параметры в конфиге оружия.

ColR_iT

Изменено пользователем ColR_iT
Ссылка на комментарий

ColR_iT, категорически не согласен с трактовкой любых секций логики в кастомдате как "работы"! Ты об'единяешь понятия разного уровня.

Это как отдельную анимацию приравнять к state_lib'ам, или отдельный звук к общему амбиенту ...

Работы - это элементы смарт-терейнов и ТОЛЬКО! Именно смарты ими и управляют и заставляют неписей в оффлайне(!) перемешаться к местам соотв.работ.

ColR_iT, ... если в логике есть переход на схему kamp, на которую НПС уйдёт и окажется в оффлайне, то он придёт как раз в точку center_point, а если это костёр, то исход очевиден

Никакой отдельный НПС с отдельной от смартов логикой никогда в оффлайне никуда не пойдет! Он просто напросто НЕ активен и только смарт-терейны с их "CALifeSmartTerrainTask" заставляют неписей перемещаться между локациями. Соответственно и в костер, если таковой прописан ему в схеме кампа он не залезет, т.к. либо он стоИт на месте (в оффлайне), либо УЖЕ в онлайне и подчиняется схеме кампа и камп-менеджеру, который НЕ дает ему залезать в костер, а рассаживает "около".

И, кстати, даже если ты его (НПС) насильно засадишь в костер (например, заспавнишь), то он из него, как правило, ""выпрыгнет", т.к. зависания в кострах именно из-за кривизны интеграции схемы кампа в смарты и этот баг сами разрабы во всех трех версиях игры так и не подправили (хотя везде пишут: TODO: убрать затык ...)

 

Итого, давайте все же схемы/логику отделять от смартов/гулагов/работ. Логика/схемы вполне самостоятельные элементы скриптов и НЕ завязаны на работы. Ну а если задействована логика схем в гулагах/работах, да еще и на НЕтекущих локациях - то программер и должен озаботиться корректной интеграцией схем в свои задумки, дабы ни в костры не лезли, ни в аномалии после ранений, ни прочие казусы не происходили ...

 

Добавлено через 9 мин.:

gruber, уже ColR_iT дал выше соотв.пояснение , но добавлю: если нет примеров в игре - это еще ничего не значит, и не нужно себе же навешивать шоры.

Например, какого лешего вертушкам запрещено вообще летать, если им не прописан путь? Они что, на гулаги завязаны иль по точкам не могут перемещаться? Просто разрабы написали в игре схему с возможностью перемешаться только по путям, но это не значит, что в скриптах нельзя изменить иль добавить иное и ввести в игру ... У меня уже вертушки летают по любой точке любой локации ... и без всяких путей ;-)

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

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

Как сделать регулируемый зум для оптики в ТЧ?

 

Стандартными методами - никак. На просторах интернета ходила .dll, где данная фишка была возможно, где её сейчас искать, к сожалению, не знаю.

ColR_iT

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


Система: Intel(R) Core I5-4200H 2.80 GHz 8 GB RAM NVdida GeForce GTX 850 M 4GB DDR3.

 

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

practik, не думаю, что простой поиск в инете не дал бы досточное кол-во ответов на твой вопрос ...

 

Собственно требуется модифицированная библиотека xrGame.dll, соответствующая твоей версии игры/патча и немного подправленные конфиги оружия с зумом, т.е. дополненные параметрами для зума из ЗП.

 

1. Для версии патча 1.0004 можно взять наработки и модифицированную xrGame.dll из ZENOBIAN-мода, откуда и возникла эта модификация зумов для остальных модов для ТЧ и ЧН.

2. В немалом кол-ве модов также имеются модифицированный библиотеки xrGame.dll для соответствующих версий/патчей. Читаем реадми к модам, например в SIMBION-моде имеются все три варианта для ТЧ.

3. Загляни в проект "Cut_x-Ray" (есть тема и на этом форуме), в котором имеются материалы для внесения собственных правок в движек, и в том числе для зума ...

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

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

У меня два вопроса. Во первых о какой то изменяемой, которая отслеживала бы идет ли дождь или нет. Например, я использую { =is_day } для активизаций разных звуков. Есть ли что то вроде { =is_raining }? В принципе я бы хотел, чтобы мною кодированные space restrictors при наличие дождя играли бы разные звуки. Это код, который я использую сейчас

 

Второй вопрос об усиление/утихание функцией звука. Это код который вы мне рекомендовали here. Единственная проблема в том, что я понятия не имею как это осуществить так что бы это работала свыше указанным space restrictors кодом.

 

Спасибо вам за помощь!

Изменено пользователем Daemonion
Ссылка на комментарий

Daemonion

1. Готовых функций/методов типа =is_raining нет, но ничего не мешает написать простенькую самому. В качестве основы может быть взята функция weather_class из sound_theme.script. Переделать строковые значения на булевы - минутное дело.

 

2. А вот с этим похуже ... Можно зазубрить основы программирования, но невозможно выучить "как думать" ...

Ты пытаешься в прокрустово ложе конфига для штатной логики вложить свою задумку, но ... т.к. разработчики не расчитывали на подобное, то без написания своих скриптов/функций тебе не обойтись. Если сам не сможешь понять как вообще работают ранее данные тебе в качестве примера скрипты - врядли сам что-то сможешь написать. Так что тут или учишься читать скрипты, понимать их и думать как написать свое или ... ищешь того, кто за тебя это реализует.

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

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

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

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

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

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

Войти

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

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

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