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

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

@Stalkersof как вариант функции из ПС.

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

 

function item_to_belt(obj)
	if obj == nil or alife():object(obj:id()) == nil then 
		return 
	end
	local def_max_weight, def_max_walk_weight, old_max_weight, old_max_walk_weight, new_max_weight, new_max_walk_weight 
	if obj:is_artefact() then
		belt_artefacts[obj:name()] = obj:section()
		def_max_weight = system_ini():r_float("inventory", "max_weight")
		def_max_walk_weight = system_ini():r_float("actor_condition", "max_walk_weight")
		old_max_weight = db.actor:get_actor_max_weight()
		old_max_walk_weight = db.actor:get_actor_max_walk_weight()
		koef_weight = system_ini():r_float(obj:section(),"additional_weight")
		new_max_weight = math.max (def_max_weight, old_max_weight + koef_weight)
		new_max_walk_weight = math.max (def_max_walk_weight, old_max_walk_weight + koef_weight)
		db.actor:set_actor_max_weight(new_max_weight)
 		db.actor:set_actor_max_walk_weight(new_max_walk_weight)
	end
end

function item_to_ruck(obj)
local def_max_weight, def_max_walk_weight, old_max_weight, old_max_walk_weight, new_max_weight, new_max_walk_weight 
	if string.find(obj:section(), "af_") then
		for k,v in pairs(belt_artefacts) do
			if k == obj:name() then
				belt_artefacts[k] = nil
				def_max_weight = system_ini():r_float("inventory", "max_weight")
				def_max_walk_weight = system_ini():r_float("actor_condition", "max_walk_weight")
				old_max_weight = db.actor:get_actor_max_weight()
				old_max_walk_weight = db.actor:get_actor_max_walk_weight()
				koef_weight = system_ini():r_float(obj:section(),"additional_weight")
				new_max_weight = math.max (def_max_weight, old_max_weight - koef_weight)
				new_max_walk_weight = math.max (def_max_walk_weight, old_max_walk_weight - koef_weight)
				db.actor:set_actor_max_weight(new_max_weight)
 				db.actor:set_actor_max_walk_weight(new_max_walk_weight)
			end
		end
	end
end

Каллбеки on_belt и on_ruck должны быть активированы в бинд_сталкер.

 

 

Изменено пользователем Marafon6540
  • Нравится 1
  • Полезно 2
Ссылка на комментарий

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

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

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

@Stalkersof как вариант функции из ПС.

Каллбеки on_belt и on_ruck должны быть активированы в бинд_сталкер.

Воспользовался подсказкой все работает. Но есть один косяк в ОГСР движке артефакт можно скинуть прям с пояса. Т.е такой вот косячок получается. Скрипт не сработает если артефакт скинуть с пояса а не перемещать в рюкзак. Никто не знает как это отследить что арт был сброшен с пояса.

Ссылка на комментарий
4 часа назад, Norman Eisenherz сказал:

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

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

 

2 часа назад, Stalkersof сказал:

Скрипт не сработает если артефакт скинуть с пояса а не перемещать в рюкзак. Никто не знает как это отследить что арт был сброшен с пояса.

Ну так повесь вызов on_ruck на событие on_drop в том же биндере актора, будет при дропе еще уменьшаться вес. Впрочем, я не знаю зачем городить эти огороды, в ОГСР же по-любому должно в движке быть добавлено свойство арта на вес, неужели его там нет?

 

P.S.

https://github.com/OGSR/OGSR-Engine/wiki/Подробное-описание-изменений#new-properties-for-artifacts

:grin2:

 

10.12.2024 в 07:11, Stalkersof сказал:

Что это за set_int_arg0(24) и такого метода не существует obj:get_hud_shared_str()

ОГСР движок

Конечно такого метода нет, разные движки же. В SA xray-extensions. В ОГСР должны быть свои новые методы для этого всего, читай доку по движку. Имя худ секции можно просто из конфига прочитать как строковой параметр, разницы нет.

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

Код типовой, в обычных апдейтах работает. Меню загрузки сейвов обновляется только один раз при создании окна.

  • Полезно 1

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

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

Ну так повесь вызов on_ruck на событие on_drop в том же биндере актора, будет при дропе еще уменьшаться вес. Впрочем, я не знаю зачем городить эти огороды, в ОГСР же по-любому должно в движке быть добавлено свойство арта на вес, неужели его там нет?

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

