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

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


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

Привет всем! Решил я заморочиться над полноценным хроманием НПС в Зове припяти - то есть когда у них мало здоровья они не падают на землю, а держась одной рукой за бок убегают или уходят хромая и истекая кровью в укрытие (как в ранних видео сталкера:  2:23

И все у меня получилось, но есть одна загвоздка!

По порядку: все анимации хромания в движке остались, поэтому чтобы заставить хромать НПС нужно подкорректировать 3 файла в папке (.../STALKER COP/gamedata/scripts"), это state_lib.script, state_mgr_animation_list.script и xr_wounded.script. Проделывал все по образу и подобию трудов под названием "Paradise Lost" для ТЧ (автору респект!)
В файле state_lib.script нужно дописать два ходячих состояния:

 

        limping_run = {    weapon = "unstrapped", --"none"
                movement = move.run,
                mental = anim.free,
                bodystate = move.standing,
                animstate = nil,
                animation = "damaged_run"
            },
    limping_walk = {    weapon = "unstrapped", --"none", --"drop",
                movement = move.walk,
                mental = anim.free,
                bodystate = move.standing,
                animstate = nil,
                animation = "damaged_walk"
            },

 


В файле state_mgr_animation_list.script нужно расписать две анимации этих состояний:

 

damaged_run    = {    prop    = { maxidle = 5,
                                    sumidle = 10,
                                    rnd = 70 },
                        into    = nil,
                        out        = nil,
                        idle    = { [0]    = "dmg_norm_run_fwd_0" },
                        rnd        = nil },

    damaged_walk    = {    prop    = { maxidle = 5,
                                    sumidle = 10,
                                    rnd = 70 },
                        into    = nil,
                        out        = nil,
                        idle    = { [0]    = "dmg_norm_run_fwd_1" },
                        rnd        = nil },

 


А в файле xr_wounded.script нужно включить это в состояние "раненый":


1)закоментировать в разделе "--Actions" знаками "--" строчки

self.object:movement_enabled(false)
self.object:wounded(true)


2)Добавляем это перед строкой

if wound_manager_state == "true" then

   -- отправляем чудака в кавер, если его ранг превышает заданное значение.
--if self.object:health > 0.05 then
if self.object:character_rank() >= 2 then    --500
    if wound_manager.cover == "true" then
        if self.pos == nil or self.vid == nil then
            local pt = self.object:safe_cover(self.object:position(), 20, 0)
            if pt then
                self.pos = pt:position()
                self.vid = pt:level_vertex_id()        
                if self.object:accessible(self.vid) == false then
                    local vtemp = vector():set(0, 0, 0)
                    self.vid, vtemp = self.object:accessible_nearest(self.pos, vtemp)
                    self.pos = vtemp
                end
--                xr_sound.set_sound(self.object, "wounded_limping")
                self.object:clear_animations() --???(!!!)
                self.object:set_desired_position      (self.pos)
                self.object:set_desired_direction     ()
                self.object:set_detail_path_type      (move.line)
                self.object:set_path_type             (game_object.level_path)

--                self.object:set_item                  (object.drop, get_weapon(self.object))

                self.object:set_body_state            (move.standing)
                self.object:set_mental_state          (anim.free)

                self.object:set_dest_level_vertex_id  (self.vid)  
                local runner = math.random(1,2)
                if runner == 1 then
                    self.object:set_movement_type  (move.run)
                    state_mgr.set_state(self.object, "limping_run")
                else  
                    self.object:set_movement_type  (move.walk)
                    state_mgr.set_state(self.object, "limping_walk")
                end
            end
            return
        else
            -- кавер выбран, просто туда идем
            if self.object:accessible(self.vid) == false then
                self.vid = nil
                return
            end
            printf("dist to cover [%s]", self.object:position():distance_to(self.pos))
            if self.object:position():distance_to_sqr(self.pos) > 1 then
                return
            end            
        end
    else
        self.pos = nil
        self.vid = nil
    end
--else
--Если ранг ниже заданного, не ищем кавер - падаем прямо тут.
    if self.object:character_rank() < 2 then    --500
        return
    end
end

Здесть я трогал только параметр строки "if self.object:character_rank() >= 2 then"
 и "if self.object:character_rank() < 2 then" (Они определяют по рангу какие НПС будут падать сразу, а
какие будут хромая убегать. Я поставил 2 чтобы хромали все НПС)

3)В блоке "-- проверяем на обычную раненость" дописываем

self.cover    = self:process_cover(hp)

4)После строк

