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

Скриптование


Svoboда

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

21 час назад, Купер сказал:

страшно, конечно. Там, по идее, по дельте времени ~ 1раза в секунду более, чем достаточно.

В x-ray extensions вроде есть коллбэк на перемещение в слот. Хм, как бы его правильно использовать, пример нужен.

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


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

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

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

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

Подозреваю, вот сюда:

function CHudAnimationsMgr:get_type_animation(state)

Нужно как-то вклинить кусок кода с проверкой на то, что в руках артефакт.

Но у меня if self.item:is_artefact() и if get_clsid(self.item) == clsid.artefact_s варианты не проконали. Просто анимка не работает.

Ну а дальше проще...

    if state == "idle" then
        return "anim_idle"
    elseif state == "moving" then
        return "anim_idle"
    elseif state == "sprint" then
        return "anim_idle_sprint"...

Но у меня лыжи не едут.

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


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

Но!

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

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


Ссылка на сообщение
13 часов назад, RayTwitty сказал:

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

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

  • Нравится 2

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


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

Есть мод на умное выпадение частей монстров, если в кость запчасти попала пуля, часть не выдаётся. Так вот там кости учитываются по номерам. Вопрос - где номера эти костей в моделях смотреть? Как эта нумерация высчитывается?

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


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

@ted.80 , благодарю. Нашёл тулзу для просчёта, dump_ogf. Позволяет узнать всё о модели.

https://synthira.ru/load/drugie_igry/s_t_a_l_k_e_r/s_t_a_l_k_e_r_2/dump_ogf/24-1-0-3265

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

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


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

Как добавить в скрипт проверку, что в опциях игры нажата определённая кнопка-"флажок"? Сама кнопка в опциях "Игра" успешно добавлена, флажок работает.

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


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

Столкнулся с весьма мерзким явлением. При сохранении (неважно каком - квиксейве или ручном) и попытке загрузиться с него происходит безлоговый вылет. При повторном заходе в игру сохранение исправно загружается. То же самое происходит даже с автосейвами при заходе на новую локацию (в т.ч. через чит-телепорт). Загрузка автосейва - безлоговый вылет. При перезаходе в игру автосейв грузится. Куда хоть копать? Уже попутно пару косяков отловил в попытке понять, в чём соль, а толку ноль.

Платформа ТЧ + x-ray extensions.

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


Ссылка на сообщение
(изменено)

@naxac, вопрос как к специалисту. Безлоговый вылет при загрузке любого сохранения, но при этом при перезаходе в игру этот же любой сейв грузится нормально. Я понимаю, что телепатов нет, но хотелось бы знать к чему такие симптомы. Я так понимаю, в сейв пишется что-то непотребное, которое потом грузится нормально... Куда хоть копать в первую очередь? Net_spawn функции, bind-скрипты? Если бы вылет был стабильным, а так-то оно грузится... со второго раза.

Изменено пользователем Капрал Хикс

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


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

Такой вопрос...

Метод self.start_btn:SetText("") для ui_main_menu.script поддерживает кириллицу вот тут ""? Пробую сослаться на стринговый файл текста с кириллицей - отображает id строки. Пробую вставить в "" кириллицу - отображает кракозябры.

Это для текста "нажмите любую клавишу для перехода к игре", для ТЧ, пауза при загрузке игры как в ЗП.

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


Ссылка на сообщение
(изменено)
14 часов назад, Norman Eisenherz сказал:

при прямом вводе – переводить скрипт в кодировку ANSI или Windows-1251.

Помог этот вариант, мододелам на заметку.

Изменено пользователем Капрал Хикс

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


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

Стоит фишка на использование горячих клавиш Enter и Delete для загрузки/удаления сохранений в соотв. меню. Так вот если курсор не стоит на строке сохранения, при нажатии клавиши подтверждения удаления сохранки вылет:

[error]Expression    : fatal error
[error]Function      : CScriptEngine::lua_error
[error]File          : E:\stalker\sources\trunk\xr_3da\xrGame\script_engine.cpp
[error]Line          : 73
[error]Description   : <no expression>
[error]Arguments     : LUA error: ... of chernobyl\gamedata\scripts\ui_load_dialog.script:234: attempt to index local 'item' (a nil value)

