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

[SoC] Как назначить выполнение скрипта на кнопку в игре


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

Итак, по многочисленным вопросам выкладываю способ, который в общем-то очень простой, но работает. Итак, как сделать, чтобы при нажатии кнопки ТАВ в игре у вас выполнялось какое-то действие? Сразу два пояснения.

 

Известен способ как прибиндить кнопкам функции скрипта, но только когда открыто главное меню, или меню спальника, или любое другое скриптовое меню. В скриптовых файлах этих меню есть виртуальный колбек на отлов нажатия кнопок клавиатуры, поэтому когда открыто меню, например, спальника того же - нельзя использовать аптечку или бинт с помощью нажатия горячей кнопки [ или ]. А вот в файле скрипта на них можно прибиндить какую-то функцию, но повторюсь - это только в момент когда на экране есть скриптовое меню. 

 

Второй способ, как сделать работу скрипта по нажатию кнопки в игре - не существует. Однако, имитацию ТАКОГО СПОСОБА УДАЛОСЬ СОЗДАТЬ, но только для клавиши ТАВ. 

 

Объяснение довольно простое - при нажатии кнопки ТАВ в игре на экран выводится текущее задание, которое отмечено в ПДА. Я подозреваю, что когда текущих заданий в ПДА не останется (например, в АМК 1.4 когда доходишь до уровня ЧАЭС 2, после разговора с О-Сознанием, пропадало последнее задание "Убить Стрелка", и не оставалось ни одного) - способ перестанет работать, но это надо проверять.

 

Так вот, оказывается, текущее задание выводится на главный экран игры, то есть на ХУД, не просто так, а в виде кастом статика. Этот кастом статик записан в файле gamedata\config\ui\ui_custom_msgs.xml и называется он main_task. Вот его-то и можно поймать скриптом, и соответственно, назначить на момент его ловли какое-то действие. Пример ниже.

 

Все мы знаем функцию апдейта из файла бинд_сталкер. Вот на неё-то и повесим колбек на специальный скрипт tabula_rasa.script, вот так:

 

if tabula_rasa then tabula_rasa.update(delta) end

 

Понятно, что вставить этот колбек надо в функцию апдейта в скрипте bind_stalker.script, а теперь займёмся самим новым скриптом. В нём будет две основных функции - самого апдейта, где будет проверяться, нет ли на главном экране кастом статика main_task, и вторая функция, где будет выполняться какое-то действие. 

 

local timer = 0

function update(delta)
   timer = timer+delta
   if timer>1000000 then timer = 1000000 end
   local hud = get_hud()
   if hud:GetCustomStatic("main_task") and timer>1000 then
      do_something()
      timer = 0
   end
end

function do_something()
   local item = db.actor:object("antirad")
   if antirad then
      db.actor:eat(item)
   end
end

 

Вот такая вот функция. А теперь - что она делает? Правильно, при нажатии ТАВ происходит использование антирада, одной штуки, если он есть. Но такое использование произойдёт не чаще, чем раз в 1000 миллисекунд, для чего есть специальная проверка - в переменной timer хранится время, прощедшее с момента последнего нажатия ТАВ, при котором timer обнуляется. Время хранится в миллисекундах, поэтому 1000 равно одной секунде. Ну а строка где проверяется, не равен ли timer миллиону - это просто страховка от возможного огромного значения переменной. Я подозреваю, что время в миллисекундах в игре может быть очень большим, но всё равно - страховка не помешает, от редчайшего случая, когда вы включили игру и уехали на пару месяцев на дачу :) Вдруг тогда timer переполнился бы и произошёл вылет - а теперь timer не переполнится, и вернувшись через год из армии вы обнаружите что на компе, который вы включили будучи ещё призывником, СТАЛКЕР не вылетел из-за корявого Русиного скрипта. Шучу, конечно.

 

Дальше - слово вам, фантазия безграничная :)

  • Полезно 1
ANViL & Rusya Conception, или просто
-=[ARC Team]=-


Ссылка на комментарий
Я подозреваю, что когда текущих заданий в ПДА не останется (например, в АМК 1.4 когда доходишь до уровня ЧАЭС 2, после разговора с О-Сознанием, пропадало последнее задание "Убить Стрелка", и не оставалось ни одного) - способ перестанет работать, но это надо проверять.

 

когда заданий нет, выводиться надпись - "Нет активного задания"

 

 

Руся молодец!! спасибо за статью :)

  • Полезно 1
Ссылка на комментарий

Отлично, тогда способ сработает всегда. :) Супер.

ANViL & Rusya Conception, или просто
-=[ARC Team]=-


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

Руся,

идея очень интересная и простая, но есть две маленькие дырочки:

1 во время выдачи задания на худ выводиться его название через main_task без нажатия на tab, по этому условие if hud:GetCustomStatic("main_task") and timer>1000 выполниться и, как в этом примере, ГГ использует антирад что не есть хорошо.