function Cwound_manager:process_fight(hp)
    local key
    key = self:get_key_from_distance(self.a.hp_fight, hp)
    if key ~= nil then
        if self.a.hp_fight[key].state then
            return tostring(xr_logic.pick_section_from_condlist(db.actor, self.npc, self.a.hp_fight[key].state))
        end
    end
    return "true"
end

дописываем:

function Cwound_manager:process_cover(hp)
    local key
    key = self:get_key_from_distance(self.a.hp_cover, hp)
    if key ~= nil then
        if self.a.hp_cover[key].state then
            return tostring(xr_logic.pick_section_from_condlist(db.actor, self.npc, self.a.hp_cover[key].state))
        end
    end        
    return "nil"    --"true"
end

5)В блоке "local state = wounded_by_state[math.mod(npc:id(), 3)]"
цифры определяют ниже какого уровня здоровья НПС хромая убегает. Везде нужно поставить одно значение
(я для тестов выставлял 70, а так 20-30 норм)
и параметр "def.hp_cover" здесь обязательно нужно поставить "true" вот так def.hp_cover = "70|true"


Все.

В "Тень Чернобыля" это работает так: когда здоровье НПС опускается ниже заданного параметра,
он перестает отстреливаться и хромая убегает или уходит (рандомно) в укрытие (в кусты, за угол, за стену)
и там падает на землю истекая кровью. Я это вставлял в любые моды ТЧ и все работало.

А загвоздка в ЗП в том что НПС хромает в укрытие и там не падает на землю, а останавливается с
анимацией хромания и "аля Майкл Джексон". Такое случается в 5 случаях из 6. И думаю это из-за того, что
в xr_wounded.script разработчики добавили использование аптечек, а что конкретно там мешает не могу разобрать.

Выложу то что наработал, мож подскажет кто, где загвоздка?

 

--    Схема раненного
--    автор: Диденко Руслан (Stohe)
--    TODO:
----------------------------------------------------------------------------------------------------------------------

---------------------------------------------------------------------------------------------------------------------
--Evaluators
----------------------------------------------------------------------------------------------------------------------
class "evaluator_wound" (property_evaluator)
function evaluator_wound:__init(name, storage) super(nil, name)
        self.a = storage
end
function evaluator_wound:evaluate ()
    if self.object:in_smart_cover() then return false end

    if self.a.wounded_set ~= true then return false end

    self.a.wound_manager:update()
    if self.mgr == nil then
        self.mgr = self.object:motivation_action_manager()
    end
    if self.object:critically_wounded() == true then
        return false
    end
    if self.mgr:evaluator(stalker_ids.property_enemy):evaluate() and
         xr_logic.pstor_retrieve(self.object, "wounded_fight") == "true"
    then
        return false
    end
    return tostring(xr_logic.pstor_retrieve(self.object, "wounded_state")) ~= "nil"
end

class "evaluator_can_fight" (property_evaluator)
function evaluator_can_fight:__init(name, storage) super(nil, name)
        self.a = storage
end
function evaluator_can_fight:evaluate ()
    if self.object:critically_wounded() == true then
        return true
    end

    return xr_logic.pstor_retrieve(self.object, "wounded_fight") ~= "false"
end

----------------------------------------------------------------------------------------------------------------------
--Actions
----------------------------------------------------------------------------------------------------------------------
class "action_wounded" (action_base)
function action_wounded:__init(name, storage) super(nil, name)
        self.a = storage
end
function action_wounded:initialize ()
        action_base.initialize (self)
    self.object:set_desired_position()
    self.object:set_desired_direction()


    if self.a.help_start_dialog then
        self.object:set_start_dialog(self.a.help_start_dialog)
    end
--    self.object:movement_enabled(false)
    self.object:disable_trade()
--    self.object:wounded(true)
end
function action_wounded:execute ()
        action_base.execute (self)
    wound_manager = self.a.wound_manager

    wound_manager_victim = xr_logic.pstor_retrieve(self.object, "wounded_victim")
    local sim = alife()
    local victim = nil
    if tostring(wound_manager_victim) == "nil" then
        victim = nil
    else
        if sim then
            victim = get_story_object(victim)
        end
    end

    -- Проверяем возможность скушать аптечку.
    if self.a.autoheal == true then
        if wound_manager.can_use_medkit ~= true then
            local begin_wounded = xr_logic.pstor_retrieve(self.object, "begin_wounded")
            local current_time = time_global()
            if begin_wounded == nil then
                xr_logic.pstor_store(self.object, "begin_wounded", current_time)
            elseif current_time - begin_wounded > 60000 then
                local npc = self.object
                sim:create("medkit_script",
                                npc:position(),
                            npc:level_vertex_id(),
                            npc:game_vertex_id(),
                            npc:id())
                wound_manager:unlock_medkit()
            end
        end
    end

    wound_manager_state = xr_logic.pstor_retrieve(self.object, "wounded_state")
    wound_manager_sound = xr_logic.pstor_retrieve(self.object, "wounded_sound")
    -- отправляем чудака в кавер, если его ранг превышает заданное значение.
