- 5
- 0
- Версия SA-MP
-
- 0.3.7-R3
Код:
script_name("Fura Tools v1.0 by sLR")
script_author("sLR")
local imgui = require 'imgui'
local sampev = require 'samp.events'
-- ===== STATE =====
local window = imgui.ImBool(false)
local tab = 0
local selected = -1
local distance = imgui.ImFloat(50)
local auto = imgui.ImBool(true)
local auto_spawn = imgui.ImBool(false)
local bullet_tracer = imgui.ImBool(false)
local highlight_player = imgui.ImBool(false)
local players = {}
local copied_players = {}
local bullets = {}
-- ===== STYLE =====
function style()
imgui.SwitchContext()
local s = imgui.GetStyle()
local c = s.Colors
local clr = imgui.Col
local v4 = imgui.ImVec4
s.WindowPadding = imgui.ImVec2(0,0)
s.FramePadding = imgui.ImVec2(6,4)
s.ItemSpacing = imgui.ImVec2(8,6)
s.WindowRounding = 8
s.FrameRounding = 6
c[clr.WindowBg] = v4(0.08,0.09,0.11,1)
c[clr.ChildWindowBg] = v4(0.10,0.11,0.14,1)
c[clr.Button] = v4(0.16,0.18,0.25,1)
c[clr.ButtonHovered] = v4(0.28,0.45,1,1)
c[clr.ButtonActive] = v4(0.18,0.35,0.9,1)
c[clr.Header] = v4(0.2,0.3,0.6,0.4)
c[clr.HeaderHovered] = v4(0.3,0.5,1,0.8)
c[clr.HeaderActive] = v4(0.3,0.5,1,1)
end
-- ===== SCAN =====
function scan()
players = {}
if not doesCharExist(PLAYER_PED) then return end
local px,py,pz = getCharCoordinates(PLAYER_PED)
for i = 0, 1003 do
if sampIsPlayerConnected(i) then
local ok, ped = sampGetCharHandleBySampPlayerId(i)
if ok and ped and doesCharExist(ped) then
local x,y,z = getCharCoordinates(ped)
if x then
local dist = getDistanceBetweenCoords3d(px,py,pz,x,y,z)
table.insert(players,{
id = i, dist = dist, ped = ped,
nick = sampGetPlayerNickname(i) or "Unknown",
in_zone = (dist <= distance.v)
})
end
end
end
end
table.sort(players,function(a,b) return a.dist < b.dist end)
end
-- ===== MAIN =====
function main()
repeat wait(100) until isSampAvailable()
style()
sampAddChatMessage("{FFFFFF}[Fura Tools]{FF0000} Загружено. Введите /bws", -1)
sampRegisterChatCommand("bws", function()
window.v = not window.v
end)
while true do
wait(0)
imgui.Process = window.v
if auto.v and window.v then scan() end
-- === ОТРИСОВКА ТРЕЙСЕРОВ ===
if bullet_tracer.v and #bullets > 0 then
local now = os.clock()
for i = #bullets, 1, -1 do
local b = bullets[i]
-- Удаляем через 1 секунду
if now - b.time > 1.0 then
table.remove(bullets, i)
else
-- ИСПОЛЬЗУЕМ Ex ВЕРСИЮ! false, false означает "рисовать даже если за камерой"
local res1, sx1, sy1 = convert3DCoordsToScreenEx(b.ox, b.oy, b.oz, false, false)
local res2, sx2, sy2 = convert3DCoordsToScreenEx(b.tx, b.ty, b.tz, false, false)
-- Если координаты получены
if res1 and res2 and sx1 and sy1 and sx2 and sy2 then
-- Жестко заданный красный цвет без прозрачности, чтобы 100% было видно
renderDrawLine(sx1, sy1, sx2, sy2, 0xFFFF0000, 3.0)
end
end
end
end
-- Отрисовка подсветки игрока
if highlight_player.v and selected ~= -1 and players[selected] then
local player_ped = players[selected].ped
if player_ped and doesCharExist(player_ped) then
local px, py, pz = getCharCoordinates(PLAYER_PED)
local plx, ply, plz = getCharCoordinates(player_ped)
if px and py and pz and plx and ply and plz then
renderDrawLine(px, py, pz, plx, ply, plz, 0xFF00FF00)
end
end
end
end
end
-- ===== EVENT HANDLERS =====
function sampev.onSendBulletSync(data)
if bullet_tracer.v then
if data.origin and data.target and type(data.origin.x) == "number" and type(data.target.x) == "number" then
table.insert(bullets, {
ox = data.origin.x,
oy = data.origin.y,
oz = data.origin.z,
tx = data.target.x,
ty = data.target.y,
tz = data.target.z,
time = os.clock()
})
end
end
end
-- ===== UI =====
function imgui.OnDrawFrame()
if not window.v then return end
imgui.SetNextWindowSize(imgui.ImVec2(520,420), imgui.Cond.Once)
imgui.Begin("##main", window, imgui.WindowFlags.NoTitleBar + imgui.WindowFlags.NoResize + imgui.WindowFlags.NoCollapse)
imgui.PushStyleColor(imgui.Col.ChildWindowBg, imgui.ImVec4(0.12,0.14,0.18,1))
imgui.BeginChild("header", imgui.ImVec2(0,40), false)
imgui.SetCursorPosY(10)
imgui.SetCursorPosX(15)
imgui.TextColored(imgui.ImVec4(0.4,0.7,1,1), "Fura Tools v1.0 by sLR")
imgui.SameLine(imgui.GetWindowWidth() - 35)
if imgui.Button("X", imgui.ImVec2(25,20)) then window.v = false end
imgui.EndChild()
imgui.PopStyleColor()
imgui.BeginChild("tabs", imgui.ImVec2(0,45), false)
imgui.SetCursorPosX(10)
if imgui.Button("Игроки", imgui.ImVec2(170,30)) then tab = 0; scan() end
imgui.SameLine(190)
if imgui.Button("Дополнительно", imgui.ImVec2(170,30)) then tab = 1 end
imgui.SameLine(370)
if imgui.Button("Настройки", imgui.ImVec2(130,30)) then tab = 2 end
imgui.EndChild()
imgui.Separator()
imgui.SetCursorPosX(10)
imgui.BeginChild("content", imgui.ImVec2(-10,-10), false)
if tab == 0 then
imgui.Text("Дистанция сканирования")
local changed = false
if imgui.Button("-", imgui.ImVec2(28,20)) then distance.v = math.max(5, distance.v - 1); changed = true end
imgui.SameLine()
if imgui.SliderFloat("##dist", distance, 5, 300, "%.0f m") then changed = true end
imgui.SameLine()
if imgui.Button("+", imgui.ImVec2(28,20)) then distance.v = math.min(300, distance.v + 1); changed = true end
imgui.SameLine()
if imgui.InputFloat("##dist_input", distance, 0, 0, "%.0f") then
if distance.v < 5 then distance.v = 5 end
if distance.v > 300 then distance.v = 300 end
changed = true
end
imgui.Dummy(imgui.ImVec2(0,0))
imgui.AlignTextToFramePadding()
imgui.Checkbox("Авто сканирование", auto)
imgui.SameLine()
imgui.AlignTextToFramePadding()
if imgui.Checkbox("Подсветить игрока", highlight_player) then
if not highlight_player.v then selected = -1 end
end
imgui.Dummy(imgui.ImVec2(0,2))
if changed then scan(); selected = -1; highlight_player.v = false end
local total = #players
local in_zone_count = 0
for _,p in ipairs(players) do if p.in_zone then in_zone_count = in_zone_count + 1 end end
imgui.Text(string.format("В зоне: %d / Всего: %d", in_zone_count, total))
imgui.BeginChild("list", imgui.ImVec2(0,-70), true)
for i,p in ipairs(players) do
local label = string.format("ID %d | %s | %.1fm", p.id, p.nick, p.dist)
if p.in_zone then imgui.PushStyleColor(imgui.Col.Text, imgui.ImVec4(0.45,0.95,0.45,1)) end
if imgui.Selectable(label, selected == i) then selected = i end
if p.in_zone then imgui.PopStyleColor() end
end
imgui.EndChild()
if selected ~= -1 and players[selected] then
if imgui.Button("Телепортировать игрока", imgui.ImVec2(-1,28)) then
sampSendChat("/gethere "..players[selected].id)
end
end
if imgui.Button("Скопировать ID", imgui.ImVec2(250,28)) then
copied_players = {}
for _,p in ipairs(players) do table.insert(copied_players, p) end
local buf=""
for _,p in ipairs(copied_players) do buf = buf.."/gethere "..p.id.."\n" end
imgui.SetClipboardText(buf)
end
imgui.SameLine()
if imgui.Button("Телепортировать всех", imgui.ImVec2(250,28)) then
if #copied_players > 0 then
lua_thread.create(function()
for _,p in ipairs(copied_players) do sampSendChat("/gethere "..p.id); wait(1000) end
end)
end
end
end
if tab == 1 then
imgui.AlignTextToFramePadding()
imgui.Checkbox("Авто спавн при сливе", auto_spawn)
imgui.SameLine()
if imgui.Button("?", imgui.ImVec2(20,20)) then end
if imgui.IsItemHovered() then
imgui.SetNextWindowSize(imgui.ImVec2(340, 180), imgui.Cond.Always)
imgui.BeginTooltip()
imgui.TextWrapped("Это автоспавн всех игроков без цветного клиста.")
imgui.TextWrapped("Точнее: если ты стоишь в доме возле строя и кто-то залетает на спидхаке,")
imgui.TextWrapped("и начинает с софтом сливать всех, но ты не можешь увидеть ID — просто нажми Alt + X.")
imgui.TextWrapped("Все игроки без фракции и цветного клиста будут заспавнены.")
imgui.TextWrapped("Работает только когда галочка активна.")
imgui.EndTooltip()
end
imgui.Dummy(imgui.ImVec2(0, 5))
imgui.AlignTextToFramePadding()
if imgui.Checkbox("Bullet tracer", bullet_tracer) then
if not bullet_tracer.v then bullets = {} end
end
imgui.SameLine()
if imgui.Button("?", imgui.ImVec2(20,20)) then end
if imgui.IsItemHovered() then
imgui.SetNextWindowSize(imgui.ImVec2(340, 60), imgui.Cond.Always)
imgui.BeginTooltip()
imgui.TextWrapped("Отрисовывает линии когда при стрельбе.")
imgui.EndTooltip()
end
end
if tab == 2 then
end
imgui.EndChild()
imgui.End()
end