Изменено пользователем Stalkersof
Ссылка на комментарий
10.12.2024 в 02:45, RayTwitty сказал:
-- впилить
elseif self.item:is_artefact() then
...
end

Впилил...

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

--[[-----------------------------------------------------------------------------------------------
 File         : sa_hud_animations_mgr.script
 Description  : Дополнительные анимации худа
 Copyright    : Shadows Addon
 Author       : Ray Twitty aka Shadows
 Date         : 17.12.2012
 Last edit    : 26.12.2018
---------------------------------------------------------------------------------------------------
 * Описание возможностей
 - анимация ходьбы (moving)
 - анимации удара прикладом (kick), учитывающие подствольник и затворную задержку (параметры kick_enabled, kick_hit_power, kick_hit_impulse, kick_hit_distance, kick_hit_time, kick_sound_time)
 - исправление сброса анимации при попытках: включить подствольник, стрелять, перезаряжаться и использовать автомобили на расстоянии
 - скрытие патронов у дробовиков после стрельбы и перезарядки (параметр cartridge_bone)
--]]-----------------------------------------------------------------------------------------------
local hud_animations_mgr
local MAX_ANIM_COUNT = 8
---------------------------------------------------------------------------------------------------
local weapon_states = {
    idle = 0,
    fire = 1,
    fire2 = 2,
    reload = 3,
    showing = 4,
    hiding = 5,
    hidden = 6,
    misfire = 7,
    mag_empty = 8,
    switch = 9
}
---------------------------------------------------------------------------------------------------
local missile_states = {
    hidden = 0,
    showing = 1,
    idle = 2,
    attack_begin = 3,
    attack_idle = 4,
    attack_act = 5,
    attack_end = 6,
    empty = 7,
    hiding = 8,
    playing = 9
}
--[[-----------------------------------------------------------------------------------------------
 * HUD ANIMATIONS MANAGER
--]]-----------------------------------------------------------------------------------------------
class "CHudAnimationsMgr"
function CHudAnimationsMgr:__init()
    self.last_item_id = 0
    self.animation = ""
    self.animation_length = 0
end
---------------------------------------------------------------------------------------------------
function CHudAnimationsMgr:update()
    self.item = db.actor:active_item()
    if self.item then
        self.item_id = self.item:id()
        self.current_state = self.item:get_hud_item_state()
        if self.last_item_id ~= self.item_id then
            self:update_item_data()
            self:reset_animation()
            self.last_item_id = self.item_id
        end
        if self:is_idle_state() then
            self:moving_and_idle_animation()
        else
            self:reset_animation()
        end
        if self.last_current_state ~= self.current_state then
            if self.item:is_weapon_shotgun() and self.cartridge_bone then
                if self.current_state == weapon_states.fire or self.current_state == weapon_states.reload then
                    self.item:set_hud_bone_visible(self.cartridge_bone, 1)
                else
                    self.item:set_hud_bone_visible(self.cartridge_bone, 0)
                end
            end
            self.last_current_state = self.current_state
        end
    end
end
---------------------------------------------------------------------------------------------------
function CHudAnimationsMgr:moving_and_idle_animation()
    if self.animation ~= "kick" then
        if db.actor:is_actor_running() or db.actor:is_actor_walking() then
            if self.animation ~= "moving" then
                self:play_hud_animation(self:get_type_animation("moving"))
                self.animation = "moving"
            end
        elseif db.actor:is_actor_sprinting() then
            if self.animation ~= "sprint" then
                self:play_hud_animation(self:get_type_animation("sprint"))
                self.animation = "sprint"
            end
        else
            if self.animation ~= "idle" then
                self:play_hud_animation(self:get_type_animation("idle"))
                self.animation = "idle"
            end
        end
    end
end
---------------------------------------------------------------------------------------------------
function CHudAnimationsMgr:kick_animation()
    if self.animation ~= "kick" and self.kick_enabled and self:is_idle_state() and get_actor_data("camera_type") == EActorCameras.eacFirstEye then
        self:play_hud_animation(self:get_type_animation("kick"))
        self.animation = "kick"
        start_real_timer("kick_end", self.animation_length, "sa_hud_animations_mgr.get_hud_animations_mgr():reset_animation")
        start_real_timer("kick_hit", self.kick_hit_time, "sa_hud_animations_mgr.get_hud_animations_mgr():kick_hit")
        start_real_timer("kick_sound", self.kick_sound_time, "sa_hud_animations_mgr.get_hud_animations_mgr():kick_sound")
    end