--if self.object:health > 0.05 then
if self.object:character_rank() >= 2 then    --500
    if wound_manager.cover == "true" then
        if self.pos == nil or self.vid == nil then
            local pt = self.object:safe_cover(self.object:position(), 20, 0)
            if pt then
                self.pos = pt:position()
                self.vid = pt:level_vertex_id()        
                if self.object:accessible(self.vid) == false then
                    local vtemp = vector():set(0, 0, 0)
                    self.vid, vtemp = self.object:accessible_nearest(self.pos, vtemp)
                    self.pos = vtemp
                end
--                xr_sound.set_sound(self.object, "wounded_limping")
                self.object:clear_animations() --???(!!!)
                self.object:set_desired_position      (self.pos)
                self.object:set_desired_direction     ()
                self.object:set_detail_path_type      (move.line)
                self.object:set_path_type             (game_object.level_path)

--                self.object:set_item                  (object.drop, get_weapon(self.object))

                self.object:set_body_state            (move.standing)
                self.object:set_mental_state          (anim.free)

                self.object:set_dest_level_vertex_id  (self.vid)  
                local runner = math.random(1,2)
                if runner == 1 then
                    self.object:set_movement_type  (move.run)
                    state_mgr.set_state(self.object, "limping_run")
                else  
                    self.object:set_movement_type  (move.walk)
                    state_mgr.set_state(self.object, "limping_walk")
                end
            end
            return
        else
            -- кавер выбран, просто туда идем
            if self.object:accessible(self.vid) == false then
                self.vid = nil
                return
            end
            printf("dist to cover [%s]", self.object:position():distance_to(self.pos))
            if self.object:position():distance_to_sqr(self.pos) > 1 then
                return
            end            
        end
    else
        self.pos = nil
        self.vid = nil
    end
--else
--Если ранг ниже заданного, не ищем кавер - падаем прямо тут.
    if self.object:character_rank() < 2 then    --500
        return
    end
end   
    if wound_manager_state == "true" then
        local h = hit()
        h.power = 0
        h.direction = self.object:direction()
        h.bone = "bip01_spine"
        h.draftsman = db.actor
        h.impulse = 0
        h.type = hit.wound
        self.object:hit(h)
    else
        -- жрание аптечек и прочей срани.
        -- Использовать можно только если нам можно сейчас есть аптечку.
        if self.a.use_medkit == true then
            wound_manager:eat_medkit()
        end

        if tostring(wound_manager_state) == "nil" then
            print_table(self.a.hp_state)
            print_table(self.a.hp_state_see)
            abort("wrong wounded animation %s", self.object:name())
        end
        state_mgr.set_state(self.object, wound_manager_state, nil, nil, {look_object = victim}, nil)
    end

    -- нужно отыграть фоновый
    if wound_manager_sound == "nil" then
        xr_sound.set_sound_play(self.object:id(), nil)
    else
        xr_sound.set_sound_play(self.object:id(), wound_manager_sound)
    end
end
function action_wounded:finalize ()
        action_base.finalize (self)
        self.object:enable_trade()
        self.object:disable_talk()
--  xr_sound.set_sound(self.object, nil)
        self.object:wounded(false)
        self.object:movement_enabled(true)
end

----------------------------------------------------------------------------------------------------------------------
-- Class wound_manager
----------------------------------------------------------------------------------------------------------------------
class "Cwound_manager"
function Cwound_manager:__init(npc, storage)
    self.npc = npc
    self.a = storage
    self.can_use_medkit = false
end
function Cwound_manager:update()
    -- Автовылечивание раненых после боя
