Скриптование - Страница 637 - Скрипты / конфиги / движок - AMK Team
Перейти к контенту

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

Тема для обсуждения скриптов всего и всех в серии игр STALKER.


Задавая вопрос (!):
1. Внимательно изучите суть вопроса. Вопрос должен соответствовать выбранной Вами темы. Это поможет сохранить порядок и читабельность темы, а также облегчит поиск и понимание сего;
2. Изучите то, что уже есть в теме (пролистайте "руками", воспользуйтесь поиском на форуме);
3. Изучите информацию которая может вам помочь:

 
 

Stalkerin. Там есть много хороших статей касательно данной темы.
Уроки по модостроению. Есть рабочие примеры готовых скриптов различного назначения.

 

Справочное руководство по языку Lua 5.1
https://www.mediawiki.org/wiki/Extension:Scribunto/Lua_reference_manual/ru
Справочник по функциям и классам. Собрано много информации по функциям и классам, не всем, но по основные сведения предоставлены.

4. Дабы не превращать обсуждение в "кашу" разной информативной направленности, задавайте несколько вопросов по порядку (в разных постах) после того, как получите ответ на предыдущий вопрос;
5. "Спасибо" и тому подобное - будьте так любезны в ПМ. Если не любите писать в ПМ, в конце вопроса напишите фразу: "Заранее спасибо!" - или что-то в этом духе;
6. ПОЖАЛУЙСТА! Указывайте, для какой игры Вам необходима информация (ТЧ, ЧН, ЗП), если стоит мод - укажите название мода;
7. Если Вы что-то сделали и результат не такой, какой Вами задумывался, то, пожалуйста, приводите коды которые Вы изменяли/писали целиком! Это поможет другим правильно ответить на Ваш вопрос, а также оградит Вас от лишней писанины.
8. Оформляйте сообщение. Пользуйтесь тегами для того, чтобы отделить код от текста. Пишите грамотно - ПОЛЬЗУЙТЕСЬ ЗНАКАМИ ПРЕПИНАНИЯ.
9. И помните: «Правильно заданный вопрос – половина ответа».

 

Какие вопросы следует задавать, а какие нет...

 

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

 

Вопросы которые будут удалятся, следовательно их задавать не нужно:
-- Где находится та или иная функция?
Для ответа используем поиск по словам среди файлов оригинальной игры или мода, если объект поиска относится к нему, при помощью программы, которая Вам наиболее симпатизирует;
-- Как сделать что-то/то-то?
С подобными вопросами, либо в "ковырялки", где Вам вероятнее всего так же не ответят, либо выдвигаем мысли, подкреплённые теорией, практикой (идеальный вариант) и здравым рассудком;
-- Вопросы со смыслом: "сделайте", "совместите" и подобными глаголами повелительного наклонения.
-- К тому же удалению будут подвергаться вопросы, в которых масштабно не используются теги, для отделения кода и цитат от основного текста, а также не вписан в спойлер код размером превышающие семь строк.
Ответ на возможно возникший вопрос: В какую тему можно обратиться по поводу логики и спавна объектов?
В тему "ковырялок" соответствующей версии игры, для которой Вы задаёте вопрос.

И последнее: очень рекомендовано к прочтению Правила форума
 


  • Спасибо 1
  • Полезно 2
Ссылка на комментарий
https://www.amk-team.ru/forum/topic/6185-skriptovanie/

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

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

@naxac Сменил класс для двух сброшенных артефактов: вылет "нет объекта ГГ" при проверке дистанции в измененном [se_artefact.script]. Как такое может быть, если ГГ грузится первым?

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

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

Шпаргалка

@Norman Eisenherz , ты используешь переменную клиентского актера db.actor. В момент появления серверного объекта артефакта клиентского объекта актера ещё нет. Используй либо серверный объект актера alife():actor(), либо проверку на наличие db.actor.

@Капрал Хикс , может быть, на net_destroy какое-нибудь непотребство происходит? В какой-нибудь схеме сбой, или в каком-нибудь биндере?... Ещё, вроде, что-то такое было, если не убрать перед дестроем статик с экрана, добавленный через AddDialogToRender.

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

Аддон для ОП-2.09.2: Яндекс/Google/GitHub/Тема на AP-PRO

naxac.gif

Что-то туплю видимо, давно lua не ковырял :biggrin:

 

Есть локальная функция в модуле:

local function myfunc()
    print("myfunc !!!")
end

Нужно вызвать ее по имени. Но, имя генерируется в другом месте. Первая мысль была сделать просто ["myfunc"](), но не сработало, как и this["myfunc"]()

Так, как сделать? Через loadstring что ли? loadstring(script_name()..".myfunc()")() выглядит как дичь же :biggrin: (но работает, правда не с локальными функциями, что логично)

Telegram-канал RayTwitty Space

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

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

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

При вводе string_id надо добавлять game.translate_string, при прямом вводе – переводить скрипт в кодировку ANSI или Windows-1251.

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

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

Шпаргалка

@Капрал Хикс , если self.start_btn - это статик, а не кнопка, то у него есть метод SetTextST("string_id"), которому game.translate_string не нужно, он автоматически транслирует строку.

  • Нравится 2

Аддон для ОП-2.09.2: Яндекс/Google/GitHub/Тема на AP-PRO

naxac.gif

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

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

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

Изменено пользователем Капрал Хикс
16 hours ago, naxac said:

если self.start_btn - это статик, а не кнопка, то у него есть метод

Так у дочерних классов методов только больше. Где-то попадалось исключение по наследованию родительских методов, но точно не в CUIStatic.

  • Полезно 2

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

Шпаргалка

Стоит фишка на использование горячих клавиш 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 GSC Game World
-- Author:      Serhiy Vynnychenko (narrator@gsc-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
 

 

@Капрал Хикс попробуй все строчки вида

if index == 4294967295 then return end

заменить на

if index == 4294967295 or index == -1 then return end

Возможно скрипт написан под обновленный lua.

  • Нравится 1

Telegram-канал RayTwitty Space

@Капрал Хикс тогда надо дебажить, выводить в лог индекс который выдает GetSelectedItem, смотреть, почему с ним не работает GetItem (получение элемента списка по его номеру) и т.д.

 

Да и вообще, в целом не ясно "если курсор не стоит на строке сохранения" - курсор это что? Фокус мыши не наведен на элемента списка? Или элемент списка не выделен?

Просто в каком-то ориг скрипте был момент (наверно save dialog), что вместо GetSelectedItem использовался GetFocusedItem, и там как раз тоже был косяк с тем, что при подвязке хоткеев мышь могла не быть над элементом списка в момент действия. Но тут такого я не вижу.

Telegram-канал RayTwitty Space

2 минуты назад, RayTwitty сказал:

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

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

@Капрал Хикс при этом какая-нибудь строчка выделена? (закрашен элемент списка полоской на фоне)

Telegram-канал RayTwitty Space

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

30 минут назад, Капрал Хикс сказал:

Тут бы запретить вызов клавиши Delete при невыделенной строке как-то.

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

Telegram-канал RayTwitty Space

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

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

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

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

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

Войти

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

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

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