--[[ -- * Script Name: Solus -- * Script Version: 1.0.0 -- * Script Author: Klient#1690 ]] --- @region: dependencies --- @param: pos: vector --- @param: size: vector --- @return: boolean local function is_mouse_in_bounds(pos, size) local x, y = pos.x, pos.y local w, h = size.x, size.y local mouse_position = {input.get_cursor_pos()} return ((mouse_position[1] >= x and mouse_position[1] < x + w and mouse_position[2] >= y and mouse_position[2] < y + h) and gui.is_menu_open()) end --- @endregion --- @region: enumerations local e_global = { SCREEN = {render.get_screen_size()} } --- @endregion --- @region: table --- @param: tbl: table --- @return: number function table.count(tbl) if tbl == nil then return 0 end if #tbl == 0 then local count = 0 for data in pairs(tbl) do count = count + 1 end return count end return #tbl end --- @endregion --- @region: animation local animation = {} animation.data = {} --- @param: start: any --- @param: end_pos: any --- @param: time: number --- @return: any function animation.lerp(start, end_pos, time) if (type(start) == "table") then local color_data = {0, 0, 0, 0} for i, color_key in ipairs({"r", "g", "b", "a"}) do color_data[i] = animation.lerp(start[color_key], end_pos[color_key], time) end return render.color(unpack(color_data)) end return (end_pos - start) * (global_vars.frametime * time) + start end --- @param: name: string --- @param: value: any --- @param: time: number --- @retrun: any function animation.new(name, value, time) if (animation.data[name] == nil) then animation.data[name] = value end animation.data[name] = animation.lerp(animation.data[name], value, time) return animation.data[name] end --- @endregion --- @region: drag --- @class: c_drag --- @field: public: x: number --- @field: public: y: number --- @field: public: width: number --- @field: public: height: number --- @field: public: d_x: number --- @field: public: d_y: number --- @field: public: dragging: boolean --- @field: public: unlocked: boolean local c_drag = {} local m_drag = { __index = c_drag } --- @param: slider_x: MenuItem --- @param: slider_y: MenuItem --- @param: x: number --- @param: y: number --- @return c_drag function c_drag.new(slider_x, slider_y, x, y) slider_x:set_int(x) slider_y:set_int(y) return setmetatable({ x = slider_x, y = slider_y, d_x = 0, d_y = 0, dragging = false, unlocked = false }, m_drag) end --- @return void function c_drag:unlock() self.unlocked = true end --- @return void function c_drag:lock() self.unlocked = false end --- @param: width: number --- @param: height: number --- @return: void function c_drag:handle(width, height) self.width = width self.height = height local screen = e_global.SCREEN local mouse_position = {input.get_cursor_pos()} if (is_mouse_in_bounds(math.vec3(self.x:get_int(), self.y:get_int()), math.vec3(self.width, self.height))) then if (input.is_key_down(0x01) and not self.dragging) then self.dragging = true self.d_x = self.x:get_int() - mouse_position[1] self.d_y = self.y:get_int() - mouse_position[2] end end if (not input.is_key_down(0x01)) then self.dragging = false end if (self.dragging and gui.is_menu_open()) then local new_x = math.max(0, math.min(screen[1] - self.width, mouse_position[1] + self.d_x)) local new_y = math.max(0, math.min(screen[2] - self.height, mouse_position[2] + self.d_y)) new_x = self.unlocked and mouse_position[1] + self.d_x or new_x new_y = self.unlocked and mouse_position[2] + self.d_y or new_y self.x:set_int(new_x) self.y:set_int(new_y) end end --- @return: number, number function c_drag:get() return self.x:get_int(), self.y:get_int() end --- @endregion --- @region: draw local draw = {} --- @param: pos: vec3 --- @param: size: vec3 --- @param: color1: color --- @param: round: number: optional --- @param: round_flags: number: optional --- @return: void function draw.rect(pos, size, color1, round, round_flags) local a, b = pos, pos + size if (round ~= nil) then render.rect_filled_rounded(a.x, a.y, b.x, b.y, color1, round, round_flags or render.all) return end return render.rect_filled(a.x, a.y, b.x, b.y, color1) end --- @param: pos: vec3 --- @param: size: vec3 --- @param: color1: color --- @return: void function draw.rect_outline(pos, size, color1) local a, b = pos, pos + size return render.rect(a.x, a.y, b.x, b.y, color1) end --- @param: pos: vector --- @param: size: vector --- @param: color1: color --- @param: color2: color --- @param: ltr: boolean: optional --- @param: normal: boolean: optional --- @return: void function draw.gradient(pos, size, color1, color2, ltr, normal) local a, b = pos, pos + size if (normal == true) then a, b = pos, size end if (ltr == true) then render.rect_filled_multicolor(a.x, a.y, b.x, b.y, color1, color2, color1, color2) return end return render.rect_filled_multicolor(a.x, a.y, b.x, b.y, color1, color1, color2, color2) end --- @param: pos: vec3 --- @param: size: vec3 --- @vararg: any --- @return: void function draw.push_clip_rect(pos, size, ...) local a, b = pos, pos + size return render.push_clip_rect(a.x, a.y, b.x, b.y, ...) end --- @return: void function draw.pop_clip_rect() return render.pop_clip_rect() end --- @param: pos: vec3 --- @param: color1: color --- @param: radius: number --- @param: angle: number: optional --- @param: percentage: number: optional --- @param: thickness: number: optional --- @param: segments: number: optional --- @return: void function draw.circle_outline(pos, color1, radius, angle, percentage, thickness, segments) local x, y = pos.x, pos.y return render.circle(x, y, radius, color1, thickness or 1, segments or 12, percentage or 1, angle or 0) end --- @param: pos: vector --- @param: size: vector --- @param: color1: color --- @param: length: number --- @return: void function draw.shadow(pos, size, color1, length) local r, g, b, a = color1.r, color1.g, color1.b, color1.a for i = 1, 10 do draw.rect_outline(pos - math.vec3(i, i), size + math.vec3(i * 2, i * 2), render.color(r, g, b, (60 - (60 / length) * i) * (a / 255))) end end --- @param: pos: vec3 --- @param: size: vec3 --- @param: color1: color --- @param: glow: boolean: optional --- @return: void function draw.window(pos, size, color1, glow) local round = 6 local x, y = pos.x, pos.y local width, height = x + size.x, y + size.y local r, g, b, a = color1.r, color1.g, color1.b, color1.a if (glow == true) then draw.shadow(pos, size, render.color(r, g, b, (255 / 255) * a), 10) end draw.rect(pos, size, render.color(0, 0, 0, (80 / 255) * a), round-2) draw.push_clip_rect(math.vec3(x, y), math.vec3(round, round + 1)) draw.circle_outline(pos + math.vec3(round + 1, round + 1), render.color(r, g, b, (255 / 255) * a), round + 2, 180, 0.3, 1) draw.pop_clip_rect() draw.push_clip_rect(pos + math.vec3(size.x - round), math.vec3(round, round + 1)) draw.circle_outline(pos + math.vec3(size.x - round - 1, round + 1), render.color(r, g, b, (255 / 255) * a), round + 2, 280, 0.3, 1) draw.pop_clip_rect() draw.rect(math.vec3(pos.x + round - 3, pos.y), math.vec3(size.x - (round * 2) + 6, 1), render.color(r, g, b, (255 / 255) * a)) draw.gradient(math.vec3(pos.x, pos.y + round - 3), math.vec3(1, (size.y + 5) / 2), render.color(r, g, b, (255 / 255) * a), render.color(r, g, b, (0 / 255) * a)) draw.gradient(math.vec3(pos.x + size.x - 1, pos.y + round - 3), math.vec3(1, (size.y + 5) / 2), render.color(r, g, b, (255 / 255) * a), render.color(r, g, b, (0 / 255) * a)) end --- @endregion --- @region: fonts local fonts = {} fonts.verdana = {} fonts.verdana.default = render.create_font("verdana.ttf", 12, render.font_flag_shadow) --- @endregion --- @region: ui local ui_general = {} ui_general.accent_check = gui.add_checkbox("Accent color", "lua>tab a") ui_general.accent_color = gui.add_colorpicker("lua>tab a>Accent color", true) ui_general.glow = gui.add_checkbox("Glow", "lua>tab a") ui_general.keybinds = gui.add_checkbox("Keybinds", "lua>tab a") ui_general.watermark = gui.add_checkbox("Watermark", "lua>tab a") ui_general.keybinds_x = gui.add_slider("Keybinds x", "lua>tab a", 0, e_global.SCREEN[1], 1); gui.set_visible("lua>tab a>Keybinds x", false) ui_general.keybinds_y = gui.add_slider("Keybinds y", "lua>tab a", 0, e_global.SCREEN[2], 1); gui.set_visible("lua>tab a>Keybinds y", false) --- @endregion --- @region: watermark local watermark = {} function watermark.handle() if (not ui_general.watermark:get_bool()) then return end local accent_color = ui_general.accent_color:get_color() local a_r, a_g, a_b = accent_color.r, accent_color.g, accent_color.b local prefix = "fatality" local ping = math.floor((utils.get_rtt() or 0) * 1000) local latency = ping >= 1 and (" | %dms"):format(ping) or "" local time = utils.get_time() local actual_time = ("%s:%s"):format(time.hour, time.min) local text = ("%s | %s%s | %s"):format(prefix, info.fatality.username, latency, actual_time) local text_size = {render.get_text_size(fonts.verdana.default, text)} local x, y = e_global.SCREEN[1], 8 local width, height = animation.new("watermark width", text_size[1] + 12, 8), 22 x = x - width - 10 draw.window(math.vec3(x, y), math.vec3(width, height), render.color(a_r, a_g, a_b, 255), ui_general.glow:get_bool()) render.text(fonts.verdana.default, x + (width / 2) - (text_size[1] / 2), y + (height / 2) - (text_size[2] / 2) + 1, text, render.color(255, 255, 255, 255)) end --- @endregion --- @region: keybinds local keybinds = {} keybinds.active = {} keybinds.list = { ["Double tap"] = "rage>aimbot>aimbot>double tap", ["On shot anti-aim"] = "rage>aimbot>aimbot>hide shot", ["Minimum damage"] = "rage>aimbot>ssg08>scout>override", ["Force safepoint"] = "rage>aimbot>aimbot>force extra safety", ["Headshot only"] = "rage>aimbot>aimbot>headshot only", ["Duck peek assist"] = "misc>movement>fake duck", ["Quick peek assist"] = "misc>movement>peek assist" } keybinds.width = 0 keybinds.modes = { [0] = "always", [1] = "holding", [2] = "toggled", [3] = "off" } keybinds.dragging = c_drag.new(ui_general.keybinds_x, ui_general.keybinds_y, 0, 0) function keybinds.handle() if (not ui_general.keybinds:get_bool()) then return end local accent_color = ui_general.accent_color:get_color() local a_r, a_g, a_b = accent_color.r, accent_color.g, accent_color.b local latest_item = false local maximum_offset = 66 for bind_name, path in pairs(keybinds.list) do local item_active = gui.get_config_item(path):get_bool() if (item_active) then latest_item = true if (keybinds.active[bind_name] == nil) then keybinds.active[bind_name] = {mode = "", alpha = 0, offset = 0, active = false} end local key_code, key_type = gui.get_keybind(path) local bind_mode = keybinds.modes[key_type] local bind_name_size = {render.get_text_size(fonts.verdana.default, bind_name)} local bind_state_size = {render.get_text_size(fonts.verdana.default, bind_mode)} keybinds.active[bind_name].mode = bind_mode keybinds.active[bind_name].alpha = animation.lerp(keybinds.active[bind_name].alpha, 1, 12) keybinds.active[bind_name].offset = bind_name_size[1] + bind_state_size[1] keybinds.active[bind_name].active = true elseif (keybinds.active[bind_name] ~= nil) then keybinds.active[bind_name].alpha = animation.lerp(keybinds.active[bind_name].alpha, 0, 12) keybinds.active[bind_name].active = false if (keybinds.active[bind_name].alpha < 0.1) then keybinds.active[bind_name] = nil end end if (keybinds.active[bind_name] ~= nil and keybinds.active[bind_name].offset > maximum_offset) then maximum_offset = keybinds.active[bind_name].offset end end local alpha = animation.new("keybinds alpha", (gui.is_menu_open() or table.count(keybinds.active) > 0 and latest_item) and 1 or 0, 12) local text = "keybinds" local text_size = {render.get_text_size(fonts.verdana.default, text)} local x, y = keybinds.dragging:get() local width, height = animation.new("keybinds width", 30 + maximum_offset, 8), 22 local height_offset = height + 3 draw.window(math.vec3(x, y), math.vec3(width, height), render.color(a_r, a_g, a_b, 255 * alpha), ui_general.glow:get_bool()) render.text(fonts.verdana.default, x + (width / 2) - (text_size[1] / 2), y + (height / 2) - (text_size[2] / 2) + 1, text, render.color(255, 255, 255, 255 * alpha)) for bind_name, value in pairs(keybinds.active) do local key_type = "[" .. (value.mode or "?") .. "]" local key_type_size = {render.get_text_size(fonts.verdana.default, key_type)} render.text(fonts.verdana.default, x + 5, y + height_offset, bind_name, render.color(255, 255, 255, 255 * alpha * value.alpha)) render.text(fonts.verdana.default, x + width - key_type_size[1] - 5, y + height_offset, key_type, render.color(255, 255, 255, 255 * alpha * value.alpha)) height_offset = height_offset + 15 * value.alpha end keybinds.dragging:handle(width, (table.count(keybinds.active) > 0 and height_offset or height)) end --- @endregion --- @region: events --- @event: on_paint function on_paint() keybinds.handle() watermark.handle() end --- @endregion