--    if self.npc:best_enemy() == nil then
--        self.npc.health = 1
--    end

    hp    = 100*self.npc.health
    psy    = 100*self.npc.psy_health

    --printf("PSY [%s] HP [%s]", psy, hp)

    self.state, self.sound = self:process_psy_wound(psy)

    if self.state == "nil" and
         self.sound == "nil"
    then
        -- проверяем на обычную раненость
        self.state, self.sound = self:process_hp_wound(hp)
        self.fight    = self:process_fight(hp)
        self.victim = self:process_victim(hp)
        self.cover    = self:process_cover(hp)
    else
        -- устанавливаем пси раненость
        self.fight = "false"
        self.cover = "false"
        self.victim = "nil"
    end
    --printf("f[%s]c[%s]v[%s]", utils.to_str(self.fight), utils.to_str(self.cover), utils.to_str(self.victim))
    --printf("st[%s]so[%s]", utils.to_str(self.state), utils.to_str(self.sound))

    xr_logic.pstor_store(self.npc, "wounded_state", self.state)
    xr_logic.pstor_store(self.npc, "wounded_sound", self.sound)
    xr_logic.pstor_store(self.npc, "wounded_fight", self.fight)
    xr_logic.pstor_store(self.npc, "wounded_victim", self.victim)
end
function Cwound_manager:unlock_medkit()
    self.can_use_medkit = true
end
function Cwound_manager:eat_medkit()
    if self.can_use_medkit == true then
        if self.npc:object("medkit_script") ~= nil then
            self.npc:eat(self.npc:object("medkit_script"))
        end

        if self.npc:object("medkit") ~= nil then
            alife():release(alife():object(self.npc:object("medkit"):id()), true)
        elseif self.npc:object("medkit_army") ~= nil then
            alife():release(alife():object(self.npc:object("medkit_army"):id()), true)
        elseif self.npc:object("medkit_scientic") ~= nil then
            alife():release(alife():object(self.npc:object("medkit_scientic"):id()), true)
        end


        local begin_wounded = xr_logic.pstor_retrieve(self.npc, "begin_wounded")
        local current_time = time_global()
        if begin_wounded ~= nil and current_time - begin_wounded <= 60000 then
            xr_sound.set_sound_play(self.npc:id(), "help_thanks")
        end
        
        xr_logic.pstor_store(self.npc, "begin_wounded", nil)
    end

    self.can_use_medkit = false
    self:update()
end
function Cwound_manager:process_fight(hp)
    local key
    key = self:get_key_from_distance(self.a.hp_fight, hp)
    if key ~= nil then
        if self.a.hp_fight[key].state then
            return tostring(xr_logic.pick_section_from_condlist(db.actor, self.npc, self.a.hp_fight[key].state))
        end
    end
    return "true"
end
function Cwound_manager:process_cover(hp)
    local key
    key = self:get_key_from_distance(self.a.hp_cover, hp)
    if key ~= nil then
        if self.a.hp_cover[key].state then
            return tostring(xr_logic.pick_section_from_condlist(db.actor, self.npc, self.a.hp_cover[key].state))
        end
    end        
    return "nil"    --"true"
end
function Cwound_manager:process_victim(hp)
    local key
    key = self:get_key_from_distance(self.a.hp_victim, hp)
    if key ~= nil then
        if self.a.hp_victim[key].state then
            return tostring(xr_logic.pick_section_from_condlist(db.actor, self.npc, self.a.hp_victim[key].state))
        end
    end
    return "nil"
end
function Cwound_manager:process_hp_wound(hp)
    local key
    key = self:get_key_from_distance(self.a.hp_state, hp)
    if key ~= nil then
        local r1,r2
        if self.npc:see(db.actor) then
            if self.a.hp_state_see[key].state then
                r1 = xr_logic.pick_section_from_condlist(db.actor, self.npc, self.a.hp_state_see[key].state)
            end
            if self.a.hp_state_see[key].sound then
                r2 = xr_logic.pick_section_from_condlist(db.actor, self.npc, self.a.hp_state_see[key].sound)
            end
        else
            if self.a.hp_state[key].state then
                r1 = xr_logic.pick_section_from_condlist(db.actor, self.npc, self.a.hp_state[key].state)
            end
            if self.a.hp_state[key].sound then
                r2 = xr_logic.pick_section_from_condlist(db.actor, self.npc, self.a.hp_state[key].sound)
            end
        end
        return tostring(r1),tostring(r2)
    end
    return "nil","nil"
end
function Cwound_manager:process_psy_wound(hp)
    local key
    key = self:get_key_from_distance(self.a.psy_state, hp)
    if key ~= nil then
        local r1,r2
        if self.a.psy_state[key].state then
            r1 = xr_logic.pick_section_from_condlist(db.actor, self.npc, self.a.psy_state[key].state)
        end
        if self.a.psy_state[key].sound then
            r2 = xr_logic.pick_section_from_condlist(db.actor, self.npc, self.a.psy_state[key].sound)
        end
        return tostring(r1),tostring(r2)
    end
    return "nil","nil"
