function mscript_get_mscript() lua_engine = getLuaEngine() script_table_lua_engine = MainForm.frmLuaTableScript.getControl(1).getControl(0) if(lua_engine ~= nil and script_table_lua_engine.focused() ~= true) then return getLuaEngine().mScript else if (script_table_lua_engine.focused()) then return script_table_lua_engine end end end ---@param line_number number|nil optional: what line to get, if none provided gets current line ---@returns string function mscript_get_line(line_number) local m = mscript_get_mscript() if line_number == nil then line_number = m.CaretY end line_number = line_number - 1 -- to get the line number as show to the left if line_number < 0 then line_number = 0 end if line_number > m.Lines.Count - 1 then line_number = m.Lines.Count - 1 end return m.Lines.getString(line_number) end ---returns {start, number} ---@returns number, number function mscript_get_start_and_end_of_current_line() local m = mscript_get_mscript() local line_start = m.SelStart - m.CaretX + 1 local line_end = line_start + string.len(mscript_get_line()) return line_start, line_end end local previous_mscript_options = {} function mscript_disable_moving_between_selection_edges() local m = mscript_get_mscript() m.Options2 = previous_mscript_options end function mscript_enable_moving_between_selection_edges() local m = mscript_get_mscript() local options = {} previous_mscript_options = m.Options2 -- Preserve other options. for name in m.Options2:gmatch("[%w_]+") do if name ~= "eoCaretSkipsSelection" and name ~= "eoCaretMoveEndsSelection" then options[#options + 1] = name end end options[#options + 1] = "eoCaretSkipsSelection" if keep_selection ~= nil then options[#options + 1] = "eoCaretMoveEndsSelection" end setProperty(m, "Options2", "[" .. table.concat(options, ",") .. "]") end mscript_enable_moving_between_selection_edges() ---moves caret left/right and up/down by x and y ---@param x number optional ---@param y number optional ---@return number, number ---returns {previous_caretX, previous_caretY}, {new_caretX, new_caretY} function mscript_move_caret(x, y) local m = mscript_get_mscript() local prev_pos = {m.CaretX, m.CaretY} if x ~= nil and x ~= 0 and math.abs(m.CaretX + x) >= 0 then m.CaretX = m.CaretX + x end if y ~= nil and y ~= 0 and math.abs(m.CaretY + y) >= 0 then m.CaretY = m.CaretY + y end local new_pos = {m.CaretX, m.CaretY} return prev_pos, new_pos end function mscript_comment_line() local m = mscript_get_mscript() local str = mscript_get_line() local y = m.CaretY - 1 if y == nil or str == nil then return end local new_str = '-- '..str local i, j = string.find(str, "^%s*%-%- ") if (i ~= nil) then new_str = string.gsub(str, "^(%s*)%-%- ", "%1", 1) end m.Lines.setString(y, new_str) mscript_move_caret(0, 1) end ---@param direction string : "up" or "down" function mscript_duplicate_line(direction) local m = mscript_get_mscript() if(direction == "up" and m.CaretY-1 ~= 0) then m.CaretY = m.CaretY + 1 else if (direction == "down") then m.CaretY = m.CaretY - 1 end end if(m.CaretY >= m.Lines.Count) then m.Lines.insert(m.Lines.Count, "") if(direction == "down") then m.Lines.insert(m.Lines.Count, "") end end local line_start, line_end = mscript_get_start_and_end_of_current_line() m.Lines.insert(m.CaretY, string.sub(m.Lines.Text, line_start, line_end)) if(direction == "down") then m.CaretY = m.CaretY + 1 else -- m.CaretY = m.CaretY + 1 end end ---comment ---@param direction string : "up" or "down" ---@param line number|nil optional function mscript_move_line(direction, line) local m = mscript_get_mscript() local str = mscript_get_line() local y = m.CaretY - 1 if line ~= nil then y, str = mscript_get_line(line) end if y == nil or str == nil then return end if(y == 0 and direction == "up") then return end if(direction == "up") then w = 1 else w = -1 end if(y == m.Lines.Count - 1) then -- only adding two lines help m.Lines.insert(m.Lines.Count, "") m.Lines.insert(m.Lines.Count, "") end local replacee = m.Lines.getString(y - w) m.Lines.delete(y-w) m.Lines.insert(y, replacee) mscript_move_caret(0, -w) end function mscript_wrap_string(sender, char) local m = mscript_get_mscript() local current_line = mscript_get_line() local potentially_skippable = string.sub(current_line, m.CaretX, m.CaretX) if string.find(char, "[%)%}%\"%'%]]") ~= nil and potentially_skippable == char then mscript_move_caret(1) return false end local _, i = string.find(char, "[%(%{%\"%'%[]") if i == nil then return char end if (string.len(m.SelText) > 1) then local sel_start = m.SelStart local sel_end = m.SelEnd if(char == '(') then m.SelText = '('..m.SelText..')' end if(char == '[') then m.SelText = '['..m.SelText..']' end if(char == '{') then m.SelText = '{'..m.SelText..'}' end if(char == '"') then m.SelText = '"'..m.SelText..'"' end if(char == "'") then m.SelText = "'"..m.SelText.."'" end m.SelStart = sel_start + 1 m.SelEnd = sel_end + 1 m.CaretX = m.CaretX + string.len(m.SelText) return false else if(char == '(') then m.SelText = '()' end if(char == '[') then m.SelText = '[]' end if(char == '{') then m.SelText = '{}' end if(char == '"') then m.SelText = '""' end if(char == "'") then m.SelText = "''" end mscript_move_caret(-1) end end ---converts shortcuts in number form to string and vice versa ---@param shortcut string|number ---@returns string|number function mscript_convert_shortcut(shortcut) local ALT = 32768 local CTRL = 16384 local SHIFT = 8192 if (type(shortcut) == "number") then local converted = "" if(shortcut >= CTRL) then converted = "CTRL+"..converted shortcut = shortcut - CTRL end if(shortcut >= ALT) then converted = "ALT+"..converted shortcut = shortcut - ALT end if(shortcut >= SHIFT) then converted = "SHIFT+"..converted shortcut = shortcut - SHIFT end local key = shortcut local out = string.format("%c", shortcut) if(key == VK_SPACE ) then out = "VK_SPACE " goto early_exit end if(key == VK_INSERT) then out = "VK_INSERT" goto early_exit end if(key == VK_DELETE) then out = "VK_DELETE" goto early_exit end if(key == VK_LEFT ) then out = "VK_LEFT " goto early_exit end if(key == VK_RIGHT ) then out = "VK_RIGHT " goto early_exit end if(key == VK_UP ) then out = "VK_UP " goto early_exit end if(key == VK_DOWN ) then out = "VK_DOWN " goto early_exit end if(key == VK_TAB ) then out = "VK_TAB " goto early_exit end if(key == VK_DIVIDE) then out = "VK_DIVIDE" goto early_exit end if(key == VK_ESCAPE) then out = "VK_ESCAPE" goto early_exit end if(key == VK_HOME ) then out = "VK_HOME " goto early_exit end if(key == VK_RETURN) then out = "VK_RETURN" goto early_exit end ::early_exit:: return converted..out end if (type(shortcut) == "string") then local converted = 0 if(string.match(shortcut, "CTRL+")) then converted = CTRL + converted --shortcut = shortcut - CTRL end if(string.match(shortcut, "ALT+")) then converted = ALT + converted --shortcut = shortcut - ALT end if(string.match(shortcut, "SHIFT+")) then converted = SHIFT + converted --shortcut = shortcut - SHIFT end return converted + string.byte(string.reverse(shortcut)) end end -- default functions and keybindinds provided by cheat engine's mscript -- idx cmdid command shortcut -- 0 | 3 : ecUp - Up -- 1 | 103 : ecSelUp - Shift+Up -- 2 | 211 : ecScrollUp - Ctrl+Up -- 3 | 4 : ecDown - Down -- 4 | 104 : ecSelDown - Shift+Down -- 5 | 212 : ecScrollDown - Ctrl+Down -- 6 | 1 : ecLeft - Left -- 7 | 101 : ecSelLeft - Shift+Left -- 8 | 5 : ecWordLeft - Ctrl+Left -- 9 | 105 : ecSelWordLeft - Shift+Ctrl+Left -- 10 | 2 : ecRight - Right -- 11 | 102 : ecSelRight - Shift+Right -- 12 | 6 : ecWordRight - Ctrl+Right -- 13 | 106 : ecSelWordRight - Shift+Ctrl+Right -- 14 | 10 : ecPageDown - PgDn -- 15 | 110 : ecSelPageDown - Shift+PgDn -- 16 | 14 : ecPageBottom - Ctrl+PgDn -- 17 | 114 : ecSelPageBottom - Shift+Ctrl+PgDn -- 18 | 9 : ecPageUp - PgUp -- 19 | 109 : ecSelPageUp - Shift+PgUp -- 20 | 13 : ecPageTop - Ctrl+PgUp -- 21 | 113 : ecSelPageTop - Shift+Ctrl+PgUp -- 22 | 7 : ecLineStart - Home -- 23 | 107 : ecSelLineStart - Shift+Home -- 24 | 15 : ecEditorTop - Ctrl+Home -- 25 | 115 : ecSelEditorTop - Shift+Ctrl+Home -- 26 | 8 : ecLineEnd - End -- 27 | 108 : ecSelLineEnd - Shift+End -- 28 | 16 : ecEditorBottom - Ctrl+End -- 29 | 116 : ecSelEditorBottom - Shift+Ctrl+End -- 30 | 223 : ecToggleMode - Ins -- 31 | 201 : ecCopy - Ctrl+Ins -- 32 | 604 : ecPaste - Shift+Ins -- 33 | 502 : ecDeleteChar - Del -- 34 | 603 : ecCut - Shift+Del -- 35 | 501 : ecDeleteLastChar - BkSp -- 36 | 501 : ecDeleteLastChar - Shift+BkSp -- 37 | 504 : ecDeleteLastWord - Ctrl+BkSp -- 38 | 601 : ecUndo - Alt+BkSp -- 39 | 602 : ecRedo - Shift+Alt+BkSp -- 40 | 509 : ecLineBreak - Enter -- 41 | 199 : ecSelectAll - Ctrl+A -- 42 | 201 : ecCopy - Ctrl+C -- 43 | 615 : ecBlockIndent - Shift+Ctrl+I -- 44 | 509 : ecLineBreak - Ctrl+M -- 45 | 510 : ecInsertLine - Ctrl+N -- 46 | 503 : ecDeleteWord - Ctrl+T -- 47 | 616 : ecBlockUnindent - Shift+Ctrl+U -- 48 | 604 : ecPaste - Ctrl+V -- 49 | 603 : ecCut - Ctrl+X -- 50 | 507 : ecDeleteLine - Ctrl+Y -- 51 | 506 : ecDeleteEOL - Shift+Ctrl+Y -- 52 | 601 : ecUndo - Ctrl+Z -- 53 | 602 : ecRedo - Shift+Ctrl+Z -- 54 | 301 : ecGotoMarker0 - Ctrl+0 -- 55 | 302 : ecGotoMarker1 - Ctrl+1 -- 56 | 303 : ecGotoMarker2 - Ctrl+2 -- 57 | 304 : ecGotoMarker3 - Ctrl+3 -- 58 | 305 : ecGotoMarker4 - Ctrl+4 -- 59 | 306 : ecGotoMarker5 - Ctrl+5 -- 60 | 307 : ecGotoMarker6 - Ctrl+6 -- 61 | 308 : ecGotoMarker7 - Ctrl+7 -- 62 | 309 : ecGotoMarker8 - Ctrl+8 -- 63 | 310 : ecGotoMarker9 - Ctrl+9 -- 64 | 351 : ecSetMarker0 - Shift+Ctrl+0 -- 65 | 352 : ecSetMarker1 - Shift+Ctrl+1 -- 66 | 353 : ecSetMarker2 - Shift+Ctrl+2 -- 67 | 354 : ecSetMarker3 - Shift+Ctrl+3 -- 68 | 355 : ecSetMarker4 - Shift+Ctrl+4 -- 69 | 356 : ecSetMarker5 - Shift+Ctrl+5 -- 70 | 357 : ecSetMarker6 - Shift+Ctrl+6 -- 71 | 358 : ecSetMarker7 - Shift+Ctrl+7 -- 72 | 359 : ecSetMarker8 - Shift+Ctrl+8 -- 73 | 360 : ecSetMarker9 - Shift+Ctrl+9 -- 74 | 371 : EcFoldLevel1 - Shift+Alt+1 -- 75 | 372 : EcFoldLevel2 - Shift+Alt+2 -- 76 | 371 : EcFoldLevel1 - Shift+Alt+3 -- 77 | 371 : EcFoldLevel1 - Shift+Alt+4 -- 78 | 371 : EcFoldLevel1 - Shift+Alt+5 -- 79 | 376 : EcFoldLevel6 - Shift+Alt+6 -- 80 | 377 : EcFoldLevel7 - Shift+Alt+7 -- 81 | 378 : EcFoldLevel8 - Shift+Alt+8 -- 82 | 379 : EcFoldLevel9 - Shift+Alt+9 -- 83 | 380 : EcFoldLevel0 - Shift+Alt+0 -- 84 | 381 : EcFoldCurrent - Shift+Alt+Ins -- 85 | 382 : EcUnFoldCurrent - Shift+Alt+Execute -- 86 | 383 : EcToggleMarkupWord - Alt+M -- 87 | 231 : ecNormalSelect - Shift+Ctrl+N -- 88 | 232 : ecColumnSelect - Shift+Ctrl+C -- 89 | 233 : ecLineSelect - Shift+Ctrl+L -- 90 | 617 : ecTab - Tab -- 91 | 618 : ecShiftTab - Shift+Tab -- 92 | 250 : ecMatchBracket - Shift+Ctrl+B -- 93 | 153 : ecColSelUp - Shift+Alt+Up -- 94 | 154 : ecColSelDown - Shift+Alt+Down -- 95 | 151 : ecColSelLeft - Shift+Alt+Left -- 96 | 152 : ecColSelRight - Shift+Alt+Right -- 97 | 160 : ecColSelPageDown - Shift+Alt+PgDn -- 98 | 164 : ecColSelPageBottom - Shift+Ctrl+Alt+PgDn -- 99 | 159 : ecColSelPageUp - Shift+Alt+PgUp -- 100 | 163 : ecColSelPageTop - Shift+Ctrl+Alt+PgUp -- 101 | 157 : ecColSelLineStart - Shift+Alt+Home -- 102 | 158 : ecColSelLineEnd - Shift+Alt+End -- 103 | 165 : ecColSelEditorTop - Shift+Ctrl+Alt+Home -- 104 | 166 : ecColSelEditorBottom - Shift+Ctrl+Alt+End do local lua_engine = getLuaEngine() local ALT = 32768 local CTRL = 16384 local SHIFT = 8192 local LEFT_BRACE = 0xDD local RIGHT_BRACE = 0xDB lua_engine.scLuaCompleter.LinesInWindow = 20 --lua_engine autocompletion menu lua_engine.scLuaCompleter.Width = 500 --lua_engine autocompletion width lua_engine.scLuaCompleter.CaseSensitive = false lua_engine.mScript.onKeyPress = mscript_wrap_string lua_engine.mScript.Keystrokes.Items[22].ShortCut = CTRL + ALT + VK_LEFT -- go to line start lua_engine.mScript.Keystrokes.Items[23].ShortCut = CTRL + ALT + SHIFT + VK_LEFT -- select to line start lua_engine.mScript.Keystrokes.Items[26].ShortCut = CTRL + ALT + VK_RIGHT -- go to line end lua_engine.mScript.Keystrokes.Items[27].ShortCut = CTRL + ALT + SHIFT + VK_RIGHT -- select to line end lua_engine.mScript.Keystrokes.Items[43].ShortCut = CTRL + LEFT_BRACE -- indent lua_engine.mScript.Keystrokes.Items[47].ShortCut = CTRL + RIGHT_BRACE -- unindent lua_engine.mScript.Keystrokes.Items[50].ShortCut = CTRL + SHIFT + VK_D -- delete whole line lua_engine.mScript.Keystrokes.Items[53].ShortCut = ALT + VK_Z -- undo -- mscript_engine.mScript.Keystrokes.Items[93].ShortCut = CTRL + ALT + VK_UP -- put caret above doesnt work, collides with ctrl+alt shortcuts -- mscript_engine.mScript.Keystrokes.Items[94].ShortCut = CTRL + ALT + VK_DOWN -- put caret below doesnt work, collides with ctrl+alt shortcuts -- i also care about script table's lua window local script_table_lua_engine = MainForm.frmLuaTableScript.getControl(1).getControl(0) local lua_engine_shortcuts = lua_engine.mScript.Keystrokes.Items script_table_lua_engine.Keystrokes.Items[22].ShortCut = lua_engine_shortcuts[22].ShortCut script_table_lua_engine.Keystrokes.Items[23].ShortCut = lua_engine_shortcuts[23].ShortCut script_table_lua_engine.Keystrokes.Items[26].ShortCut = lua_engine_shortcuts[26].ShortCut script_table_lua_engine.Keystrokes.Items[27].ShortCut = lua_engine_shortcuts[27].ShortCut script_table_lua_engine.Keystrokes.Items[43].ShortCut = lua_engine_shortcuts[43].ShortCut script_table_lua_engine.Keystrokes.Items[47].ShortCut = lua_engine_shortcuts[47].ShortCut script_table_lua_engine.Keystrokes.Items[50].ShortCut = lua_engine_shortcuts[50].ShortCut script_table_lua_engine.Keystrokes.Items[53].ShortCut = lua_engine_shortcuts[53].ShortCut script_table_lua_engine.onKeyPress = lua_engine.mScript.onKeyPress end createHotkey(getLuaEngine().btnExecute.doClick, {VK_CONTROL, VK_0}) createHotkey(function() mscript_comment_line() end, {VK_CONTROL, VK_OEM2}) createHotkey(function() mscript_move_line("up") end, {VK_MENU, VK_UP}) createHotkey(function() mscript_move_line("down") end, {VK_MENU, VK_DOWN}) createHotkey(function() mscript_duplicate_line("up") end, {VK_SHIFT, VK_MENU, VK_UP}) createHotkey(function() mscript_duplicate_line("down") end, {VK_SHIFT, VK_MENU, VK_DOWN})