-- Loja Cash / zGold (Season 3) - cliente. -- Ocupa a tela toda acima da HUD (640x432 em coordenadas 640x480), montada SO com o kit -- partCharge/SubBackPanel + ShopDisplay (nenhuma backpanel): -- shopback0/1 = borda de cima (0 com o canto ornamentado e a borda esquerda), shopback2 = borda -- esquerda de baixo, shopback3 = pedra; shopback4 = coluna das secoes (x 0..80) e o divisor antes -- do painel (x 152..168); shopback5 = tampa da coluna (y 48..80), linha dupla sob as abas (y 0..48) -- e barra de baixo (y 80..112); shopback6/7 = painel da direita (personagem / inventario) com a -- borda de corrente na direita. Botoes: leftmenubt, topmenutabbt, buy, cash, page, return. -- Abre/fecha pela tecla X (sem NPC). Secoes/itens/precos chegam do SERVIDOR (LC_OpenW). LojaCash = {} -- # layout: coordenadas do KIT (716x512 = 2 tiles de 256 + painel de 204, por 2 tiles de 256), -- com as pecas da moldura em escala 1:1 (elas encaixam umas nas outras). A janela toda e -- esticada para 640x432 (tela acima da HUD) por TX/TY. local W, H = 716, 560 -- 2 tiles de 256 + borda de baixo (512..560) local MW = 512 -- area principal 0..512, painel da direita 512..716 local RX, RW = 512, 204 local LC = 84 -- largura da coluna das secoes (shopback4 tem 2 partes de 84px) local COLS, ROWS = 3, 3 -- cards por pagina = 9 local CARD_W, CARD_H = 114, 93 -- itembackpanel 152x124 * 0.75 local CARD_X = { 96, 226, 356 } local CARD_Y = { 34, 161, 288 } local SEC_X, SEC_Y, SEC_STEP, SEC_MAX = 5, 36, 28, 13 local SEC_W, SEC_H = 70, 24 -- leftmenubt 88x30 * 0.8 local TAB_X = { 100, 176 } -- abas de moeda (topmenutabbt 86x33 -> 69x26) local INV_X, INV_Y, INV_CELL = 538, 270, 19 -- grade 8x8 do inventario (celulas de 19px) local PTS_Y = 437 -- linha de pontos (slot do shopback7, y 432..452) local PTS_X, PTS_DX = 556, 89 -- centro do nome da moeda e deslocamento ate o centro do saldo local TAB_W, TAB_H, TAB_Y = 69, 26, 4 local TIT_X, TIT_Y = 340, 10 local PAG_X, PAG_Y = 262, 478 local HERO = { x = 521, y = 11, w = 176, h = 198 } local NOME_X, NOME_Y = 614, 16 local ATU = { x = 579, y = 220, w = 70, h = 24 } local CCASH = { x = 520, y = 458, w = 58, h = 24 } local FECHAR = { x = 522, y = 486, w = 27, h = 24 } -- # transformacao kit -> tela (escala X e Y separadas). Config: LojaCash_Define.Escala / PosX / PosY local SC, OX, OY = 1, 0, 0 local KX, KY = 640 / 716, 432 / 560 local function TX(x) return OX + x * KX * SC end local function TY(y) return OY + y * KY * SC end local function TSX(v) return v * KX * SC end local function TSY(v) return v * KY * SC end local function Item3D(x, y, w, h, ...) CreateItem(TX(x), TY(y), TSX(w), TSY(h), ...) end local function Hit(x, y, w, h, mx, my) return mx >= TX(x) and mx < TX(x + w) and my >= TY(y) and my < TY(y + h) end -- imagens do kit por nome (para o layout do LojaCashEditor): id Lua e tamanho real local KIT = { itembackpanel = { id = 10600, w = 152, h = 124 }, buy0 = { id = 10601, w = 72, h = 30 }, buy1 = { id = 10602, w = 72, h = 30 }, buy2 = { id = 10603, w = 72, h = 30 }, cash0 = { id = 10604, w = 72, h = 30 }, cash1 = { id = 10605, w = 72, h = 30 }, cash2 = { id = 10606, w = 72, h = 30 }, page0 = { id = 10607, w = 23, h = 23 }, page1 = { id = 10608, w = 23, h = 23 }, page2 = { id = 10609, w = 23, h = 23 }, page3 = { id = 10610, w = 23, h = 23 }, page4 = { id = 10611, w = 23, h = 23 }, page5 = { id = 10612, w = 23, h = 23 }, hot = { id = 10613, w = 39, h = 33 }, new = { id = 10614, w = 39, h = 33 }, sale = { id = 10615, w = 60, h = 47 }, miniinventorypanel = { id = 10616, w = 4, h = 4 }, shopback0 = { id = 10617, w = 256, h = 256 }, shopback1 = { id = 10618, w = 256, h = 256 }, shopback2 = { id = 10619, w = 256, h = 256 }, shopback3 = { id = 10620, w = 256, h = 256 }, shopback4 = { id = 10621, w = 256, h = 256 }, shopback5 = { id = 10622, w = 256, h = 256 }, shopback6 = { id = 10623, w = 256, h = 256 }, shopback7 = { id = 10624, w = 256, h = 256 }, deco0 = { id = 10625, w = 58, h = 70 }, deco1 = { id = 10626, w = 4, h = 4 }, deco2 = { id = 10627, w = 4, h = 4 }, deco3 = { id = 10628, w = 4, h = 4 }, deco4 = { id = 10629, w = 58, h = 125 }, inventorypanel0 = { id = 10630, w = 22, h = 22 }, inventorypanel1 = { id = 10631, w = 22, h = 22 }, leftmenubt0 = { id = 10632, w = 88, h = 30 }, leftmenubt1 = { id = 10633, w = 88, h = 30 }, topmenutabbt0 = { id = 10634, w = 86, h = 33 }, topmenutabbt1 = { id = 10635, w = 86, h = 33 }, return0 = { id = 10636, w = 34, h = 30 }, return1 = { id = 10637, w = 34, h = 30 }, return2 = { id = 10638, w = 34, h = 30 }, } -- # botoes (ids) local BT_CLOSE, BT_PREV, BT_NEXT, BT_REFRESH, BT_BUYPTS = 1, 2, 3, 4, 5 local BT_GIFT_OK, BT_GIFT_CANCEL = 6, 7 local BT_TAB = 10 -- 11, 12 local BT_SEC = 100 -- 101..113 local BT_BUY = 200 -- 201..209 local BT_GIFT = 300 -- 301..309 --#region LAYOUT EXTERNO (Customs/Config/Loja Cash Layout.lua, gerado pelo LojaCashEditor.html) local LayoutAplicado = false local function ApplyLayout() local L = LojaCash_Layout if L == nil or L.Zonas == nil or LayoutAplicado then return end local Z = L.Zonas -- tamanho da janela = extensao das pecas montadas (a tela e esticada para 640x432 a partir dele) local mw, mh = 0, 0 for _, pc in ipairs(L.Pecas or {}) do if pc.x + pc.w > mw then mw = pc.x + pc.w end if pc.y + pc.h > mh then mh = pc.y + pc.h end end -- CUIDADO: mw/mh e a caixa DELIMITADORA das pecas, e varias tem sobra -- TRANSPARENTE (shopback6/7 sao declaradas w=256 mas a arte util tem ~205). -- Usar a caixa faz KX encolher demais e a moldura visivel termina antes da -- borda da tela -- em wide sobra um naco do mundo na direita. LarguraKit / -- AlturaKit dizem qual e a extensao UTIL do kit (nil = usa a caixa). mw = LojaCash_Define.LarguraKit or mw mh = LojaCash_Define.AlturaKit or mh if mw > 0 and mh > 0 then W, H = mw, mh; KX, KY = 640 / W, 432 / H end if Z.Abas then TAB_X = { Z.Abas.x, Z.Abas.x + (Z.Abas.dx or 76) }; TAB_W, TAB_H, TAB_Y = Z.Abas.w or 69, Z.Abas.h or 26, Z.Abas.y end if Z.Titulo then TIT_X, TIT_Y = Z.Titulo.x, Z.Titulo.y end if Z.Secoes then SEC_X, SEC_Y, SEC_STEP, SEC_W, SEC_H = Z.Secoes.x, Z.Secoes.y, Z.Secoes.dy or SEC_STEP, Z.Secoes.w or SEC_W, Z.Secoes.h or SEC_H end if Z.Cards then CARD_W, CARD_H = Z.Cards.w or CARD_W, Z.Cards.h or CARD_H CARD_X = { Z.Cards.x, Z.Cards.x + (Z.Cards.dx or 130), Z.Cards.x + 2 * (Z.Cards.dx or 130) } CARD_Y = { Z.Cards.y, Z.Cards.y + (Z.Cards.dy or 127), Z.Cards.y + 2 * (Z.Cards.dy or 127) } end if Z.Paginacao then PAG_X, PAG_Y = Z.Paginacao.x, Z.Paginacao.y end if Z.Personagem then HERO = { x = Z.Personagem.x, y = Z.Personagem.y, w = Z.Personagem.w, h = Z.Personagem.h } end if Z.Nome then NOME_X, NOME_Y = Z.Nome.x, Z.Nome.y end if Z.Atualizar then ATU = { x = Z.Atualizar.x, y = Z.Atualizar.y, w = Z.Atualizar.w or 70, h = Z.Atualizar.h or 24 } end if Z.Inventario then INV_X, INV_Y, INV_CELL = Z.Inventario.x, Z.Inventario.y, Z.Inventario.cell or INV_CELL end if Z.Pontos then PTS_X, PTS_DX, PTS_Y = Z.Pontos.x, Z.Pontos.dx or 89, Z.Pontos.y end if Z.ComprarCash then CCASH = { x = Z.ComprarCash.x, y = Z.ComprarCash.y, w = Z.ComprarCash.w or 58, h = Z.ComprarCash.h or 24 } end if Z.Fechar then FECHAR = { x = Z.Fechar.x, y = Z.Fechar.y, w = Z.Fechar.w or 27, h = Z.Fechar.h or 24 } end LayoutAplicado = true end -- desenha as pecas do layout externo (moldura inteira), na ordem do editor local function DrawLayoutPieces() for _, pc in ipairs(LojaCash_Layout.Pecas or {}) do local k = KIT[pc.img] if k then local pw, ph = 1, 1 while pw < k.w do pw = pw * 2 end while ph < k.h do ph = ph * 2 end local u, uw = (pc.sx or 0) / pw, (pc.sw or k.w) / pw local v, vh = (pc.sy or 0) / ph, (pc.sh or k.h) / ph if pc.fx then u, uw = ((pc.sx or 0) + (pc.sw or k.w)) / pw, -(pc.sw or k.w) / pw end if pc.fy then v, vh = ((pc.sy or 0) + (pc.sh or k.h)) / ph, -(pc.sh or k.h) / ph end CreateInterface(k.id, TX(pc.x), TY(pc.y), TSX(pc.w), TSY(pc.h), u, v, uw, vh, 1, 1) end end end --#endregion --#region UTIL local function POT(n) local p = 1 while p < n do p = p * 2 end return p end -- desenha a regiao (sx, sy, sw, sh) em pixels de uma imagem de tamanho real tw x th -- (textura e POT, conteudo no canto superior esquerdo) no retangulo x, y, w, h. -- flip = espelha na horizontal, flipy = espelha na vertical. local function Pic(id, x, y, w, h, tw, th, sx, sy, sw, sh, flip, flipy) sx = sx or 0 sy = sy or 0 sw = sw or tw sh = sh or th local pw, ph = POT(tw), POT(th) local u, uw = sx / pw, sw / pw local v, vh = sy / ph, sh / ph if flip then u, uw = (sx + sw) / pw, -sw / pw end if flipy then v, vh = (sy + sh) / ph, -sh / ph end CreateInterface(id, TX(x), TY(y), TSX(w), TSY(h), u, v, uw, vh, 1, 1) end local function Txt(x, y, text, r, g, b, bold, a) SetFont(bold and 1 or 0) SetTextBackColor(0, 0, 0, 0) SetTextColor(r, g, b, a or 255) SetText(math.floor(TX(x)), math.floor(TY(y)), text or "") SetFont(0) end local function TxtC(cx, y, text, r, g, b, bold, a) SetFont(bold and 1 or 0) SetTextBackColor(0, 0, 0, 0) SetTextColor(r, g, b, a or 255) SetText2(math.floor(TX(cx)), math.floor(TY(y)), text or "") SetFont(0) end -- fator de FPS (REFERENCE_FPS / FPS) - 1 se o exe nao tiver a native local function Fps() return (GetFpsFactor and GetFpsFactor()) or 1 end local function T() return LojaCash_Define.Texts[getLanguage()] or LojaCash_Define.Texts["Eng"] end --#endregion --#region REGISTRO / ESTADO function LojaCash.Init() if LojaCash_Define.Ativado then InterfaceController.MainProcInterface(LojaCash.Interface) InterfaceController.InterfaceClickEvent(LojaCash.ClickEvent) InterfaceController.MainProcWorldKey(LojaCash.KeyListener) InterfaceController.ScrollMouse(LojaCash.Scroll) InterfaceController.ClientProtocol(LojaCash.Protocol) LojaCash.Define() LojaCash_Define.Saldo = { [1] = 0, [2] = 0 } LojaCash_Define.Secoes = {} LojaCash_Define.Angle = 0 end end function LojaCash.Define() LojaCash_Define.Buttons = {} LojaCash_Define.Secao = 1 LojaCash_Define.Moeda = 1 -- aba do topo: 1 = Cash, 2 = zGold LojaCash_Define.Pagina = 1 LojaCash_Define.Press = {} -- [idBotao] = frames restantes do estado "pressionado" LojaCash_Define.Locked = false LojaCash_Define.Gift = nil -- { item = , nome = "" } quando a caixa de presente esta aberta LojaCash_Define.Aberta = false end function LojaCash.SecaoAtual() return LojaCash_Define.Secoes[LojaCash_Define.Secao] end -- itens da secao atual filtrados pela aba de moeda function LojaCash.ItensVisiveis() local sec = LojaCash.SecaoAtual() local lista = {} if sec == nil then return lista end for i in ipairs(sec.Itens) do if sec.Itens[i].Moeda == LojaCash_Define.Moeda then table.insert(lista, sec.Itens[i]) end end return lista end function LojaCash.TotalPaginas(lista) if #lista == 0 then return 1 end return math.ceil(#lista / (COLS * ROWS)) end function LojaCash.NomeItem(item) local nome = GetNameByIndex(item.Index) if nome == nil or nome == "" then nome = "Item " .. tostring(item.Index) end if (item.Level or 0) > 0 then nome = nome .. " +" .. math.floor(item.Level) end return nome end function LojaCash.Pressionar(id) LojaCash_Define.Press[id] = 4 / Fps() -- ~4 frames a 25 FPS, independente do FPS end -- estado de um botao de 3 imagens: 1 normal, 2 hover, 3 pressionado function LojaCash.Estado(id, mx, my) local p = LojaCash_Define.Press[id] if p and p > 0 then LojaCash_Define.Press[id] = p - 1 return 3 end if LojaCash.CheckButton(id, mx, my) then return 2 end return 1 end -- mouse dentro da janela? function LojaCash.MouseDentro(mx, my) return Hit(0, 0, W, H, mx, my) end --#endregion --#region ABRE / FECHA function LojaCash.Open() CreatePacket("LC_Open", LojaCash_Define.Packet) SendPacket("LC_Open") ClearPacket("LC_Open") end function LojaCash.OpenWindow() if not LojaCash_Define.Aberta then LojaCash.Define() LojaCash_Define.Aberta = true CloseAllWindowsExcept(-1) UICustomInterface = LojaCash_Define.WindowID end -- secao/pagina podem ter ficado fora da lista nova if LojaCash_Define.Secao > #LojaCash_Define.Secoes then LojaCash_Define.Secao = 1 end local total = LojaCash.TotalPaginas(LojaCash.ItensVisiveis()) if LojaCash_Define.Pagina > total then LojaCash_Define.Pagina = total end end function LojaCash.Close() UICustomInterface = 0 SetKeyCapture(0) SetUnlockInterfaces() LojaCash.Define() end --#endregion --#region BOTOES function LojaCash.CreateButton(id, X, Y, Wd, Ht) LojaCash_Define.Buttons[id] = {X1 = TX(X), X2 = TX(X + Wd), Y1 = TY(Y), Y2 = TY(Y + Ht)} end function LojaCash.CheckButton(id, X, Y) local b = LojaCash_Define.Buttons[id] if b == nil then return false end return X >= b.X1 and X <= b.X2 and Y >= b.Y1 and Y <= b.Y2 end -- botao com imagens de 3 estados (tw x th reais) desenhado em x, y, w, h local function Button3(id, imgs, x, y, w, h, tw, th, label, mx, my, r, g, b) LojaCash.CreateButton(id, x, y, w, h) local estado = LojaCash.Estado(id, mx, my) Pic(imgs[estado] or imgs[1], x, y, w, h, tw, th) if label then TxtC(x + w / 2, y + (h - 8) / 2, label, r or 230, g or 230, b or 230, true) end end --#endregion --#region DESENHO: MOLDURA E AREA PRINCIPAL (shopback0..5, tudo 1:1 no espaco do kit) local function DrawMainFrame(IMG) -- mosaico: shopback0 (canto ornamentado + borda de cima/esquerda), shopback1 (borda de cima), -- shopback2 (borda esquerda + canto de baixo), shopback3 (pedra) Pic(IMG.Back[1], 0, 0, 256, 256, 256, 256) Pic(IMG.Back[2], 256, 0, 256, 256, 256, 256) Pic(IMG.Back[3], 0, 256, 256, 256, 256, 256) Pic(IMG.Back[4], 256, 256, 256, 256, 256, 256) -- coluna das secoes = shopback4 ESPELHADA: parte 1 (x 0..84) em cima e parte 2 (x 84..168) embaixo; -- espelhada, a linha fica na borda esquerda da tela e o ornamento do topo encosta no canto Pic(IMG.Side, 0, 0, LC, 256, 256, 256, 0, 0, 84, 256, true) Pic(IMG.Side, 0, 256, LC, 256, 256, 256, 84, 0, 84, 256, true) -- pedra abaixo dos tiles ate a borda de baixo Pic(IMG.Back[3], 0, 512, 256, 48, 256, 256, 0, 200, 256, 48) Pic(IMG.Back[4], 256, 512, 256, 48, 256, 256, 0, 200, 256, 48) Pic(IMG.Back[4], 512, 512, 204, 48, 256, 256, 0, 200, 204, 48) end -- borda de baixo = as 4 sub-imagens da shopback5 (28px de altura cada: y 0..28, 28..56, 56..84, -- 84..112) lado a lado, de cima para baixo na imagem = da esquerda para a direita na tela: -- 256 + 256 + 80 + 200 = 792 -> reduzido para 716 (x 0.904), alinhadas embaixo (y 532..560) local function DrawBottomBar(IMG) local k = 716 / 792 Pic(IMG.Bars, 0, 532, 256 * k, 28, 256, 256, 0, 0, 256, 28) Pic(IMG.Bars, 256 * k, 532, 256 * k, 28, 256, 256, 0, 28, 256, 28) Pic(IMG.Bars, 512 * k, 532, 80 * k, 28, 256, 256, 0, 56, 80, 28) Pic(IMG.Bars, 592 * k, 532, 200 * k, 28, 256, 256, 0, 84, 200, 28) end local function DrawTabs(IMG, mx, my, Tx) for m = 1, 2 do local ativa = (LojaCash_Define.Moeda == m) LojaCash.CreateButton(BT_TAB + m, TAB_X[m], TAB_Y, TAB_W, TAB_H - 4) Pic(IMG.Tab[ativa and 2 or 1], TAB_X[m], TAB_Y, TAB_W, TAB_H, 86, 33) local nome = LojaCash_Define.Moedas[m] or tostring(m) if ativa then TxtC(TAB_X[m] + TAB_W / 2, TAB_Y + 5, nome, 255, 215, 100, true) else TxtC(TAB_X[m] + TAB_W / 2, TAB_Y + 5, nome, 200, 200, 200, false) end end TxtC(TIT_X, TIT_Y, Tx.Title, 255, 208, 0, true) end local function DrawSections(IMG, mx, my) local n = math.min(#LojaCash_Define.Secoes, SEC_MAX) for s = 1, n do local y = SEC_Y + (s - 1) * SEC_STEP local ativa = (s == LojaCash_Define.Secao) LojaCash.CreateButton(BT_SEC + s, SEC_X, y, SEC_W, SEC_H) local img = IMG.Menu[1] if ativa or LojaCash.CheckButton(BT_SEC + s, mx, my) then img = IMG.Menu[2] end Pic(img, SEC_X, y, SEC_W, SEC_H, 88, 30) if ativa then TxtC(SEC_X + SEC_W / 2, y + 7, LojaCash_Define.Secoes[s].Nome, 255, 215, 100, true) else TxtC(SEC_X + SEC_W / 2, y + 7, LojaCash_Define.Secoes[s].Nome, 220, 220, 220, false) end end for s = n + 1, SEC_MAX do LojaCash_Define.Buttons[BT_SEC + s] = nil end end local function DrawCards(IMG, mx, my, Tx, lista) local base = (LojaCash_Define.Pagina - 1) * (COLS * ROWS) if #lista == 0 then TxtC(300, 230, Tx.Empty, 200, 200, 200, false) end for slot = 1, COLS * ROWS do local item = lista[base + slot] if item then local col = ((slot - 1) % COLS) + 1 local row = math.floor((slot - 1) / COLS) + 1 local cx, cy = CARD_X[col], CARD_Y[row] Pic(IMG.Panel, cx, cy, CARD_W, CARD_H, 152, 124) -- nome (faixa de cima, cortado se nao couber) e preco (faixa de baixo) local nome = LojaCash.NomeItem(item) local maxc = math.floor(CARD_W / 3) if #nome > maxc then nome = string.sub(nome, 1, maxc - 1) .. "." end TxtC(cx + CARD_W / 2, cy + 5, nome, 255, 208, 0, false) TxtC(cx + CARD_W / 2, cy + 76, string.format(Tx.Price, FormatZen(item.Preco), LojaCash_Define.Moedas[item.Moeda] or "?"), 255, 255, 255, false) -- item 3D em caixa PADRAO (mesmo tamanho e mesma posicao para todos os itens) local bw = LojaCash_Define.TamanhoItem or 34 local bh = bw local IC = LojaCash_Define.ItemCard or {} if SetItemFill then SetItemFill(IC.Preenchimento or 0.82) end Item3D(cx + CARD_W / 2 - bw / 2 + (IC.DeslocaX or 0), cy + (LojaCash_Define.AlturaItem or 47) - bh / 2 + (IC.DeslocaY or 0), bw, bh, item.Index, math.floor(item.Level or 0) * 8 + (item.Skill or 0) * 128 + (item.Luck or 0) * 4, item.Option, item.Exc) -- byte cru do level, como o inventario nativo (RenderItem3D usa Level>>3) if Hit(cx, cy + 12, CARD_W, 62, mx, my) then LojaCash_Define.HoverCard = { item = item, cx = cx + CARD_W / 2, cy = cy + 30 } end -- selo if item.Tag == 3 then Pic(IMG.Tag[3], cx + CARD_W - 46, cy - 4, 45, 35, 60, 47) elseif item.Tag == 1 or item.Tag == 2 then Pic(IMG.Tag[item.Tag], cx + 4, cy + 16, 29, 25, 39, 33) end -- comprar / presente Button3(BT_BUY + slot, IMG.Buy, cx + 1, cy + CARD_H + 4, 54, 22, 72, 30, Tx.Buy, mx, my) Button3(BT_GIFT + slot, IMG.Buy, cx + 59, cy + CARD_H + 4, 54, 22, 72, 30, Tx.Gift, mx, my) else LojaCash_Define.Buttons[BT_BUY + slot] = nil LojaCash_Define.Buttons[BT_GIFT + slot] = nil end end end local function DrawPages(IMG, mx, my, Tx, total) LojaCash.CreateButton(BT_PREV, PAG_X, PAG_Y, 18, 18) LojaCash.CreateButton(BT_NEXT, PAG_X + 56, PAG_Y, 18, 18) Pic(IMG.Prev[LojaCash.Estado(BT_PREV, mx, my)], PAG_X, PAG_Y, 18, 18, 23, 23) Pic(IMG.Next[LojaCash.Estado(BT_NEXT, mx, my)], PAG_X + 56, PAG_Y, 18, 18, 23, 23) Pic(IMG.Deco[2], PAG_X + 20, PAG_Y + 1, 34, 16, 4, 4) -- fundo escuro do numero TxtC(PAG_X + 37, PAG_Y + 4, string.format(Tx.Page, LojaCash_Define.Pagina, total), 255, 255, 255, false) end --#endregion --#region DESENHO: PAINEL DA DIREITA (shopback6/7, inventorypanel, cash*, return*) local function DrawRightColumn(IMG, mx, my, Tx) -- shopback6 (personagem) em cima e shopback7 (inventario / pontos) embaixo, 1:1, um completa o outro if LojaCash_Layout == nil then Pic(IMG.CharPanel, RX, 0, RW, 256, 204, 256) Pic(IMG.InvPanel, RX, 256, RW, 256, 204, 256) end -- personagem 3D dentro da moldura (cols 8..186, rows 10..210 do kit) local P = LojaCash_Define.Personagem or {} -- parado; gira so enquanto o mouse esta sobre ele if Hit(HERO.x, HERO.y, HERO.w, HERO.h, mx, my) then LojaCash_Define.Angle = (LojaCash_Define.Angle + (P.Giro or 0) * Fps()) % 360 end RenderHero(TX(HERO.x), TY(HERO.y), TSX(HERO.w), TSY(HERO.h), (P.Angulo or 0) + LojaCash_Define.Angle, P.Distancia or 1600, P.Fov or 7, P.Altura or -70, P.Escala or 1, P.Pose or 1) TxtC(NOME_X, NOME_Y, GetHeroName(), 255, 255, 255, true) -- atualizar (reenvia LC_Open: saldos e lista) LojaCash.CreateButton(BT_REFRESH, ATU.x, ATU.y, ATU.w, ATU.h) Pic(LojaCash.CheckButton(BT_REFRESH, mx, my) and IMG.Menu[2] or IMG.Menu[1], ATU.x, ATU.y, ATU.w, ATU.h, 88, 30) TxtC(ATU.x + ATU.w / 2, ATU.y + (ATU.h - 10) / 2, Tx.Refresh, 220, 220, 220, false) -- grade 8x8 do inventario (celulas de 19px) for r = 0, 7 do for c = 0, 7 do Pic(IMG.Cell[1], INV_X + c * INV_CELL, INV_Y + r * INV_CELL, INV_CELL, INV_CELL, 22, 22) end end local n = GetInventoryNumItems() local hover = nil for i = 0, n - 1 do local tipo, level, op1, ext, x, y, w, h, dur = GetInventoryItemAt(i) if tipo then local ix, iy, iw, ih = INV_X + x * INV_CELL, INV_Y + y * INV_CELL, w * INV_CELL, h * INV_CELL local sobre = Hit(ix, iy, iw, ih, mx, my) for rr = 0, h - 1 do for cc = 0, w - 1 do Pic(IMG.Cell[2], ix + cc * INV_CELL, iy + rr * INV_CELL, INV_CELL, INV_CELL, 22, 22) end end if sobre then Pic(IMG.Mini, ix, iy, iw, ih, 4, 4) hover = { inv = i, tipo = tipo, level = level, cx = ix + iw / 2, cy = (h == 1) and (iy + ih / 2) or iy } end local II = LojaCash_Define.ItemInventario or {} if SetItemFill then SetItemFill(II.Preenchimento or 0.9) end Item3D(ix + (II.DeslocaX or 0), iy + (II.DeslocaY or 0), iw, ih, tipo, level, op1, ext) -- quantidade (pocoes, flechas, joias em pacote...), igual ao inventario nativo if DrawItemNumber then DrawItemNumber(TX(ix + (II.DeslocaX or 0)), TY(iy + (II.DeslocaY or 0)), TSX(iw), TSY(ih), tipo, level, dur or 0) end end end -- pontos da moeda da aba selecionada (Cash ou zGold): nome no slot da esquerda, saldo no da direita local moeda = LojaCash_Define.Moeda TxtC(PTS_X, PTS_Y, LojaCash_Define.Moedas[moeda] or "?", 255, 208, 0, true) TxtC(PTS_X + PTS_DX, PTS_Y, FormatZen(LojaCash_Define.Saldo[moeda] or 0), 255, 255, 255, false) -- separadores escuros (tiles deco) personagem / inventario / pontos if LojaCash_Layout == nil then Pic(IMG.Deco[3], RX + 12, 250, RW - 24, 1, 4, 4) Pic(IMG.Deco[4], RX + 12, 426, RW - 24, 1, 4, 4) end return hover end -- comprar cash + fechar: desenhados DEPOIS da barra de baixo (o X fica sobre ela, como no original) local function DrawRightButtons(IMG, mx, my, Tx) Button3(BT_BUYPTS, IMG.Cash, CCASH.x, CCASH.y, CCASH.w, CCASH.h, 72, 30, Tx.BuyPoints, mx, my, 255, 215, 100) LojaCash.CreateButton(BT_CLOSE, FECHAR.x, FECHAR.y, FECHAR.w, FECHAR.h) Pic(IMG.Close[LojaCash.Estado(BT_CLOSE, mx, my)], FECHAR.x, FECHAR.y, FECHAR.w, FECHAR.h, 34, 30) if LojaCash.CheckButton(BT_CLOSE, mx, my) then Txt(FECHAR.x + FECHAR.w + 6, FECHAR.y + 6, Tx.Close, 255, 255, 255, false) end end --#endregion --#region DESENHO: CAIXA DE PRESENTE local function DrawGiftBox(mx, my, Tx) local g = LojaCash_Define.Gift if g == nil then return end local bx, by = 246, 170 Pic(IMG_PANEL, bx, by, 224, 112, 213, 64) TxtC(bx + 112, by + 10, string.format(Tx.GiftTitle, LojaCash.NomeItem(g.item)), 255, 208, 0, true) Pic(IMG_EDITBOX, bx + 56, by + 32, 113, 18, 113, 18) Txt(bx + 61, by + 36, g.nome .. "_", 255, 255, 255, false) TxtC(bx + 112, by + 56, Tx.GiftHint, 200, 200, 200, false) LojaCash.CreateButton(BT_GIFT_OK, bx + 78, by + 78, 24, 24) LojaCash.CreateButton(BT_GIFT_CANCEL, bx + 122, by + 78, 24, 24) Pic(LojaCash.CheckButton(BT_GIFT_OK, mx, my) and IMG_OK_DOWN or IMG_OK, bx + 78, by + 78, 24, 24, 24, 24) Pic(LojaCash.CheckButton(BT_GIFT_CANCEL, mx, my) and IMG_EXIT_DOWN or IMG_EXIT, bx + 122, by + 78, 24, 24, 24, 24) end --#endregion --#region INTERFACE function LojaCash.Interface() if UICustomInterface ~= LojaCash_Define.WindowID then if LojaCash_Define.Locked then SetUnlockInterfaces() LojaCash_Define.Locked = false end return end local Tx = T() local IMG = LojaCash_Define.Images local mx, my = MousePosX(), MousePosY() -- escala / posicao da janela (padrao: tela toda acima da HUD) SC = LojaCash_Define.Escala or 1 OX = LojaCash_Define.PosX or (640 - W * KX * SC) / 2 OY = LojaCash_Define.PosY or (480 - H * KY * SC) / 2 EnableAlphaTest() if LojaCash.MouseDentro(mx, my) or LojaCash_Define.Gift then SetLockInterfaces() LojaCash_Define.Locked = true elseif LojaCash_Define.Locked then SetUnlockInterfaces() LojaCash_Define.Locked = false end if LojaCash_Layout then ApplyLayout() DrawLayoutPieces() else DrawMainFrame(IMG) end DrawTabs(IMG, mx, my, Tx) DrawSections(IMG, mx, my) local lista = LojaCash.ItensVisiveis() local total = LojaCash.TotalPaginas(lista) if LojaCash_Define.Pagina > total then LojaCash_Define.Pagina = total end LojaCash_Define.HoverCard = nil DrawCards(IMG, mx, my, Tx, lista) local hover = DrawRightColumn(IMG, mx, my, Tx) if LojaCash_Layout == nil then DrawBottomBar(IMG) end DrawRightButtons(IMG, mx, my, Tx) DrawPages(IMG, mx, my, Tx, total) -- tooltips por ultimo (por cima de tudo), iguais aos do inventario nativo if LojaCash_Define.Gift then DrawGiftBox(mx, my, Tx) elseif hover then if DrawInventoryTooltip then DrawInventoryTooltip(hover.inv, math.floor(TX(hover.cx)), math.floor(TY(hover.cy))) else ShowItemDescription(mx, my, hover.tipo, hover.level) end elseif LojaCash_Define.HoverCard then local hc = LojaCash_Define.HoverCard if DrawItemTooltip then DrawItemTooltip(math.floor(TX(hc.cx)), math.floor(TY(hc.cy)), hc.item.Index, math.floor(hc.item.Level or 0) * 8 + (hc.item.Skill or 0) * 128 + (hc.item.Luck or 0) * 4, hc.item.Dur or 0, hc.item.Option or 0, hc.item.Exc or 0) else ShowItemDescription(mx, my, hc.item.Index, hc.item.Level) end end DisableAlphaBlend() end --#endregion --#region TECLADO / MOUSE -- caixa de texto do presente: o teclado esta capturado (SetKeyCapture), entao as -- teclas chegam so por aqui (WM_KEYDOWN); Shift = maiuscula local function GiftKey(key) local g = LojaCash_Define.Gift if key == Keys.Escape then LojaCash.GiftCancel() return true end if key == Keys.Return then LojaCash.GiftSend() return true end if key == Keys.Back then g.nome = string.sub(g.nome, 1, -2) return true end if #g.nome >= 10 then return true end local ch = nil if key >= Keys.A and key <= Keys.Z then ch = string.char(key) if IsKeyDown(Keys.ShiftKey) == 0 then ch = string.lower(ch) end elseif key >= Keys.D0 and key <= Keys.D9 then ch = string.char(key) elseif key >= 96 and key <= 105 then -- numpad 0..9 ch = string.char(key - 48) end if ch then g.nome = g.nome .. ch end return true end function LojaCash.KeyListener(key) if UICustomInterface == LojaCash_Define.WindowID and LojaCash_Define.Gift then return GiftKey(key) end if key == LojaCash_Define.Shortcut and GetChatPlayerOpen() ~= 1 and CheckWindowOpen(UIStore) == 0 then if UICustomInterface == 0 then LojaCash.Open() return true elseif UICustomInterface == LojaCash_Define.WindowID then LojaCash.Close() return true end end if key == Keys.Escape and UICustomInterface == LojaCash_Define.WindowID then LojaCash.Close() return true end end function LojaCash.ClickEvent() if UICustomInterface ~= LojaCash_Define.WindowID then return end local x, y = MousePosX(), MousePosY() local Tx = T() -- caixa de presente aberta: so ela recebe cliques if LojaCash_Define.Gift then if LojaCash.CheckButton(BT_GIFT_OK, x, y) then LojaCash.GiftSend() end if LojaCash.CheckButton(BT_GIFT_CANCEL, x, y) then LojaCash.GiftCancel() end return true end if LojaCash.CheckButton(BT_CLOSE, x, y) then LojaCash.Pressionar(BT_CLOSE) LojaCash.Close() return true end if LojaCash.CheckButton(BT_PREV, x, y) then LojaCash.Pressionar(BT_PREV) LojaCash.MudarPagina(-1) return true end if LojaCash.CheckButton(BT_NEXT, x, y) then LojaCash.Pressionar(BT_NEXT) LojaCash.MudarPagina(1) return true end if LojaCash.CheckButton(BT_REFRESH, x, y) then LojaCash.Open() return true end if LojaCash.CheckButton(BT_BUYPTS, x, y) then LojaCash.Pressionar(BT_BUYPTS) SendMessageClient(Tx.BuyPointsMsg) return true end for m = 1, 2 do if LojaCash.CheckButton(BT_TAB + m, x, y) then LojaCash_Define.Moeda = m LojaCash_Define.Pagina = 1 return true end end for s = 1, math.min(#LojaCash_Define.Secoes, SEC_MAX) do if LojaCash.CheckButton(BT_SEC + s, x, y) then LojaCash_Define.Secao = s LojaCash_Define.Pagina = 1 return true end end local lista = LojaCash.ItensVisiveis() local base = (LojaCash_Define.Pagina - 1) * (COLS * ROWS) for slot = 1, COLS * ROWS do local item = lista[base + slot] if item and LojaCash.CheckButton(BT_BUY + slot, x, y) then LojaCash.Pressionar(BT_BUY + slot) LojaCash.Comprar(item) return true end if item and LojaCash.CheckButton(BT_GIFT + slot, x, y) then LojaCash.Pressionar(BT_GIFT + slot) LojaCash_Define.Gift = { item = item, nome = "" } SetKeyCapture(1) return true end end -- clique dentro da janela nao passa para o mundo if LojaCash.MouseDentro(x, y) then return true end end function LojaCash.MudarPagina(dir) local total = LojaCash.TotalPaginas(LojaCash.ItensVisiveis()) local p = LojaCash_Define.Pagina + dir if p >= 1 and p <= total then LojaCash_Define.Pagina = p end end function LojaCash.Scroll(Direction) if UICustomInterface ~= LojaCash_Define.WindowID then return end if LojaCash_Define.Gift then return true end if Hit(0, 0, MW, H, MousePosX(), MousePosY()) then LojaCash.MudarPagina(Direction > 0 and -1 or 1) return true end end --#endregion --#region PACOTES function LojaCash.Comprar(item) CreatePacket("LC_Comprar", LojaCash_Define.Packet) SetBytePacket("LC_Comprar", LojaCash_Define.Secao) SetWordPacket("LC_Comprar", item.ListID) SendPacket("LC_Comprar") ClearPacket("LC_Comprar") end function LojaCash.GiftCancel() LojaCash_Define.Gift = nil SetKeyCapture(0) end function LojaCash.GiftSend() local g = LojaCash_Define.Gift if g == nil then return end if #g.nome == 0 then SendMessageClient(T().GiftEmpty) return end CreatePacket("LC_Presente", LojaCash_Define.Packet) SetBytePacket("LC_Presente", LojaCash_Define.Secao) SetWordPacket("LC_Presente", g.item.ListID) SetBytePacket("LC_Presente", #g.nome) SetCharPacketLength("LC_Presente", g.nome, #g.nome) SendPacket("LC_Presente") ClearPacket("LC_Presente") LojaCash.GiftCancel() end function LojaCash.Protocol(Packet, PacketName) if Packet ~= LojaCash_Define.Packet then return false end if PacketName == "LC_OpenW" then LojaCash_Define.Saldo[1] = GetDwordPacket(PacketName, -1) LojaCash_Define.Saldo[2] = GetDwordPacket(PacketName, -1) LojaCash_Define.Secoes = {} local nSec = GetBytePacket(PacketName, -1) for s = 1, nSec do local len = GetBytePacket(PacketName, -1) local nome = GetCharPacketLength(PacketName, -1, len) local nItens = GetBytePacket(PacketName, -1) local sec = { Nome = nome, Itens = {} } for i = 1, nItens do local it = {} it.ListID = GetWordPacket(PacketName, -1) it.Index = GetWordPacket(PacketName, -1) it.Level = GetBytePacket(PacketName, -1) it.Dur = GetBytePacket(PacketName, -1) it.Skill = GetBytePacket(PacketName, -1) it.Luck = GetBytePacket(PacketName, -1) it.Option = GetBytePacket(PacketName, -1) it.Exc = GetBytePacket(PacketName, -1) it.Moeda = GetBytePacket(PacketName, -1) it.Tag = GetBytePacket(PacketName, -1) it.Preco = GetDwordPacket(PacketName, -1) table.insert(sec.Itens, it) end table.insert(LojaCash_Define.Secoes, sec) end ClearPacket(PacketName) LojaCash.OpenWindow() return true end if PacketName == "LC_Saldo" then local moeda = GetBytePacket(PacketName, -1) local valor = GetDwordPacket(PacketName, -1) ClearPacket(PacketName) if moeda == 1 or moeda == 2 then LojaCash_Define.Saldo[moeda] = valor end return true end return false end --#endregion LojaCash.Init() return LojaCash