end
---------------------------------------------------------------------------------------------------
function CHudAnimationsMgr:get_type_animation(state)
    if self.item:is_weapon_gl() then
        if get_weapon_data(self.item, "grenade_mode") then
            if state == "idle" then
                return "anim_idle_g"
            elseif state == "moving" then
                return "anim_idle_g_moving"
            elseif state == "sprint" then
                return "anim_idle_g_sprint"
            elseif state == "kick" then
                return "anim_kick_g"
            end
        elseif get_weapon_data(self.item, "is_attached_grenade_launcher") or read_line(self.section, "grenade_launcher_status") == 1 then
            if state == "idle" then
                return "anim_idle_gl"
            elseif state == "moving" then
                return "anim_idle_gl_moving"
            elseif state == "sprint" then
                return "anim_idle_gl_sprint"
            elseif state == "kick" then
                return "anim_kick_gl"
            end
        end

            elseif self.item:is_weapon_pistol() and self:is_mag_empty() then
        if state == "idle" then
            return "anim_empty"
        elseif state == "moving" then
            return "anim_idle_moving_empty"
        --elseif state == "sprint" then
            --return "anim_idle_sprint_empty"
        elseif state == "kick" then
            return "anim_kick_empty"
        end

            elseif get_clsid(self.item) == clsid.wpn_bm16_s then
        local mag_size = self.item:get_ammo_in_magazine()
        if mag_size == 1 then
            if state == "idle" then
                return "anim_idle_1"
            elseif state == "moving" then
                return "anim_idle_moving_1"
            end
        elseif mag_size == 2 then
            if state == "idle" then
                return "anim_idle_2"
            elseif state == "moving" then
                return "anim_idle_moving_2"
            end
        end

        elseif self.item:is_artefact() then
            if state == "idle" then
                return "anim_idle"
            elseif state == "moving" then
                return "anim_idle"
            elseif state == "sprint" then
                return "anim_idle_sprint"
            end
    end

    if state == "idle" then
        return "anim_idle"
    elseif state == "moving" then
        return "anim_idle_moving"
    elseif state == "sprint" then
        return "anim_idle_sprint"
    elseif state == "kick" then
        return "anim_kick"
    end