Как бы доработать скрипт?

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

-- File:        UI_LOAD_DIALOG.SCRIPT
-- Description: Load Dialog for STALKER
-- Created:     28.10.2004
-- Copyright:   2004 разработчик серии игр
-- Author:      Serhiy Vynnychenko (narrator@компания-разработчик (признана нежелательная)-game.kiev.ua)
-- Version:     0.5

class "load_item" (CUIListItemEx)

function load_item:__init() super()
    self.file_name        = "filename"
    self:SetWndRect        (0,0,430,22)

    local ca = 255
    local cr = 216
    local cg = 186
    local cb = 140

    self.fn                = CUIStatic    ()
    self.fn:SetAutoDelete    (true)
    self:AttachChild        (self.fn)
    self.fn:SetWndRect        (0,0,230,22)
    self.fn:SetText            ("filename")
    self.fn:SetFont            (GetFontLetterica18Russian())
    self.fn:SetTextColor    (ca,cr,cg,cb)

    self.fage            = CUIStatic    ()
    self.fage:SetAutoDelete    (true)
    self:AttachChild        (self.fage)
    local shirik = (device().height/device().width > 1.5)
    local fageX = shirik and 250 or 325
    self.fage:SetWndRect    (fageX,0,150,22)
    self.fage:SetText        ("fileage")
    self.fage:SetFont        (GetFontLetterica16Russian())
    self.fage:SetTextColor    (ca,cr,cg,cb)
end

class "load_dialog" (CUIScriptWnd)

function load_dialog:__init() super()
   self:InitControls()
   self:InitCallBacks()
   self:FillList()
end

function load_dialog:__finalize()

end

function load_dialog:FillList()
    local f = getFS()
    local flist = f:file_list_open_ex("$game_saves$",bit_or(FS.FS_ListFiles,FS.FS_RootOnly),"*.sav")
    local f_cnt = flist:Size()

    flist:Sort(FS.FS_sort_by_modif_down)

    for    it=0, f_cnt-1     do
        local file    = flist:GetAt(it)
        local file_name = string.sub(file:NameFull(), 0, (string.len(file:NameFull()) - 4))
        local date_time = "[" .. file:ModifDigitOnly() .. "]"
        --menu_item = .. 
        self:AddItemToList(file_name, date_time)
    end
end

function load_dialog:InitControls()
    self:Init(0,0,1024,768)

    local xml             = CScriptXmlInit()
    local ctrl
    xml:ParseFile("ui_mm_load_dlg.xml")

    xml:InitStatic("back_video", self)

    xml:InitStatic("background",            self)
    --xml:InitStatic("newspaper_video",        self)

    self.form = xml:InitStatic("form",        self)

    xml:InitStatic("form:caption",            self.form)

    ctrl = xml:InitStatic("form:picture",        self.form)
    ctrl:SetWindowName("static_pict")

    xml:InitStatic("form:file_info",        self.form)

    self.file_caption     = xml:InitStatic("form:file_caption",    self.form)
    self.file_data        = xml:InitStatic("form:file_data",    self.form)

    xml:InitFrame("form:list_frame",        self.form)

    ctrl = xml:InitList("form:list",         self.form)
    ctrl:ShowSelectedItem(true)
    self:Register(ctrl, "list_window")

    ctrl = xml:Init3tButton("form:btn_load",    self.form)
    self:Register(ctrl, "button_load")

    ctrl = xml:Init3tButton("form:btn_delete",    self.form)
    self:Register(ctrl, "button_del")

    ctrl = xml:Init3tButton("form:btn_cancel",    self.form)
    self:Register(ctrl, "button_back")

    self.message_box = CUIMessageBoxEx()
    self:Register(self.message_box,"message_box")
end