end
function Cwound_manager:get_key_from_distance(t, hp)
    local key
    for k,v in pairs(t) do
        if v.dist >= hp then
            key = k
        else
            return key
        end
    end
    return key
end
function Cwound_manager:hit_callback()
    if self.npc:alive() == false then
        return
    end

    if self.npc:critically_wounded() == true then
        return
    end

    self:update()
end

----------------------------------------------------------------------------------------------------------------------
-- binder
----------------------------------------------------------------------------------------------------------------------
function add_to_binder (object, ini, scheme, section, st)

        local operators     = {}
        local properties    = {}

        properties["wounded"]        =   xr_evaluators_id.sidor_wounded_base
        properties["can_fight"]     =   xr_evaluators_id.sidor_wounded_base + 1

        operators["wounded"]        =   xr_actions_id.sidor_act_wounded_base + 0


        local manager = object:motivation_action_manager ()
        manager:add_evaluator (properties["wounded"],        this.evaluator_wound("wounded", st))
        manager:add_evaluator (properties["can_fight"],     this.evaluator_can_fight("can_fight", st))

        local action = this.action_wounded("wounded_action", st)
        action:add_precondition (world_property(stalker_ids.property_alive,        true))
        action:add_precondition (world_property(properties["wounded"],            true))
        action:add_effect (world_property(properties["wounded"],        false))
        action:add_effect (world_property(stalker_ids.property_enemy,    false))
        action:add_effect (world_property(properties["can_fight"],        true))
         manager:add_action      (operators["wounded"], action)

        action = manager:action (xr_actions_id.alife)
        action:add_precondition (world_property(properties["wounded"],            false))

        action = manager:action (stalker_ids.action_gather_items)
        action:add_precondition (world_property(properties["wounded"],            false))

        action = manager:action (stalker_ids.action_combat_planner)
        action:add_precondition (world_property(properties["can_fight"],       true))

        action = manager:action (stalker_ids.action_danger_planner)
        action:add_precondition (world_property(properties["can_fight"],       true))

        action = manager:action (stalker_ids.action_anomaly_planner)
        action:add_precondition (world_property(properties["can_fight"],       true))

end


------------
-- Вызывается только в начале на чтении логики, создает экшены, эвалуаторы и производит
-- первичную настройку.
function set_wounded(npc, ini, scheme, section)
    local st = xr_logic.assign_storage_and_bind(npc, ini, scheme, section)
    st.wound_manager = Cwound_manager(npc, st)
end
-- Вызывается на переключении на новую секцию. Производит вычитывание настроек из текущей секции.
function reset_wounded(npc, scheme, st, section)
    local wounded_section
    if scheme == nil or scheme == "nil" then
        wounded_section = utils.cfg_get_string(st.ini, st.section_logic, "wounded", npc, false, "")
    else
        wounded_section = utils.cfg_get_string(st.ini, section, "wounded", npc, false, "")
    end
    init_wounded(npc, st.ini, wounded_section, st.wounded, scheme)
    st.wounded.wound_manager:hit_callback()
end
-- Функция чтения настроек. В нее передается секция, откуда их нужно читать.
local wounded_by_state = {
    [0] = "wounded_heavy",
    [1] = "wounded_heavy_2",
    [2] = "wounded_heavy_3"
}