end
---------------------------------------------------------------------------------------------------
function CHudAnimationsMgr:play_hud_animation(anim_type)
    if anim_type then
        local anim_name = read_line(self.hud_section, anim_type, "string")
        if anim_name then
            local animations_list = self:fill_animations_list(anim_name)
            if table.size(animations_list) > 0 then
                anim_name = animations_list[math.random(#animations_list)]
                self.item:play_hud_animation(anim_name, true)
                self.animation_length = self.item:get_hud_animation_length(anim_name)
            end
        end
    end
end
---------------------------------------------------------------------------------------------------
function CHudAnimationsMgr:update_item_data()
    self.section = self.item:section()
    self.hud_section = get_hud_data(self.item, "hud_section")
    self.cartridge_bone = read_line(self.hud_section, "cartridge_bone", "string")
    self.kick_enabled = read_line(self.section, "kick_enabled", "bool")
    if self.kick_enabled then
        self.kick_hit_power = read_line(self.section, "kick_hit_power")
        self.kick_hit_impulse = read_line(self.section, "kick_hit_impulse")
        self.kick_hit_distance = read_line(self.section, "kick_hit_distance")
        self.kick_hit_time = read_line(self.section, "kick_hit_time")
        self.kick_sound_time = read_line(self.section, "kick_sound_time", "number", system_ini(), self.kick_hit_time)
    end
end
---------------------------------------------------------------------------------------------------
function CHudAnimationsMgr:fill_animations_list(anim_name)
    local animations_list = {}
    if anim_name then
        table.insert(animations_list, anim_name)
        for i = 2, MAX_ANIM_COUNT do
            if self.item:has_hud_animation(anim_name..i) then
                table.insert(animations_list, anim_name..i)
            end
        end
    end
    return animations_list
end
---------------------------------------------------------------------------------------------------
function CHudAnimationsMgr:is_idle_state()
    if not get_actor_data("zoom_mode") then
        if self.item:is_weapon() then
            return self.current_state == weapon_states.idle
        else
            return self.current_state == missile_states.idle
        end
    end
end
---------------------------------------------------------------------------------------------------
function CHudAnimationsMgr:is_mag_empty()
    return self.item:get_ammo_in_magazine() == 0
end
---------------------------------------------------------------------------------------------------
function CHudAnimationsMgr:reset_animation()
    self.animation = ""
    self.animation_length = 0
end
---------------------------------------------------------------------------------------------------
function CHudAnimationsMgr:on_keyboard(dik, keyboard_action)
    if self.item and self.item:is_weapon() then
        if keyboard_action == key_events.pressed then
            if dik == bind_to_dik(key_bindings.kEXT_1) then
                self:kick_animation()
            elseif dik == bind_to_dik(key_bindings.kWPN_RELOAD) then
                if self.item:get_ammo_in_magazine() ~= get_weapon_data(self.item, "mag_size") then
                    self:reset_animation()
                end
            elseif dik == bind_to_dik(key_bindings.kUSE) then
                local target_obj = level.get_target_obj()
                if target_obj and target_obj:is_holder() then
                    self:reset_animation()
                end
            end
        elseif keyboard_action == key_events.released then
            if dik == bind_to_dik(key_bindings.kWPN_FIRE) then
                if self:is_mag_empty() then
                    self:reset_animation()
                end
            elseif dik == bind_to_dik(key_bindings.kWPN_FUNC) then
                if read_line(self.section, "grenade_launcher_status") == 2 and not get_weapon_data(self.item, "is_attached_grenade_launcher") then
                    self:reset_animation()
                end
            end
        end
    end
end
---------------------------------------------------------------------------------------------------
function CHudAnimationsMgr:kick_hit()
    local target_obj = level.get_target_obj()
    local target_dist = level.get_target_dist()
    if target_obj and target_dist <= self.kick_hit_distance then
        make_hit(target_obj, self.kick_hit_power, self.kick_hit_impulse, hit.wound, device().cam_dir, db.actor, get_bone_name_by_id(target_obj, level.get_target_element()))
    end
end
---------------------------------------------------------------------------------------------------
function CHudAnimationsMgr:kick_sound()
    play_safe_sound_object("weapons\\swing_"..math.random(4))
end
--[[-----------------------------------------------------------------------------------------------
 * INIT
--]]-----------------------------------------------------------------------------------------------
function get_hud_animations_mgr()
    if not hud_animations_mgr then
        hud_animations_mgr = CHudAnimationsMgr()
    end
    return hud_animations_mgr
end

Но!

Для артефакта скрипт почему-то ситуацию отрабатывает зеркально относительно стволов. Триггер на включение той или иной анимки срабатывает, когда арт  в слоте не активен. Т.е., получается арт в руках - ждём. Убрали из рук - и вот здесь пытаемся играть анимку. Это как понимать? :).

Ссылка на комментарий
9 часов назад, Norman Eisenherz сказал:

Меню загрузки сейвов обновляется только один раз при создании окна.

Ну если load_dialog:Update() вызывается один раз, тогда никак:pardon:Хотя ЕМНИП в главном меню оно работало нормально, можно попробовать оттуда пробросить вызов.

 

9 часов назад, Stalkersof сказал:

Мне это надо для индикатора переносимого веса.

Это который на худе типа как в ЗП? Так для него просто нужно получить текущий вес инвентаря и сравнить с db.actor:get_actor_max_weight() или db.actor:get_actor_max_walk_weight(). Зачем второй раз считать всю эту заморочь, если движок уже посчитал?)

 

6 часов назад, Капрал Хикс сказал:

Убрали из рук - и вот здесь пытаемся играть анимку. Это как понимать?

Возможно стейты (номера) другие, скрипт работает для оружия и гранат/болта. Никогда эту фичу с артом не ковырял, может там другие стейты идут...

 

В методе is_idle_state попробуй замени if self.item:is_weapon() then на if self.item:is_weapon() or self.item:is_artefact() then. У арта айдл вроде тоже нулевой стейт.

  • Нравится 1
  • Полезно 2
Ссылка на комментарий
26 минут назад, RayTwitty сказал:

Возможно стейты (номера) другие... У арта айдл вроде тоже нулевой стейт.

@RayTwitty , а где это определяется/каким образом посмотреть можно?

Ссылка на комментарий
10 часов назад, RayTwitty сказал:

Это который на худе типа как в ЗП? Так для него просто нужно получить текущий вес инвентаря и сравнить с db.actor:get_actor_max_weight() или db.actor:get_actor_max_walk_weight(). Зачем второй раз считать всю эту заморочь, если движок уже посчитал?)