function load_dialog:InitCallBacks()
    self:AddCallback("button_load",        ui_events.BUTTON_CLICKED,             self.OnButton_load_clicked,    self)
    self:AddCallback("button_back",        ui_events.BUTTON_CLICKED,             self.OnButton_back_clicked,    self)
    self:AddCallback("button_del",        ui_events.BUTTON_CLICKED,             self.OnButton_del_clicked,    self)
    self:AddCallback("message_box",        ui_events.MESSAGE_BOX_YES_CLICKED,    self.OnMsgYes,            self)
    self:AddCallback("message_box",        ui_events.MESSAGE_BOX_OK_CLICKED,     self.OnMsgYes,            self)

    self:AddCallback("list_window", ui_events.LIST_ITEM_CLICKED,         self.OnListItemClicked,        self)
    self:AddCallback("list_window", ui_events.WINDOW_LBUTTON_DB_CLICK,    self.OnListItemDbClicked,    self)
end

function file_exist(fname)
    local f = getFS()
    local flist = f:file_list_open_ex("$game_saves$",bit_or(FS.FS_ListFiles,FS.FS_RootOnly) , fname)
    local f_cnt = flist:Size()

    if f_cnt > 0 then
        return true
    else
        return false
    end
end

function delete_save_game(filename)
    local save_file        = filename .. ".sav"
    local dds_file        = filename .. ".dds"

    local f = getFS()

    f:file_delete("$game_saves$",save_file)

    if file_exist(dds_file) then
        f:file_delete("$game_saves$", dds_file)
    end
end

function AddTimeDigit(str, dig)
    if (dig > 9) then
        str = str .. dig
    else
        str = str .. "0" .. dig
    end

    return str

end

function file_data(fname)
    local f = getFS()
    local flist = f:file_list_open_ex("$game_saves$",bit_or(FS.FS_ListFiles,FS.FS_RootOnly) , fname .. ".sav")
    local f_cnt = flist:Size()

    if f_cnt > 0 then
        local file        = flist:GetAt(0)
        local sg = CSavedGameWrapper(fname)

        local y,m,d,h,min,sec,ms = 0,0,0,0,0,0,0
        y,m,d,h,min,sec,ms = sg:game_time():get(y,m,d,h,min,sec,ms)

        local date_time = ""

        date_time = AddTimeDigit(date_time, h)
        date_time = date_time .. ":"
        date_time = AddTimeDigit(date_time, min)
        date_time = date_time .. " "
        date_time = AddTimeDigit(date_time, m)
        date_time = date_time .. "/"
        date_time = AddTimeDigit(date_time, d)
        date_time = date_time .. "/"

        date_time = date_time .. y

        --string.format("[%d:%d:%d %d]",m,d,h,min,y)
        local health = string.format("\\n%s %d%s", game.translate_string("ui_inv_health"),sg:actor_health()*100,"%")

        return game.translate_string("st_level") .. ": " .. game.translate_string(sg:level_name()) .. "\\n" .. game.translate_string("ui_inv_time")..": " .. date_time .. health
    else
        return "no file data"
    end
end

function load_dialog:OnListItemClicked()
    local list_box        = self:GetListWnd("list_window")

    if list_box:GetSize()==0 then return end

    local picture        = self:GetStatic("static_pict")
    local itm_index        = list_box:GetSelectedItem()
    local item        = list_box:GetItem(itm_index)

    if item == nil then
        self.file_caption:SetText    ("")
        self.file_data:SetText        ("")
        picture:InitTexture        ("ui\\ui_noise")
        return
    end

    local item_text            = item.fn:GetText()
    self.file_caption:SetText    (item_text)
    self.file_data:SetText        (file_data(item_text))

    if file_exist(item_text .. ".sav") ~= true then
        list_box:RemoveItem(itm_index)
        return
    end

    if file_exist(item_text .. ".dds") then
        picture:InitTexture(item_text)
    else
        picture:InitTexture("ui\\ui_noise")
    end
end

function load_dialog:OnListItemDbClicked()
    self:OnButton_load_clicked()
end