function init_wounded(npc, ini, section, st, scheme)
    --printf("WOUNDED SECTION [%s][%s]", tostring(section), tostring(scheme))

    if tostring(section) == st.wounded_section and
         tostring(section) ~= "nil"
    then
        return
    end

    st.wounded_section = utils.to_str(section)

    local def = {}
    local npc_community = character_community(npc)
    if npc_community == "monolith" then
        local state = wounded_by_state[math.mod(npc:id(), 3)]
        def.hp_state            = "20|"..state.."@nil"
        def.hp_state_see        = "20|"..state.."@nil"
        def.psy_state            = ""
        def.hp_victim            = "20|nil"
        def.hp_cover            = "20|false"
        def.hp_fight            = "20|false"
        def.syndata                = ""
        def.help_dialog            = nil
        def.help_start_dialog    = nil
        def.use_medkit            = false
        def.enable_talk            = true
        def.not_for_help        = true

    elseif npc_community == "zombied" then
        def.hp_state            = "40|wounded_zombie@nil"
        def.hp_state_see        = "40|wounded_zombie@nil"
        def.psy_state            = ""
        def.hp_victim            = "40|nil"
        def.hp_cover            = "40|false"
        def.hp_fight            = "40|false"
        def.syndata                = ""
        def.help_dialog            = nil
        def.help_start_dialog    = nil
        def.use_medkit            = false
        def.enable_talk            = true
        def.not_for_help        = true
    else
        local state = wounded_by_state[math.mod(npc:id(), 3)]
        def.hp_state            = "70|"..state.."@help_heavy"
        def.hp_state_see        = "70|"..state.."@help_heavy"
        def.psy_state            = "70|{=best_pistol}psy_armed,psy_pain@wounded_psy|20|{=best_pistol}psy_shoot,psy_pain@{=best_pistol}wounded_psy_shoot,wounded_psy"
        def.hp_victim            = "70|nil"
        def.hp_cover            = "70|true"
        def.hp_fight            = "70|false"
        def.syndata                = ""
        def.help_dialog            = "dm_help_wounded_medkit_dialog"
        def.help_start_dialog    = nil
        def.use_medkit            = true
        def.enable_talk            = true
        def.not_for_help        = false
    end


    if tostring(section) == "nil" then
        -- Загружаем дефолты!
        st.hp_state        = utils.parse_data(npc, def.hp_state)
        st.hp_state_see    = utils.parse_data(npc, def.hp_state_see)
        st.psy_state    = utils.parse_data(npc, def.psy_state)
        st.hp_victim    = utils.parse_data(npc, def.hp_victim)
        st.hp_cover        = utils.parse_data(npc, def.hp_cover)
        st.hp_fight        = utils.parse_data(npc, def.hp_fight)
        st.syndata        = utils.parse_syn_data(npc, def.syndata)
        st.help_dialog    = def.help_dialog
        st.help_start_dialog = nil
        st.use_medkit   = def.use_medkit
        st.autoheal        = true
        st.enable_talk    = true
        st.not_for_help    = def.not_for_help
    else
        st.hp_state        = utils.parse_data(npc, utils.cfg_get_string(ini, section, "hp_state", npc, false, "", def.hp_state))
        st.hp_state_see    = utils.parse_data(npc, utils.cfg_get_string(ini, section, "hp_state_see", npc, false, "", def.hp_state_see))
        st.psy_state    = utils.parse_data(npc, utils.cfg_get_string(ini, section, "psy_state", npc, false, "", def.psy_state))
        st.hp_victim    = utils.parse_data(npc, utils.cfg_get_string(ini, section, "hp_victim", npc, false, "", def.hp_victim))
        st.hp_cover        = utils.parse_data(npc, utils.cfg_get_string(ini, section, "hp_cover", npc, false, "", def.hp_cover))
        st.hp_fight        = utils.parse_data(npc, utils.cfg_get_string(ini, section, "hp_fight", npc, false, "", def.hp_fight))
        st.syndata        = utils.parse_syn_data(npc, utils.cfg_get_string(ini, section, "syndata", npc, false, "", def.syndata))
        st.help_dialog    = utils.cfg_get_string(ini, section, "help_dialog", npc, false, "", def.help_dialog)
        st.help_start_dialog = utils.cfg_get_string(ini, section, "help_start_dialog", npc, false, "", nil)
        st.use_medkit   = utils.cfg_get_bool(ini, section, "use_medkit", npc, false, def.use_medkit)
        st.autoheal        = utils.cfg_get_bool(ini, section, "autoheal", npc, false, true)
        st.enable_talk    = utils.cfg_get_bool(ini, section, "enable_talk", npc, false, true)
        st.not_for_help    = utils.cfg_get_bool(ini, section, "not_for_help", npc, false, def.not_for_help)
    end

    -- флажок, что функция хотя бы раз вызывалась
    st.wounded_set = true
end

function unlock_medkit(npc)
    if db.storage[npc:id()].wounded ~= nil then
        db.storage[npc:id()].wounded.wound_manager:unlock_medkit()
    end
end



function is_wounded(npc)
    local npc_storage = db.storage[npc:id()]
    if npc_storage == nil then
        return false
    end

    if npc_storage.wounded ~= nil then
--        if npc:object("medkit") ~= nil and
--           npc_storage.wounded.wound_manager.can_use_medkit == true
--       then
--            return false
--        end

        return tostring(npc_storage.wounded.wound_manager.state) ~= "nil"
    end
    return false
end

function hit_callback(npc_id) -- Тут может не быть стораджа.
    if db.storage[npc_id].wounded ~= nil then
        db.storage[npc_id].wounded.wound_manager:hit_callback()
    end