function send_task(actor, type, task, objective)
    if db.actor == nil then return false end
    
    --' Берем координаты из текстуры таска
    local task_texture, task_rect = get_texture_info("ui_iconsTotal_"..task:get_id(), "ui_iconsTotal_locations")
        
    --' Играем дефолтный звук
    pda_task:play(db.actor, 0, sound_object.s2d)

    local news_text = "%c[255,160,160,160]"..game.translate_string(action_descr_by_type[type]).."\\n".."%c[default]"..game.translate_string(task:get_title())

    if db.actor:is_talking() then    
        db.actor:give_talk_message(news_text, task_texture, task_rect,"iconed_answer_item")
    else
        db.actor:give_game_news(news_text, task_texture, task_rect, 0, 3000)
    end    

    if type == "new" or
        type == "update"
    then
        --' Выдать новое подзадание
        if task:get_objectives_cnt() == objective:get_idx()+1 then
            return
        end
        news_text = game.translate_string(task:get_objective(objective:get_idx() + 1):get_description())
    end

    [b]local hud = get_hud()
    hud:AddCustomStatic("main_task", true)
    hud:GetCustomStatic("main_task"):wnd():SetTextST(news_text)
    hud:GetCustomStatic("main_task").m_endTime = time_global()/1000 + 5[/b]

end

 

Способ лечения:

Закоментить строки

--local hud = get_hud()

--hud:AddCustomStatic("main_task", true)

--hud:GetCustomStatic("main_task"):wnd():SetTextST(news_text)

--hud:GetCustomStatic("main_task").m_endTime = time_global()/1000 + 5

 

2 как мне кажется если зажать tab и держать его более 1 секунды то ГГ скушает еще один антирад, что тоже не хорошо.

Способ лечения:

 

local tab = 0

function update(delta)
    local hud = get_hud()
    if hud:GetCustomStatic("main_task") then
        if tab==0 then
        do_something()
        tab = 1
        end
    else
        if tab==1 then
        tab = 0
        end
    end
end

 

переменная tab является флагом нажатия на клавишу, и сбрасывается только когда клавиша отпускается то есть main_task исчезает с худа.

 

А так очень хорошая идея.

  • Полезно 1
Возможно всё, ну или почти всё.
Ссылка на комментарий

Это действие, относящееся к кнопки ТАВ, можно спокойно переназначить на любую другую удобную кнопку. У меня, например, кнопка ТАВ открывает инвентарь. А задания я перенес на совершенно другую кнопку.

Кто весел - тот смеется, кто хочет - тот добьется, кто ищет - тот всегда найдет!

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

Про файл news_manager я знаю, и чтобы не было ложного срабатывания при выводе на экран сообщения - я просто закомментил строки как ты говоришь, а вывод задания сделал в виде send_tip, которое есть в АМК. И задание выскакивает теперь как сообщение, а ложного срабатывания нету.

 

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

 

И ещё - можно сделать чтобы надпись ваааще не была видна на экране. Для этого в файле ui_custom_msgs.xml в параметрах кастом статика main_task или сделать текст прозрачным (параметр a=0, то есть альфа равна нулю) или сделать выводимому тексту отрицательные координаты, x = -1000 y = -1000, это уберёт текст за границы экрана. Получится - кнопка нажата, а действие её только скриптовое.

 

PS. Очень приятно, что тема нашла именно тех, кому это пригодилось :)

Изменено пользователем Руся
  • Спасибо 1
ANViL & Rusya Conception, или просто
-=[ARC Team]=-


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

Руся, спасибо за скрипт!

А можно сделать чтобы при нажатии на одну клавишу съедалась аптека, антирад и консерва?

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

Да нет проблем.

 

На этот момент можно повесить всё что угодно. Хоть починку всех предметов в инвентаре, хоть спаун Ночной Звезды прямо в рюкзак :). А можно всё это вместе и ещё дать сто тысяч денег. Запросто.

Просто в функцию do_something допиши что нужно.

Изменено пользователем Руся
ANViL & Rusya Conception, или просто
-=[ARC Team]=-


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

Руся, запаковывай это чуво в инсталер и длей много-много функций спауна вещей в инвертаре. И название придумал "Unofficial trainer for Stalker SoC by Rusya" :D

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

А зачем? Есть же Cheat Spawner, кажется.. К тому же трейнер не получится - в этом способе всего одна кнопка работает :)

ANViL & Rusya Conception, или просто
-=[ARC Team]=-


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

4ufak, ну давай включим мозг

скрипт отлавливает появление заданного статика на экране, на нем обычно отображается активное задание - трабла в том, что когда подзадание выполняется или добавляется ненавистный статик вылезает на экран, а так как задания у нас даются зачастую во время диалогов то сразу после закрытия оного появляется статик и выполняет функцию do_something

 

сам же всем советую юзать кнопку паузы (все равно старые геймеры по привычке жмут ескейп)

а саму паузу можно через консоль включить и отключить

вот только чтобы не было "притормаживания" лучше юзать функцию для вывода диалога

i-igroman.ru - Мой, принципиально новый сайт о компьютерных играх

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

Судя по lua_help_script class key_bindings, число клавиш ограничено.Где связь между ними и выбором кнопок в Опции/Управление - без понятия. Предлагается попатчить DLL и добавить штук 10 неиспользуемых kAction0..kAction9.Это сложно?

Прошел Солянку, иду в NLC

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

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

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

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

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

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

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

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

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

Войти

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

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

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