function load_dialog:OnMsgYes()
    local list = self:GetListWnd("list_window")
    local index = list:GetSelectedItem()

    if index == 4294967295 then return end

    if self.msgbox_id == 1 then
        local item  = list:GetItem(index)
        local fname = item.fn:GetText()

        delete_save_game    (fname)

        list:RemoveItem        (index)

        self:OnListItemClicked()
    elseif self.msgbox_id == 2 then
        self:load_game_internal()
    end

    self.msgbox_id = 0
end

function load_dialog:load_game_internal()
    local console = get_console()
    local list = self:GetListWnd("list_window")

    if list:GetSize()==0 then return end

    local index = list:GetSelectedItem()

    if index == 4294967295 then return end

    local item  = list:GetItem(index)
    local fname = item.fn:GetText()

    if (alife() == nil) then
        console:execute    ("disconnect")
        console:execute    ("start server(" .. fname .. "/single/alife/load) client(localhost)")
    else
        console:execute    ("load " .. fname)
    end
end

function load_dialog:OnButton_load_clicked()
    local console = get_console()
    local list = self:GetListWnd("list_window")

    if list:GetSize()==0 then return end

    local index = list:GetSelectedItem()

    if index == 4294967295 then return end

    local item        = list:GetItem(index)
    local fname        = item.fn:GetText()

    if (alife() == nil) then

        if valid_saved_game(fname) then
            self:load_game_internal()
        else
            self.msgbox_id            = 0
            self.message_box:Init        ("message_box_invalid_saved_game")
            self:GetHolder():start_stop_menu(self.message_box, true)
        end

        return
    end

    if valid_saved_game(fname) then
        self.msgbox_id = 2
        self.message_box:Init("message_box_confirm_load_save")
        self:GetHolder():start_stop_menu(self.message_box, true)
    else
        self.msgbox_id            = 0
        self.message_box:Init        ("message_box_invalid_saved_game")
        self:GetHolder():start_stop_menu(self.message_box, true)
    end
end

function load_dialog:OnButton_back_clicked()
    self:GetHolder():start_stop_menu    (self.owner, true) --new(show main window)
    self:GetHolder():start_stop_menu    (self,true)
    self.owner:Show                (true)
end

function load_dialog:OnButton_del_clicked()
    local list = self:GetListWnd("list_window")

    if list:GetSize()==0 then return end
    local index = list:GetSelectedItem()

    if index == 4294967295 then return end

    self.msgbox_id = 1
    self.message_box:Init("message_box_delete_file_name")
    self:GetHolder():start_stop_menu(self.message_box, true)
end

function load_dialog:OnKeyboard(dik, keyboard_action)  --virtual function
--[[
   ui_base_dialog.base_dialog.OnKeyboard(self,dik,keyboard_action)

   DIK_RETURN = 28
   WINDOW_KEY_PRESSED = 6

    if dik == DIK_RETURN and keyboard_action == WINDOW_KEY_PRESSED then
        self:GetHolder():start_stop_menu    (self.owner, true) --new
        self:GetHolder():start_stop_menu    (self,true)
        self.owner:Show                (true)
    end

    return true
--]]
    CUIScriptWnd.OnKeyboard(self,dik,keyboard_action)
    local bind = dik_to_bind(dik)

    if keyboard_action == ui_events.WINDOW_KEY_PRESSED then
        if dik == DIK_keys.DIK_RETURN or dik == DIK_keys.DIK_SPACE then --* Enter/Space
            self:OnButton_load_clicked()
        elseif dik == DIK_keys.DIK_DELETE or dik == DIK_keys.DIK_DECIMAL then --* Delete/.(Numpad)
            self:OnButton_del_clicked()
        elseif dik == DIK_keys.DIK_ESCAPE or dik == DIK_keys.DIK_HOME then --* Esc/ Home /DIK_BACK - Back Space
            self:OnButton_back_clicked()
        end
    end

    return true
end

function load_dialog:AddItemToList(file_name, date_time)
    local _itm            = load_item()
    _itm.fn:SetText            (file_name)
    _itm.fage:SetText        (date_time)

    local list_box            = self:GetListWnd("list_window")
    list_box:AddItem        (_itm)
end
 

 

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


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

Или элемент списка не выделен?

Именно так, курсор стоит не на строке.

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


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

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

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


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

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

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