end


function is_heavy_wounded_by_id(npc_id)
    if db.storage[npc_id].wounded ~= nil then
        return tostring(db.storage[npc_id].wounded.wound_manager.state) ~= "nil"
    end
    return false
end
function is_psy_wounded_by_id(npc_id)
    if db.storage[npc_id].wounded ~= nil then
        return db.storage[npc_id].wounded.wound_manager.state == "psy_pain" or
                 db.storage[npc_id].wounded.wound_manager.state == "psy_armed" or
                 db.storage[npc_id].wounded.wound_manager.state == "psy_shoot" or
                 db.storage[npc_id].wounded.wound_manager.state == "psycho_pain" or
                 db.storage[npc_id].wounded.wound_manager.state == "psycho_shoot"
    end
    return false
end

 

 

 

Во-первых, если потрудился написать это всё - потрудись и оформить это. В следующий раз пост просто потру.

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

ColR_iT

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

Выкладываю готовые файлы:

 

http://rghost.ru/52851627

 

http://rghost.ru/52851661

 

http://rghost.ru/52851671

 

 

 

 

http://rghost.ru/52851838

 

http://rghost.ru/52851849

 

http://rghost.ru/52851858

 

 

 

 

 

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

  • Нравится 1
Ссылка на комментарий

Здраствуйте! Решил покопатся в конфигах G36 Меняю

scope_zoom_factor = -35

scope_dynamic_zoom = on

 

И получается http://img-fotki.yandex.ru/get/9497/183412328.0/0_10a869_99803dad_L.jpg

http://img-fotki.yandex.ru/get/9491/183412328.0/0_10a868_af5e3030_L.jpg
http://img-fotki.yandex.ru/get/9497/183412328.0/0_10a867_1f1ed770_L.jpg

 

Конфиг scope_zoom_factor брал из w_g36_up.ltx из оригинальной игры.

 

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

 

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

Можно ли создать эффект появления нпс, когда вокруг искрят молнии от телепорта, и как? Подобное можно наблюдать как в ЧН (очень активно), так и в ТЧ, на локации ЧАЭС, когда Монолит появляется.

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

@ммихаилл, через рестриктор со схемой sr_particle.

Почитай здесь: http://stalkerin.gameru.net/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%BB%D0%BE%D0%B3%D0%B8%D0%BA%D0%B8._%D0%A7%D0%B0%D1%81%D1%82%D1%8C_3

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

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

naxac.gif

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

Ребят, кто может точно сказать что означает k-ap?

k_dist = коэффициент дальности


k_disp = кучность
k_hit = убойность
k_impulse = Импульс
k_pierce = пробивная способность пули(хотя многие и пишут в справочниках что это коэффициент насколько испортиться броня при попадании), хотя может и портиться, но у дроби в оригинале стоит 0, и это значить с дроби что-ли хоть за стреляйся, всё равно не испортишь броню. Но вот что это пробивная способность это точно на все сто процентов, ставишь больше 1.15 и пробивает забор, ещё больше то деревянные стены, ещё больше то деревья толстые.(В ТЧ, в ЗП пока не знаю точно, не пробовал)

k_ap = А что это такое? В ТЧ такого нет.
impair = коэффициент износа ствола от пули
buck_shot = кол-во составляющих в пуле
tracer = является ли патрон трассирующим
wm_size = визуальный размер дырки на стене от пули
k_air_resistance = сопротивление воздуха

 

Я так думаю что это тоже самое что и k_pierce, т.е больше склоняюсь к этому варианту :russian_ru:



В ЗП по другому всё что-ли, сделал патронам k_pierce = 1.5 как в тч обычно делаю, так теперь забор бетонный пробивает насквозь.

Бетонный то не должен пробивать вообще, по крайней мере в ТЧ не пробивает бетонное, кирпичное, вроде как.

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

Кто нибудь запускал enb шейдеры на ЗП? Я попробовал: окно для редактирования шейдеров ингейм появляется, но сами шейдеры не работают. Кто проверял?

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

@Потенциал, Я, фиговые шейдеры если честно, да и фпс жестоко садят. Иногда игра вылетает обругивая видеокарту. Если ты конечно об ENB Series говоришь.

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

@Anonim,фиговые шейдеры или нет - с этим я разберусь сам. Ты мне скажи, у тебя всё нормально работало и как ты их установил? Можешь поделится ссылкой, если не трудно. 

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

нормально работало

Иногда игра вылетает обругивая видеокарту

