Загрузка данных
-- ... existing code ...
-- STREAMING_CHUNK:Implementing 3D to 2D screen calculations for character bounding boxes...
local function getPedScreenBoundingBox(ped)
if not doesCharExist(ped) or isCharDead(ped) then return false end
-- Проверяем, находится ли персонаж в объективе камеры (работает и за стенами)
if not isCharOnScreen(ped) then
return false
end
local ped_x, ped_y, ped_z = getCharCoordinates(ped)
-- Конвертируем 3D координаты ног и головы в 2D координаты экрана (convert3DCoordsToScreen)
local foot_x, foot_y = convert3DCoordsToScreen(ped_x, ped_y, ped_z - 1.0)
local head_x, head_y = convert3DCoordsToScreen(ped_x, ped_y, ped_z + 0.9)
if foot_x and foot_y and head_x and head_y 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
end
return false
end
-- STREAMING_CHUNK:Rendering visual overlays on screen without ImGui...
function renderESP()
if not esp_enabled then return end
local my_ped = PLAYER_PED
if not doesCharExist(my_ped) then return end
render_w, render_h = getScreenResolution()
local my_x, my_y, my_z = getCharCoordinates(my_ped)
local origin_x = render_w / 2
local origin_y = render_h
for _, ped in ipairs(getAllChars()) do
if ped ~= my_ped and doesCharExist(ped) and not isCharDead(ped) then
local px, py, pz = getCharCoordinates(ped)
local distance = getDistanceBetweenCoords3d(my_x, my_y, my_z, px, py, pz)
if distance <= 150.0 then
local valid, box_x, box_y, box_w, box_h, foot_x, foot_y = getPedScreenBoundingBox(ped)
if valid then
-- Трейсеры (линии от низа экрана к игроку)
renderDrawLine(origin_x, origin_y, foot_x, foot_y, 1.5, COLOR_TRACER)
-- 2D Квадратная рамка
drawBoxBorder(box_x, box_y, box_w, box_h, 1.5, COLOR_BOX)
-- Полоса здоровья (HP Bar)
local health = getCharHealth(ped)
if health > 100 then health = 100 end
if health < 0 then health = 0 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, COLOR_BG)
local hp_r = math.floor((100 - health) * 2.55)
local hp_g = math.floor(health * 2.55)
local hp_color = 0xFF000000 + (hp_r * 65536) + (hp_g * 256)
renderDrawBox(bar_x, bar_y, 4, bar_h, hp_color)
-- Никнейм, ID и Дистанция
local player_name = ""
if isSampLoaded() then
local res, id = sampGetPlayerIdByCharHandle(ped)
if res and id then
local nickname = sampGetPlayerNickname(id)
if nickname and #nickname > 0 then
player_name = nickname .. " [" .. id .. "]"
end
end
end
if player_name == "" then
player_name = toCP1251("Игрок")
end
local text_str = string.format("%s (%d%s)", player_name, math.floor(distance), toCP1251("м"))
if #text_str > 0 and esp_font then
local text_len = renderGetFontDrawTextLength(esp_font, text_str)
renderFontDrawText(esp_font, text_str, box_x + (box_w / 2) - (text_len / 2), box_y - 15, COLOR_TEXT)
end
end
end
end
end
end
-- STREAMING_CHUNK:Registering events, hotkeys and initializing script main loop...
function main()
while not isSampAvailable() do wait(100) end
esp_font = renderCreateFont("Arial", 9, 5)
local msg_loaded = toCP1251("[Wallhack]: Скрипт успешно загружен! Включение/Выключение: RSHIFT или /esp")
sampAddChatMessage(msg_loaded, 0x0088FF)
local function toggleESP()
esp_enabled = not esp_enabled
local status_str = esp_enabled and toCP1251("[Wallhack]: Статус: {00FF00}ВКЛЮЧЕН") or toCP1251("[Wallhack]: Статус: {FF0000}ВЫКЛЮЧЕН")
sampAddChatMessage(status_str, 0xFFFFFF)
end
sampRegisterChatCommand("esp", toggleESP)
while true do
wait(0)
if isKeyJustPressed(moonloader.VK_RSHIFT) and not sampIsChatInputActive() and not sampIsDialogActive() then
toggleESP()
end
renderESP()
end
end