Загрузка данных
-- STREAMING_CHUNK:Loading required dependencies and modules...
local script_name = "SAMP Wallhack & Visuals"
local script_author = "Assistant"
local script_version = "1.0"
local moonloader = require 'moonloader'
local imgui = require 'mimgui'
local encoding = require 'encoding'
local ffi = require 'ffi'
encoding.default = 'CP1251'
local u8 = encoding.UTF8
-- STREAMING_CHUNK:Initializing state variables and configuration settings...
local main_window_state = imgui.new.bool(false)
local config = {
esp_enabled = imgui.new.bool(true),
box_enabled = imgui.new.bool(true),
tracer_enabled = imgui.new.bool(true),
names_enabled = imgui.new.bool(true),
hp_bar_enabled = imgui.new.bool(true),
dist_enabled = imgui.new.bool(true),
ignore_ped_dead = imgui.new.bool(true),
tracer_origin = imgui.new.int(0),
max_distance = imgui.new.float(150.0),
line_thickness = imgui.new.float(1.5),
box_color = imgui.new.float[4](0.2, 0.8, 1.0, 1.0),
tracer_color = imgui.new.float[4](1.0, 0.2, 0.2, 0.8),
text_color = imgui.new.float[4](1.0, 1.0, 1.0, 1.0)
}
local render_w, render_h = getScreenResolution()
-- STREAMING_CHUNK:Defining color conversion helper functions...
local function imguiColorToARGB(imgui_color)
local r = math.floor(imgui_color[0] * 255)
local g = math.floor(imgui_color[1] * 255)
local b = math.floor(imgui_color[2] * 255)
local a = math.floor(imgui_color[3] * 255)
return bit.or(bit.or(bit.or(bit.lshift(a, 24), bit.lshift(r, 16)), bit.lshift(g, 8)), b)
end
-- STREAMING_CHUNK:Setting up ImGui user interface frame and layout...
imgui.OnFrame(function()
return main_window_state[0]
end, function(player)
imgui.SetNextWindowSize(imgui.ImVec2(420, 360), imgui.Cond.FirstUseEver)
imgui.Begin(u8"Настройки ESP / Wallhack", main_window_state, imgui.WindowFlags.NoCollapse)
imgui.Text(u8"Управление функциями визуализации:")
imgui.Separator()
imgui.Checkbox(u8"Включить ESP / Wallhack", config.esp_enabled)
if config.esp_enabled[0] then
imgui.Spacing()
if imgui.TreeNode(u8"Отображение элементов") then
imgui.Checkbox(u8"Квадратные боксы (2D Box)", config.box_enabled)
imgui.SameLine()
imgui.ColorEdit4(u8"Цвет Бокса##box_col", config.box_color, imgui.ColorEditFlags.NoInputs)
imgui.Checkbox(u8"Линии к игрокам (Tracers)", config.tracer_enabled)
imgui.SameLine()
imgui.ColorEdit4(u8"Цвет Линий##line_col", config.tracer_color, imgui.ColorEditFlags.NoInputs)
imgui.Checkbox(u8"Имена и ID игроков", config.names_enabled)
imgui.Checkbox(u8"Полоска здоровья (HP Bar)", config.hp_bar_enabled)
imgui.Checkbox(u8"Дистанция до игрока", config.dist_enabled)
imgui.Checkbox(u8"Игнорировать мертвых", config.ignore_ped_dead)
imgui.TreePop()
end
imgui.Spacing()
imgui.Separator()
if imgui.TreeNode(u8"Параметры и позиционирование") then
imgui.Text(u8"Точка старта линий:")
imgui.RadioButtonIntPtr(u8"Снизу экрана", config.tracer_origin, 0)
imgui.SameLine()
imgui.RadioButtonIntPtr(u8"Из центра экрана", config.tracer_origin, 1)
imgui.SliderFloat(u8"Макс. дистанция", config.max_distance, 10.0, 500.0, "%.0fm")
imgui.SliderFloat(u8"Толщина линий", config.line_thickness, 1.0, 5.0, "%.1f px")
imgui.TreePop()
end
end
imgui.Separator()
imgui.TextDisabled(u8"Активация меню: клавиша RSHIFT или команда /esp")
imgui.End()
end)
-- STREAMING_CHUNK:Implementing 3D to 2D math calculations for character bounding boxes...
local function getPedScreenBoundingBox(ped)
local ped_x, ped_y, ped_z = getCharCoordinates(ped)
local res_foot, foot_x, foot_y = convert3DCoordsToScreen(ped_x, ped_y, ped_z - 1.0)
local res_head, head_x, head_y = convert3DCoordsToScreen(ped_x, ped_y, ped_z + 0.9)
if res_foot and res_head then
local height = math.abs(foot_y - head_y)
local width = height / 2.1
local x = head_x - (width / 2)
local y = head_y
return true, x, y, width, height, foot_x, foot_y, head_x, head_y
end
return false
end
-- STREAMING_CHUNK:Rendering visual overlays (boxes, lines, text) on screen...
function renderESP()
if not config.esp_enabled[0] then return end
local my_ped = PLAYER_PED
local my_x, my_y, my_z = getCharCoordinates(my_ped)
local origin_x = render_w / 2
local origin_y = (config.tracer_origin[0] == 0) and render_h or (render_h / 2)
for _, ped in ipairs(getAllChars()) do
if ped ~= my_ped and doesCharExist(ped) then
local dead_check = config.ignore_ped_dead[0] and isCharDead(ped)
if not dead_check then
local px, py, pz = getCharCoordinates(ped)
local distance = getDistanceBetweenCoords3d(my_x, my_y, my_z, px, py, pz)
if distance <= config.max_distance[0] then
local valid, box_x, box_y, box_w, box_h, foot_x, foot_y, head_x, head_y = getPedScreenBoundingBox(ped)
if valid then
local box_argb = imguiColorToARGB(config.box_color)
local tracer_argb = imguiColorToARGB(config.tracer_color)
local text_argb = imguiColorToARGB(config.text_color)
if config.tracer_enabled[0] then
renderDrawLine(origin_x, origin_y, foot_x, foot_y, config.line_thickness[0], tracer_argb)
end
if config.box_enabled[0] then
renderDrawBorder(box_x, box_y, box_w, box_h, config.line_thickness[0], box_argb)
end
if config.hp_bar_enabled[0] then
local health = getCharHealth(ped)
if health > 100 then health = 100 end
local bar_h = (box_h * health) / 100
local bar_x = box_x - 6
local bar_y = box_y + (box_h - bar_h)
renderDrawBox(bar_x, box_y, 4, box_h, 0x88000000)
local hp_color = bit.or(0xFF000000, bit.or(bit.lshift(math.floor((100 - health) * 2.55), 16), bit.lshift(math.floor(health * 2.55), 8)))
renderDrawBox(bar_x, bar_y, 4, bar_h, hp_color)
end
if config.names_enabled[0] or config.dist_enabled[0] then
local text_str = ""
local res, id = sampGetPlayerIdByCharHandle(ped)
if res and config.names_enabled[0] then
local name = sampGetPlayerNickname(id)
text_str = string.format("%s [%d]", name, id)
elseif config.names_enabled[0] then
text_str = "NPC / Ped"
end
if config.dist_enabled[0] then
text_str = text_str .. string.format(" (%.1fm)", distance)
end
if #text_str > 0 then
local font = renderCreateFont("Arial", 9, 5)
renderFontDrawText(font, text_str, box_x + (box_w / 2), box_y - 15, text_argb, true)
end
end
end
end
end
end
end
end
-- STREAMING_CHUNK:Registering events, hotkeys and initializing script main loop...
function main()
if not isSampLoaded() or not isSampfuncsLoaded() then return end
while not isSampAvailable() do wait(100) end
sampAddChatMessage(string.format("[%s]: Скрипт загружен. Меню: /esp или RSHIFT.", script_name), 0x0088FF)
sampRegisterChatCommand("esp", function()
main_window_state[0] = not main_window_state[0]
end)
while true do
wait(0)
if isKeyJustPressed(moonloader.VK_RSHIFT) and not sampIsChatInputActive() and not sampIsDialogActive() then
main_window_state[0] = not main_window_state[0]
end
renderESP()
end
end