Перша частина
Друга частина
Найчастіше при розробці мода або в грі доводиться виконувати різні дії - видача інфопорцій, спавн об'єктів, включення відключення скриптового ПНО, скидання рюкзака, з'їдання антирада, запуск скриптового меню і т.д. Можна призначати гарячі кнопки своїм скриптам у будь-якій версії гри, при цьому не використовуючи головне меню, кейлоггер або редагування движка. По-перше, це кнопка, натискання якої відображає на екрані назву активного квесту (за замовчуванням – Tab). Приклад можна подивитися в моді OGSE 0692. У ньому на кнопку підвішено з'їдання антирада та включення кулемета до БТР. По-друге, є алгоритм, який використовує інші кнопки. Розглянемо його докладніше.
Ідея досить проста - використання консольної команди виду " bind_console demo_record 1 knumpad0 ". В даному прикладі при натисканні кнопки 0 на додатковій клавіатурі буде виконано команду " demo_record 1 ". Таким чином, для кожної кнопки можна задати виконання своєї консольної команди. Ми можемо взяти як команду якусь невикористовувану в синглу, наприклад " mm_net_player_name ", а як параметр передавати ідентифікатор натиснутої кнопки. Тепер, якщо на апдейті ловити значення параметра консольної команди, знатимемо, яка кнопка натиснута, і виконувати відповідну їй функцію.
Працює ця схема на будь-якій версії гри. Не слід використовувати вже забиндені кнопки, т.к. Події, пов'язані з ними, можна перестануть виконуватися. Слід пам'ятати, що при відкритому діалоговому вікні воно перехоплює обробку кнопок і натискання не відловлюється.
Варіант 1: |
local con = nil -- переменная для объекта консоли local con_command = "mm_net_player_name" -- консольная команда local def_value = "_" -- значение по умолчанию - символ подчеркивания function update() if not con then -- инициализируем схему con = get_console() -- кешируем консоль con:execute( con_command .." ".. def_value ) -- инициализируем дефотлным значением, т.к. кнопка не нажата for k,v in pairs(_G[script_name()]) do -- перебираем функции в текущем файле -- v это функция и её имя является кодом клавиши if type(v)=='function' and DIK_keys[string.upper(k)] then local key = "k"..string.gsub(k,"dik_","") -- формируем ключ и con:execute("bind_console "..con_command.." "..k.." "..key) -- биндим кнопку на него end end else -- получаем из консоли значение параметра для нашей команды local str = con:get_string(con_command) -- если оно не является значением по умолчанию -- и в этом файле есть функция с таким именем, то выполняем её if str~=def_value and this[str] then this[str]() con:execute(con_command.." "..def_value) -- записываем значение по умолчанию end end end function dik_numpad0() news_manager.send_tip(db.actor,"нажали кнопку numpad0") end function dik_numpad1() news_manager.send_tip(db.actor,"нажали кнопку numpad1") end function dik_numpad2() news_manager.send_tip(db.actor,"нажали кнопку numpad2") end
|
При натисканні клавіш 0,1 або 2 цифрової клавіатури буде виведено відповідне кожній кнопці повідомлення. Відстежувати можна не лише натискання, а й відпускання кнопки. Зробити це можна аналогічно випадку з кнопкою Tab. На наше щастя на одну дію можна забиндити другу кнопку командою "bind_sec". Варіант коду з відловом відпускання виглядає так:
Варіант 2: |
local con = nil local con_command = "mm_net_player_name" local def_value = "_" local act_key = "" -- последняя нажатая клавиша function update() if not con then con = get_console() con:execute(con_command .." " .. def_value) for k,v in pairs(_G[script_name()]) do if type(v)=='function' and DIK_keys[string.upper(k)] then local key = "k"..string.gsub(k,"dik_","") con:execute("bind_console "..con_command.." "..k.." "..key) end end else local str = con:get_string(con_command) if str~=def_value and this[str] then this[str]() con:execute(con_command .." " .. def_value) --отлова отпускания -- биндим на показ статика активного квеста нажатую кнопку con:execute("bind_sec scores k"..string.gsub(str,"dik_","")) -- если статик ещё не показан, то показываем его -- он будет висеть пока не отпущена клавиша local cs = get_hud():GetCustomStatic("main_task") or get_hud():AddCustomStatic("main_task") -- задаем 100% прозрачность тексту, чтоб не светился без нужды cs:wnd():SetTextColor(0,240,217,182) act_key = str -- запоминаем нажатую кнопку news_manager.send_tip(db.actor,"нажали "..act_key) end end -- отлов отпускания local cs = get_hud():GetCustomStatic("main_task") if act_key~="" and not cs then -- была нажата клавиша, а статика нет con:execute("unbind_sec scores") news_manager.send_tip(db.actor,"отпустили "..act_key) act_key="" end end function dik_numpad0() end function dik_numpad1() end function dik_numpad2() end
|
При натисканні клавіші 0 на додатковій клавіатурі буде виведено повідомлення "натиснули 0", а при відпусканні "відпустили 0". Функцію update викликаємо з апдейта біндера актора. Імена функцій беруться з класу-переліку DIK_keys, опис якого можна знайти в lua_help.script.