-- ============================================================================= -- Creado y Desarrollado por SPTEAM -- CLIENTE: GUILDZONE MANAGEMENT HUD (V3.1 BLINDADO ANTI-CRASH UP43/UP44) -- ============================================================================= local GZ_UI = { WindowID = 241, ENABLE_EDITOR = false, -- false para jugadores | true para diseño Images = { HUD = 50214, Scroll = 50210, BtnReg = 50211, BtnClose = 50213, }, RDB = { [800] = { WinX = 405, WinY = 23 }, [1024] = { WinX = 408, WinY = 42 }, [1360] = { WinX = 500, WinY = 50 } }, Calib = { WinW = 233, WinH = 219, RegX = 51, RegY = 183, RegW = 117, RegH = 28, CloseX = 181, CloseY = 6, CloseW = 28, CloseH = 27, RowY = 62, RowStepY = 25, ColClanX = 21, ColZoneX = 132, ScrollX = 192, ScrollY = 60, ScrollW = 5, ScrollH = 111, ScrollBarH = 20, }, Keys = { LButton = 1, Escape = 27, Num1 = 97, Num0 = 96, Num5 = 101, Num3 = 99 } } local NativeWindows = { 1, 2, 4, 6, 12, 13, 16 } GuildZone_State = { Show = false, Simulate = false, Clans = {}, Scroll = 0, MaxVisible = 5, Dragging = false, OffX = 0, OffY = 0, EditMode = 0, EditStep = 1, ClickFeedback = { Reg = 0, Close = 0 }, OpenMap = -1 } -- Helpers seguros compatibles con API nativa y Wrappers local function SafeDisableClick() if DisableClickClient then DisableClickClient() elseif DisableCLick then DisableCLick() end end local function SafeRenderText(x, y, txt, w, sort) if RenderText3 then RenderText3(x, y, txt or "", w or 0, sort or 0) elseif RenderText then RenderText(x, y, txt or "", w or 0, sort or 1) end end local function CloseGuildZoneWindow() GuildZone_State.Show = false GuildZone_State.Dragging = false if UICustomInterface == GZ_UI.WindowID then UICustomInterface = 0 end end function GuildZone_GetConfig() local W = WindowGetWidth() local cfg = GZ_UI.RDB[1360] if W <= 800 then cfg = GZ_UI.RDB[800] elseif W <= 1024 then cfg = GZ_UI.RDB[1024] end return cfg end local function GZ_IsMouseIn(x, y, w, h) local mx, my = MousePosX(), MousePosY() return (mx >= x and mx <= x + w and my >= y and my <= y + h) end function GuildZone_ApplyScroll(Value) local total = #GuildZone_State.Clans if total <= GuildZone_State.MaxVisible then GuildZone_State.Scroll = 0 return end local MaxScroll = total - GuildZone_State.MaxVisible GuildZone_State.Scroll = GuildZone_State.Scroll + Value if GuildZone_State.Scroll < 0 then GuildZone_State.Scroll = 0 end if GuildZone_State.Scroll > MaxScroll then GuildZone_State.Scroll = MaxScroll end end function GuildZone_ScrollWheel(Value) if GetMainScene() ~= 5 or not GuildZone_State.Show then return end local cfg = GuildZone_GetConfig() if GZ_IsMouseIn(cfg.WinX, cfg.WinY, GZ_UI.Calib.WinW, GZ_UI.Calib.WinH) then if Value > 0 then GuildZone_ApplyScroll(-1) else GuildZone_ApplyScroll(1) end end end -- [LEY #6 SPTEAM: PROHIBIDO CLEARPACKET EN RECEPCIÓN + AUTO-SHIFT U42/U43/U44] function GuildZone_Protocol(Packet, PacketName) if PacketName == "GZ_List" then local shift = 0 local SubID = GetBytePacket(PacketName, 0) if SubID == Packet then SubID = GetBytePacket(PacketName, 1) shift = 1 end if SubID == 0x01 then local Count = GetBytePacket(PacketName, 1 + shift) or 0 GuildZone_State.Clans = {} local offset = 2 + shift for i = 1, Count do local name = "" for n = 0, 9 do local char = GetBytePacket(PacketName, offset + n) if char and char > 0 then name = name .. string.char(char) end end local zone = GetBytePacket(PacketName, offset + 10) or 0 offset = offset + 11 GuildZone_State.Clans[i] = { name = name, zone = zone } end GuildZone_ApplyScroll(0) GuildZone_State.Show = true GuildZone_State.OpenMap = GetCharacterMap() UICustomInterface = GZ_UI.WindowID PlaySound(25, 0) end return true end return false end local function GuildZone_MainTick() if not GuildZone_State.Show then return false end -- Regla 0: Validar escena In-Game if GetMainScene() ~= 5 then CloseGuildZoneWindow() return false end -- Regla 1: Cerrar si se abren ventanas nativas del juego (Caso 12) for i = 1, #NativeWindows do if CheckWindowOpen(NativeWindows[i]) == 1 then CloseGuildZoneWindow() return false end end -- Regla 2: Cerrar si el jugador cambió de mapa (Caso 13) if GetCharacterMap() ~= GuildZone_State.OpenMap then CloseGuildZoneWindow() return false end -- Regla 3: Reclamar foco sobre ReyDelMu (205) o libre (0) if UICustomInterface == 0 or UICustomInterface == 205 then UICustomInterface = GZ_UI.WindowID elseif UICustomInterface ~= GZ_UI.WindowID then CloseGuildZoneWindow() return false end return true end local function GuildZone_Render_Internal() if not GuildZone_MainTick() then return end local cfg = GuildZone_GetConfig() local UX, UY = cfg.WinX, cfg.WinY local c = GZ_UI.Calib DisableAlphaBlend() SetBlend(1) glColor4f(1.0, 1.0, 1.0, 1.0) RenderImage2(GZ_UI.Images.HUD, UX, UY, c.WinW, c.WinH, 0, 0, 1.0, 1.0, 1, 1, 1.0) local isClicking = (CheckPressedKey(GZ_UI.Keys.LButton) == 1) local curTime = os.clock() if GZ_IsMouseIn(UX + c.CloseX, UY + c.CloseY, c.CloseW, c.CloseH) then if not isClicking and (curTime - GuildZone_State.ClickFeedback.Close > 0.15) then RenderImage2(GZ_UI.Images.BtnClose, UX + c.CloseX, UY + c.CloseY, c.CloseW, c.CloseH, 0, 0, 1.0, 1.0, 1, 1, 1.0) end elseif GZ_IsMouseIn(UX + c.RegX, UY + c.RegY, c.RegW, c.RegH) then if not isClicking and (curTime - GuildZone_State.ClickFeedback.Reg > 0.15) then RenderImage2(GZ_UI.Images.BtnReg, UX + c.RegX, UY + c.RegY, c.RegW, c.RegH, 0, 0, 1.0, 1.0, 1, 1, 1.0) end end SetFontType(1) SetTextBg(0, 0, 0, 0) SetTextColor(255, 255, 255, 255) local start = GuildZone_State.Scroll + 1 local finish = math.min(start + GuildZone_State.MaxVisible - 1, #GuildZone_State.Clans) local rowIdx = 0 for i = start, finish do local clan = GuildZone_State.Clans[i] if clan then local rY = UY + c.RowY + (rowIdx * c.RowStepY) SafeRenderText(UX + c.ColClanX, rY, clan.name, 100, 3) SafeRenderText(UX + c.ColZoneX, rY, "Zona " .. tostring(clan.zone), 60, 3) rowIdx = rowIdx + 1 end end if #GuildZone_State.Clans > GuildZone_State.MaxVisible then local MaxScroll = #GuildZone_State.Clans - GuildZone_State.MaxVisible local scrollRatio = GuildZone_State.Scroll / MaxScroll local scrollY = UY + c.ScrollY + (scrollRatio * (c.ScrollH - c.ScrollBarH)) RenderImage2(GZ_UI.Images.Scroll, UX + c.ScrollX, scrollY, c.ScrollW, c.ScrollBarH, 0, 0, 1.0, 1.0, 1, 1, 1.0) end if GuildZone_State.EditMode > 0 then SetTextBg(0, 0, 0, 200) SetTextColor(0, 255, 0, 255) SafeRenderText(10, 100, "GZ-EDITOR MODO: " .. tostring(GuildZone_State.EditMode), 400, 1) end -- Restauración limpia del pipeline OpenGL SetTextBg(0, 0, 0, 0) SetTextColor(255, 255, 255, 255) SetBlend(0) DisableAlphaBlend() glColor4f(1.0, 1.0, 1.0, 1.0) end function GuildZone_Render() local ok = pcall(GuildZone_Render_Internal) if not ok then SetTextBg(0, 0, 0, 0) SetTextColor(255, 255, 255, 255) SetBlend(0) DisableAlphaBlend() glColor4f(1.0, 1.0, 1.0, 1.0) end end function GuildZone_Mouse() if GetMainScene() ~= 5 or not GuildZone_State.Show then return end local cfg = GuildZone_GetConfig() local UX, UY = cfg.WinX, cfg.WinY local c = GZ_UI.Calib if GZ_IsMouseIn(UX, UY, c.WinW, c.WinH) then SafeDisableClick() end if CheckPressedKey(GZ_UI.Keys.LButton) == 1 then -- Botón Cerrar if GZ_IsMouseIn(UX + c.CloseX, UY + c.CloseY, c.CloseW, c.CloseH) then GuildZone_State.ClickFeedback.Close = os.clock() CloseGuildZoneWindow() PlaySound(25, 0) return end -- Botón Registrar (Con ClearPacket obligatorio en salientes) if GZ_IsMouseIn(UX + c.RegX, UY + c.RegY, c.RegW, c.RegH) then GuildZone_State.ClickFeedback.Reg = os.clock() local Pkt = "GZ_REG" CreatePacket(Pkt, GZ_UI.WindowID) SendPacket(Pkt) ClearPacket(Pkt) PlaySound(25, 0) return end -- Arrastrar ventana if not GuildZone_State.Dragging and GZ_IsMouseIn(UX, UY, c.WinW, 40) then GuildZone_State.Dragging = true GuildZone_State.OffX = MousePosX() - UX GuildZone_State.OffY = MousePosY() - UY end end if CheckReleasedKey(GZ_UI.Keys.LButton) == 1 then GuildZone_State.Dragging = false end if GuildZone_State.Dragging then cfg.WinX = MousePosX() - GuildZone_State.OffX cfg.WinY = MousePosY() - GuildZone_State.OffY end end function GuildZone_Keyboard(Key) if GetMainScene() ~= 5 then return false end if UIChatWindow and CheckWindowOpen(UIChatWindow) == 1 then return false end if Key == GZ_UI.Keys.Escape and GuildZone_State.Show then CloseGuildZoneWindow() PlaySound(25, 0) return true end if GZ_UI.ENABLE_EDITOR then if Key == GZ_UI.Keys.Num1 then GuildZone_State.Simulate = not GuildZone_State.Simulate GuildZone_State.EditMode = GuildZone_State.Simulate and 1 or 0 if not GuildZone_State.Simulate then CloseGuildZoneWindow() else GuildZone_State.Show = true GuildZone_State.OpenMap = GetCharacterMap() UICustomInterface = GZ_UI.WindowID end PlaySound(25, 0) return true end if GuildZone_State.EditMode > 0 then if Key == GZ_UI.Keys.Num5 then GuildZone_State.EditMode = (GuildZone_State.EditMode % 6) + 1 PlaySound(25, 0) return true end if Key == GZ_UI.Keys.Num0 then local cfg = GuildZone_GetConfig(); local c = GZ_UI.Calib Console(1, string.format("GZ_CONFIG: WinX=%d, WinY=%d | BASE: WinW=%d, WinH=%d, RegX=%d, RegY=%d, RegW=%d, RegH=%d", cfg.WinX, cfg.WinY, c.WinW, c.WinH, c.RegX, c.RegY, c.RegW, c.RegH)) return true end local step = 1; local m = GuildZone_State.EditMode; local c = GZ_UI.Calib; local cfg = GuildZone_GetConfig() if m == 1 then if Key == 37 then cfg.WinX = cfg.WinX - step elseif Key == 39 then cfg.WinX = cfg.WinX + step elseif Key == 38 then cfg.WinY = cfg.WinY - step elseif Key == 40 then cfg.WinY = cfg.WinY + step end elseif m == 2 then if Key == 37 then c.RegX = c.RegX - step elseif Key == 39 then c.RegX = c.RegX + step elseif Key == 38 then c.RegY = c.RegY - step elseif Key == 40 then c.RegY = c.RegY + step end end return true end end return false end if _G.GuildZone_Client_Active == nil then BridgeFunctionAttach('MainProcThread', 'GuildZone_Render') BridgeFunctionAttach('UpdateMouseEvent', 'GuildZone_Mouse') BridgeFunctionAttach('KeyboardEvent', 'GuildZone_Keyboard') BridgeFunctionAttach('ScrollMouseEvent', 'GuildZone_ScrollWheel') if ProtocolFunctions ~= nil and ProtocolFunctions.ClientProtocol ~= nil then ProtocolFunctions.ClientProtocol(GuildZone_Protocol) else BridgeFunctionAttach('ClientProtocol', 'GuildZone_Protocol') end _G.GuildZone_Client_Active = true end