А как его получить? Надо перебрать все предметы и вычислить их вес и все сложить или существует какой-то метод для вывода текущего веса.

 

Да и методы:

db.actor:get_actor_max_weight()

или

db.actor:get_actor_max_walk_weight()

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

 

Пс. Есть метод для получения текущего веса в инвентаре.

db.actor:get_total_weight()

т.е. перебирать все предметы как делали раньше, нет необходимости.)))

Изменено пользователем Stalkersof
Ссылка на комментарий
10 hours ago, RayTwitty said:

ЕМНИП в главном меню оно работало нормально

Нет, все равно одно обновление. Может, дело в движковом выводе окна – в простом скриптовом окне обновление постоянное.

  • Полезно 1

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Ссылка на комментарий
13 часов назад, RayTwitty сказал:

У арта айдл вроде тоже нулевой стейт.

Всё работает как нужно. Теперь ещё одна фишечка в копилку неиспользованных ранее.

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

Такой код не дает вывода в консоль, хотя в [_g.script] применяется именно log(str).

 

Если в старом варианте вывести не новую переменную, а сам счетчик time_global(), будет повтор одинакового значения – дело действительно в паузе и, если ее снять, при любом обращении к меню загрузки игра некоторое время будет жить своей жизнью, что нежелательно.

 

Можно бы сделать счетчик циклов в самом скрипте, но значение device().time_delta остается на 0, а аргумент delta, в отличие от биндеров объектов, для окна не существует – неясно, какая частота обновления окна.

 

Edit: направление было правильное, и какой-то неточный апдейт можно намутить. Соотношение циклов окна и счетчика в мс ~1:5, при загруженной игре ~1:50. Какие значения будут на другом ПК, предсказать сложно.

Изменено пользователем Norman Eisenherz
  • Полезно 1

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

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

@Norman Eisenherz у меня следующий код работает без проблем в главном меню:

function main_menu:Update()
	CUIScriptWnd.Update(self)

	log("main_menu:Update")
end

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

 

16 часов назад, Norman Eisenherz сказал:

Такой код не дает вывода в консоль, хотя в [_g.script] применяется именно log(str).

Подразумевалось, что этот баян (16 летней давности) уже известен и у тебя есть функция на замену для вывода данных (там же комментарий написан). Выводи любым способом, да хоть тем же get_console():execute("load ~~~ ВАШ ТЕКСТ"), как это делали бородатые дядьки АМК)

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

@Norman Eisenherz 3 дня выясняли что не так с апдейтом, почему он не работает, даже в игру полез проверять, как оказалось, что все работало, а дело совсем в другом :facepalm:Я же об этом еще в этом посте спрашивал...

 

Значит кури класс CRenderDevice - https://www.amk-team.ru/forum/topic/7450-spravochnik-po-funkcijam-i-klassam/?do=findComment&comment=272244

 

time_global()\device().time_global() в меню использовать смысла нет, пробуй другие счетчики, например device().frame, а дельта между кадрами device().f_time_delta (у меня тоже нулевая, но я дальше главменю не загружал).

 

Работу всего этого можно тестить с включенным vsync, залочит на 60 кадров, без него будет улетать на сотни-тысячи, разницу в показаниях видно будет сразу, "другой ПК" не нужен.

 

P.S. Вопрос риторический - зачем считать время (его мы не получим), если можно считать скорость и расстояние (скролла)? Единственное, как учесть FPS, но это см. выше.

Изменено пользователем RayTwitty
  • Спасибо 1
  • Нравится 1
Ссылка на комментарий

Эксперимент с device() описан чуть выше.

 

10 hours ago, RayTwitty said:

можно считать скорость и расстояние (скролла)

Их можно считать на уровне скриптов? Не просто править множителями до уровня "так пойдет"?

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Ссылка на комментарий
14 часов назад, Norman Eisenherz сказал:

Их можно считать на уровне скриптов? Не просто править множителями до уровня "так пойдет"?

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

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

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

Подсветка при выборе смещается с шагом, равным высоте элемента списка – можно регулировать только частоту переключения. Отношение 5:1 или 50:1 – как раз результат теста в игре, и множители подставлены на уровне ощущений.

 

Движок обычный, и начинку я могу только читать.

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

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

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

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

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

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

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

Войти

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

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

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