фпс жестоко садят

Не понимаю, зачем ЗП шейдеры, он сам по себе красив. Читай внимательнее  ;). + Эффект Deph of field очень

противный.

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

Ссылкой не поделюсь, я их года 2 назад скачивал, и снёс сразу.

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

Как прописать карту новой локации на глобальной карте?
Я прописывал в файле level.ltx данной локации и путь, и размеры карты. И в файле game_maps_single.ltx прописал расположение на глобальной карте, но ее нет, на месте, где она должна быть, черный квадрат с надписью "no map". Хотя на минимапе она отображается.
Заранее спасибо за ответы.

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

@ммихаилл, прописать надо в game_levels.ltx и game_maps_single.ltx в папках мода и SDK. В level.ltx не надо ничего прописывать! Оттуда нужно взять данные о bound_rect.

С#Н#Т#Р# (CoP 1.6.02)

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

Здравствуйте.

Руки добрались до стационарного пулемёта на блокпосте вояк. Задаю логику пулемёту:



[logic]
active = ph_idle

[ph_idle]
auto_fire = false
on_info   = {=dist_to_actor_le(100) +esc_minigunner} ph_minigun@actor

[ph_minigun@actor]
fire_angle = 150
track_target = true
target = actor
fire_range   = 100
fire_repeat  = 5
fire_time     = 5
auto_fire     = true
on_info        = {-esc_minigunner} ph_idle@stop 
on_info2      = {=dist_to_actor_ge(100)} ph_idle@stop
shoot_only_on_visible = false

[ph_idle@stop]
auto_fire = false
on_info   = {=dist_to_actor_le(100) +esc_minigunner} ph_minigun@actor
on_info2 = {-esc_minigunner} ph_idle

 

 

Но при приближении к пулемёту ловлю вылет:



FATAL ERROR
 
[error]Expression    : !m_error_code
[error]Function      : raii_guard::~raii_guard
[error]File          : D:\prog_repository\sources\trunk\xrServerEntities\script_storage.cpp
[error]Line          : 748
[error]Description   : ....r. - Зов Припяти\gamedata\scripts\ph_minigun.script:65: attempt to index field 'mgun' (a nil value)

Скрипт оригинальный, из ЗП. Заменял его на версию ЧН - тоже самое. Кто-нибудь вообще делал пулемётные турели в ЗП? Работали ли?

Изменено пользователем Сталкер Лом

Работы на Artstationhttps://www.artstation.com/artist/stalker_lom

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

self.mgun = self.object:get_car()

 

Если он равен nil, то скорее всего турель ты делал не на классе машины. 

+ в ЗП машин как таковых нету, и я не помню если просто её заспавнить будет ли она работать как турель или откажет.

Тебе нужно создать скриптовый класс, который будет наследоваться от класса машины. 

 

В скрипт class_registrator.script вставь это:

cs_register (object_factory, "CCar",             "se_machine.se_machine",            "SWM_MCHN", "machine_s")

https://www.dropbox.com/s/85fcwqv4hjc7h91/se_machine.script - Скачать сам скрипт.

 

И в конфиге машины написать в строчке class класс машины, который ты указал в class_registrator.

 

class = SWM_MCHN

 

Вообще вроде есть ещё одно обозначение, которое в движке забито уже, но я его не помню. 

  • Нравится 2

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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

Подскажите, вот есть к примеру xml файл, который читается сразу движком. И есть предположим поле какое-то, можно как-то из xml перейти в script?

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

 

 


можно как-то из xml перейти в script?

Давай конкретней, товарищ. Ну, в туториалах, к примеру, такое вот есть:

<function_on_stop>xr_effects.pri_a28_talk_ssu_video_end</function_on_stop>
<function_check_start>outro_cond.skadovsk_neutral_cond</function_check_start>
<action id="use" finalize="1">xr_effects.jup_b32_place_scanner</action>

c57d8f0c86.png

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

Конкретнее: файл ui_team_panels_tdm.xml - отвечает за таблицу статистики на TAB которая. Очевидно, что обращение к ней идет прямо из движка. Я могу удалять некоторые поля(ненужные мне). А вот как добавить? Всмысле сделать текстовое поле, текст в котором берется из скрипта.

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

@Jeka81, Может, вы не меня не поняли, но карта давно существует в игре и подключена к остальным. Мне надо, чтобы сама картинка, рисунок, map была на глобальной карте и на ней изображался ГГ стандартной меткой, ну и, конечно, другие метки присущие картам.

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

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

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

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

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

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

Войти

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

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

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