Ir para conteúdo

paulo thush

Membro
  • Registro em

  • Última visita

Histórico de Curtidas

  1. Gostei
    ATENÇÃO, DESENVOLVEDORES DE OTSERV! 
    Uma nova era está chegando — e você vai fazer parte dela desde o começo! 
     Ferramentas de IA + Formação Completa
    Estamos finalizando ferramentas exclusivas de inteligência artificial que vão revolucionar a forma como você cria e gerencia servidores de Tibia.
    E pra abrir com estilo, chegou a primeira etapa da nossa formação completa:
     Curso de Pixel Art para Tibia e Derivados


    Instrutor: Brendon Nogard, fundador da Pixel Art School
    Uma das maiores referências em arte para servidores de tibia no Brasil!
     Quem é o Nogard? @Nogard
    video-de-apresent.mp4
     
    Criador das primeiras remakes gráficas da PXG
    Mais de 10 anos de experiência com Pixel Art
    Conduziu a evolução da perspectiva GBA para um visual moderno e imersivo
    Influenciou uma geração inteira de criadores na comunidade OTServer no Brasil.
     O que você vai aprender nesse curso?
    Compre Aqui!
     Perspectiva 45° para Tibia e derivados
     Criação de itens: pokébolas, loots, mochilas, poções
     Personagens animados com variações de cabelo
     Criaturas como Wolf, Werewolf, Snake, Horse e Centauro
     Cenários: paredes, cortinas, troféus
     Texturas: folhas, rochas
     Fundamentos de estilo, coerência e construção de sprites profissionais
      Duração: 12 horas
      VALOR : R$250,00
     BÔNUS POR R$50,00
    Também está disponível o Curso de Pixel Art Top Down, ideal pra quem quer começar do zero absoluto:
    Crie personagens, inimigos, chefes
    Monte todo o ambiente do seu jogo
       Duração: 3 horas
     Por que isso é importante pra você?
    Esse é o primeiro passo pra criar um OTServer com:
     Identidade visual única
     Alto nível gráfico
     Suporte de ferramentas de IA exclusivas
     E um método claro, testado e acessível!
     Nas próximas 4 semanas...
    Vamos liberar novos cursos sobre:
     Criação de mapas
     Desenvolvimento de sistemas e scripts
     IA aplicada ao design de jogo (desenvolvimento)
     Balanceamento, mecânicas e muito mais!
     Garanta sua vaga agora!
    Comece hoje mesmo com o pé direito.
    Compre Aqui!
  2. Gostei
    paulo thush recebeu reputação de L3K0T em OTClient Personal   
    Rapaz não sou muito de comentar, mas porra que iniciativa perfeita amei...
     

     
  3. Curtir
    paulo thush deu reputação a L3K0T em OTClient Personal   
    aceita sim, precisa ativar... porem se n souber, aguarde a atualização 5.1

    você pode tentar indo em modulos/game_things/ abra o game_things.lua e ache: 
     
    function load(version)     local errorMessage = ' abaixo adicione
    g_game.enableFeature(GameSpritesAlphaChannel) compile seu cliente no object builder no modo transparência e pronto vai funcionar.
  4. Obrigado
    paulo thush deu reputação a L3K0T em OTClient Personal   
    OTCLIENT PERSONAL
     
     
    O OTClient Personal é uma fusão exclusiva dos recursos do OTClient MeHah, OTClient V8 e OTClient Edubard. Com uma interface totalmente alterada e personalizada, esta versão proporciona uma experiência de jogo singular e adaptável. Além disso, o OTClient Personal recebe atualizações constantes através do GitHub https://github.com/l3k0t/OTClient_Personal, assegurando que os administradores de servidores OTS estejam sempre atualizados com as últimas melhorias e correções na interface e no código-fonte.
     

     

     

     
    Cores nos nomes, isso é só o começo:

     
    Download: https://github.com/l3k0t/OTClient_Personal
     
    Queremos ouvir você! Sua voz é fundamental para tornar nossa comunidade ainda mais vibrante e dinâmica. Convidamos você a contribuir compartilhando suas ideias, sugestões e feedback. Juntos, podemos criar algo verdadeiramente especial. Não hesite em participar e fazer parte desta jornada conosco!
     
    RELEASES DOWNLOADS:
     
    11/05/2024 - Download OTClient 5.1 https://github.com/l3k0t/OTClient_Personal/releases/tag/otclient_5.1
    10/05/2024 - Download OTClient 5.0 https://github.com/l3k0t/OTClient_Personal/releases/tag/otclient_5.0
  5. Gostei
    Credits
    @slaw
    I just edited the tibiacom template.
    Full customizable.
    I have an organized repo for this 'My-AAC last version', I will release I just need to fix something's

    Just check the template live version.

    How Install
    Rename your tibiacom folder and paste the downloaded one.

    Picture News - Boosted Boss works well in this picture the boosted boss of the day was not in image folder.


    DOWNLOAD:
    thetibiaking/ttk-my-aac at layout-changes (github.com)
  6. Gostei
    @doukxxt
     
    Desculpa pela demora. Os últimos dias foram corridos. Decidi compartilhar isso com vocês
     
    Abra o diretório otc/data/layouts/retro/styles/40-inventory.otui e procure por essa linha.
     
    Panel id: conditionPanel layout: type: horizontalBox height: 22 padding: 2 anchors.top: slot8.bottom anchors.left: slot6.left anchors.right: slot5.right margin-top: 4 border-width: 1 border-color: #00000077 background-color: #ffffff22 Adicione abaixo disso.
    StoreButton size: 0 20 anchors.top: prev.bottom anchors.left: parent.left anchors.right: parent.right margin-left: 6 margin-top: 4 margin-right: 6 @onClick: modules.store_module.toggle() Agora, sobre como comprar itens por pontos, vou postar dois tutoriais para Gesior e Znote.
     
    APENAS GESIOR..
    Este script serve para trocar itens por pontos. Vou dar um exemplo com a Magic Sword.
     
    data/scripts.
    local StoreCustom = TalkAction("!shopMagic Sword") function StoreCustom.onSay(player, words, param) local pointsToDeduct = 10 removePoints(player, pointsToDeduct) local newItemID = 2401 -- Replace with the ID of the item the player will receive local newItemCount = 1 -- Quantity of the new item to be added to the player's inventory player:addItem(newItemID, newItemCount) player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have successfully purchased a new item in exchange for" .. pointsToDeduct .. " premium points.") return false end function removePoints(player, amount) local accountId = player:getAccountId() local query = "UPDATE `accounts` SET `premium_points` = `premium_points` - " .. amount .. " WHERE `id` = " .. accountId db.query(query) end StoreCustom:separator(" ") StoreCustom:register() Para saber quantos pontos você tem, digite !points.
    local talkaction = TalkAction("!points") function Player.getPremiumPoints(self) local query = db.storeQuery("SELECT `premium_points` FROM `accounts` WHERE `id` = " .. self:getAccountId()) if not query then return false end local value = result.getNumber(query, "premium_points") result.free(query) return value end function talkaction.onSay(player, words, param, type) if words:lower() == "!points" then local points = player:getPremiumPoints() if points > 0 then local message = "Your premium points balance is: " .. points player:popupFYI(message) else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You don't have premium points.") end return false end return true end talkaction:separator(" ") talkaction:register() Para comprar outfits ou addons.
    local outfitsCustom = TalkAction("!shopMage", "!shopCitizen", "!shopHunter", "!shopKnight", "!shopNoblewoman", "!shopNobleman", "!shopSummoner", "!shopWarrior", "!shopBarbarian", "!shopDruid", "!shopWizard", "!shopOriental", "!shopPirate", "!shopAssassin", "!shopBeggar", "!shopShaman", "!shopNorsewoman", "!shopNorseman", "!shopNightmare", "!shopJester", "!shopBrotherhood", "!shopDemon Hunter", "!shopYalaharian", "!shopNewly Wed", "!shopWarmaster", "!shopWayfarer", "!shopRetro Warrior", "!shopRetro Citizen", "!shopRetro Hunter", "!shopRetro Knight", "!shopRetro Mage", "!shopRetro Noblewoman", "!shopRetro Nobleman", "!shopRetro Summoner") function outfitsCustom.onSay(player, words, param) if words == "/shop" then return false end if words == "!shopMage" then local outfitId = (player:getSex() == PLAYERSEX_FEMALE) and 138 or 130 -- Mage outfit ID local outfitCost = 50 -- Cost in premium_points to acquire the outfit if not player:hasOutfit(outfitId) or not player:hasOutfit(outfitId, 3) then db.query("UPDATE accounts SET premium_points = premium_points - " .. outfitCost .. " WHERE account_id = " .. player:getAccountId()) player:addOutfitAddon(outfitId, 3) -- Add outfit / addons player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Mage outfit addons for " .. outfitCost .. " premium_points!") else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Mage outfit!") end ---------------- elseif words == "!shopCitizen" then local outfitId = (player:getSex() == PLAYERSEX_FEMALE) and 136 or 128 -- Citizen outfit ID local outfitCost = 50 -- Cost in premium_points to acquire the outfit if not player:hasOutfit(outfitId) or not player:hasOutfit(outfitId, 3) then db.query("UPDATE accounts SET premium_points = premium_points - " .. outfitCost .. " WHERE account_id = " .. player:getAccountId()) player:addOutfitAddon(outfitId, 3) -- Add Citizen outfit / addons player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Citizen outfit addons for " .. outfitCost .. " premium_points!") else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Citizen outfit!") end ---------------- elseif words == "!shopHunter" then local outfitId = (player:getSex() == PLAYERSEX_FEMALE) and 137 or 129 -- Hunter outfit ID local outfitCost = 50 -- Cost in premium_points to acquire the outfit if not player:hasOutfit(outfitId) or not player:hasOutfit(outfitId, 3) then db.query("UPDATE accounts SET premium_points = premium_points - " .. outfitCost .. " WHERE account_id = " .. player:getAccountId()) player:addOutfitAddon(outfitId, 3) -- Add Hunter outfit / addons player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Hunter outfit addons for " .. outfitCost .. " premium_points!") else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Hunter outfit!") end ---------------- elseif words == "!shopKnight" then local outfitId = (player:getSex() == PLAYERSEX_FEMALE) and 139 or 131 -- Knight outfit ID local outfitCost = 50 -- Cost in premium_points to acquire the outfit if not player:hasOutfit(outfitId) or not player:hasOutfit(outfitId, 3) then db.query("UPDATE accounts SET premium_points = premium_points - " .. outfitCost .. " WHERE account_id = " .. player:getAccountId()) player:addOutfitAddon(outfitId, 3) -- Add Knight outfit / addons player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Knight outfit addons for " .. outfitCost .. " premium_points!") else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Knight outfit!") end -- Add more commands and messages as necessary end return false end outfitsCustom:separator(" ") outfitsCustom:register() Para comprar uma montaria.
    local shopsCustom = TalkAction("!shopMidnight Panther", "!shopWidow Queen", "!shopRacing Bird", "!shopWar Bear", "!shopBlack Sheep", "!shopDraptor", "!shopTitanica", "!shopTin Lizzard", "!shopBlazebringer", "!shopRapid Boar", "!shopStampor", "!shopUndead Cavebear", "!shopDonkey", "!shopTiger Slug", "!shopUniwheel", "!shopCrystal Wolf", "!shopWar Horse", "!shopKingly Deer", "!shopTamed Panda", "!shopDromedary", "!shopScorpion King", "!shopDarkbrown Rented Horse", "!shopArmoured War Horse", "!shopShadow Draptor", "!shopGrey Rented Horse", "!shopBrown Rented Horse", "!shopLady Bug", "!shopManta Ray", "!shopIronblight", "!shopMagma Crawler", "!shopDragonling", "!shopGnarlhound", "!shopCrimson Ray", "!shopSteelbeak", "!shopWater Buffalo", "!shopTombstinger", "!shopPlatesaurian", "!shopUrsagrodon", "!shopThe Hellgrip", "!shopNoble Lion", "!shopDesert King", "!shopShock Head", "!shopWalker", "!shopAzudocus", "!shopCarpacosaurus", "!shopDeath Crawler", "!shopFlamesteed", "!shopJade Lion", "!shopJade Pincer", "!shopNethersteed", "!shopTempest", "!shopWinter King", "!shopDoombringer", "!shopWoodland Prince", "!shopHailstorm Fury", "!shopSiegebreaker", "!shopPoisonbane", "!shopBlackpelt", "!shopGolden Dragonfly", "!shopSteel Bee", "!shopCopper Fly", "!shopTundra Rambler", "!shopHighland Yak", "!shopGlacier Vagabond", "!shopShadow Hart", "!shopBlack Stag", "!shopEmperor Deer", "!shopFlying Divan", "!shopMagic Carpet", "!shopFloating Kashmir", "!shopRingtail Waccoon", "!shopNight Waccoon", "!shopEmerald Waccoon", "!shopFlitterkatzen", "!shopVenompaw", "!shopBatcat", "!shopSea Devil", "!shopCoralripper", "!shopPlumfish", "!shopGorongra", "!shopNoctungra", "!shopSilverneck", "!shopSlagsnare", "!shopNightstinger", "!shopRazorcreep", "!shopRift Runner", "!shopNightdweller", "!shopFrostflare", "!shopCinderhoof", "!shopMouldpincer", "!shopBloodcurl", "!shopLeafscuttler", "!shopSparkion", "!shopSwamp Snapper", "!shopMould Shell", "!shopReed Lurker", "!shopNeon Sparkid", "!shopVortexion", "!shopIvory Fang", "!shopShadow Claw", "!shopSnow Pelt", "!shopJackalope", "!shopDreadhare", "!shopWolpertinger", "!shopStone Rhino", "!shopGold Sphinx", "!shopEmerald Sphinx", "!shopShadow Sphinx", "!shopJungle Saurian", "!shopEmber Saurian", "!shopLagoon Saurian", "!shopBlazing Unicorn", "!shopArctic Unicorn", "!shopPrismatic unicorn", "!shopCranium Spider", "!shopCave Tarantula", "!shopGloom Widow", "!shopMole", "!shopMarsh Toad", "!shopSanguine Frog", "!shopToxic Toad", "!shopEbony Tiger", "!shopFeral Tiger", "!shopJungle Tiger", "!shopFleeting Knowledge", "!shopTawny Owl", "!shopSnowy Owl", "!shopBoreal Owl", "!shopLacewing Moth", "!shopHibernal Moth", "!shopCold Percht Sleigh", "!shopBright Percht Sleigh", "!shopDark Percht Sleigh", "!shopFestive Snowman", "!shopMuffled Snowman", "!shopCaped Snowman", "!shopRabbit Rickshaw", "!shopBunny Dray", "!shopCony Cart", "!shopRiver Crocovile", "!shopSwamp Crocovile", "!shopNightmarish Crocovile", "!shopGryphon", "!shopJousting Eagle", "!shopCerberus Champion", "!shopCold Percht Sleigh Variant", "!shopBright Percht Sleigh Variant", "!shopDark Percht Sleigh Variant", "!shopCold Percht Sleigh Final", "!shopBright Percht Sleigh Final", "!shopDark Percht Sleigh Final", "!shopBattle Badger", "!shopEther Badger", "!shopZaoan Badger", "!shopBlue Rolling Barrel", "!shopRed Rolling Barrel", "!shopGreen Rolling Barrel", "!shopFloating Sage", "!shopFloating Scholar", "!shopFloating Augur", "!shopHaze", "!shopAntelope", "!shopSnow Strider", "!shopDusk Pryer", "!shopDawn Strayer", "!shopSpectral Horse", "!shopSavanna Ostrich", "!shopCoral Rhea", "!shopEventide Nandu", "!shopVoracious Hyaena", "!shopCunning Hyaena", "!shopScruffy Hyaena", "!shopWhite Lion", "!shopKrakoloss", "!shopMerry Mammoth", "!shopHoliday Mammoth", "!shopFestive Mammoth", "!shopVoid Watcher", "!shopRune Watcher", "!shopRift Watcher", "!shopPhant", "!shopShellodon", "!shopSingeing Steed", "!shopHyacinth", "!shopPeony", "!shopDandelion", "!shopRustwurm", "!shopBogwurm", "!shopGloomwurm", "!shopEmerald Raven", "!shopMystic Raven", "!shopRadiant Raven", "!shopGloothomotive", "!shopTopaz Shrine", "!shopJade Shrine", "!shopObsidian Shrine", "!shopPoppy Ibex", "!shopMint Ibex", "!shopCinnamon Ibex") function shopsCustom.onSay(player, words, param) if words == "/shop" then return false end if words == "!shopMidnight Panther" then local shopId = 1 -- Mount ID local shopCost = 20 -- Cost in premium_points to acquire the shop if not player:hasMount(shopId) then db.query("UPDATE accounts SET premium_points = premium_points - " .. shopCost .. " WHERE account_id = " .. player:getAccountId()) player:addMount(shopId) -- player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Midnight Panther for " .. shopCost .. " premium_points!") else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Midnight Panther!") end elseif words == "!shopWidow Queen" then local shopId = 2 -- Mount ID local shopCost = 20 -- Cost in premium_points to acquire the shop if not player:hasMount(shopId) then db.query("UPDATE accounts SET premium_points = premium_points - " .. shopCost .. " WHERE account_id = " .. player:getAccountId()) player:addMount(shopId) -- player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Widow Queen for " .. shopCost .. " premium_points!") else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Widow Queen!") end elseif words == "!shopRacing Bird" then local shopId = 3 -- Mount ID local shopCost = 20 -- Cost in premium_points to acquire the shop if not player:hasMount(shopId) then db.query("UPDATE accounts SET premium_points = premium_points - " .. shopCost .. " WHERE account_id = " .. player:getAccountId()) player:addMount(shopId) -- player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Racing Bird for " .. shopCost .. " premium_points!") else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Racing Bird!") end elseif words == "!shopWar Bear" then local shopId = 4 -- Mount ID local shopCost = 20 -- Cost in premium_points to acquire the shop if not player:hasMount(shopId) then db.query("UPDATE accounts SET premium_points = premium_points - " .. shopCost .. " WHERE account_id = " .. player:getAccountId()) player:addMount(shopId) -- player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the War Bear for " .. shopCost .. " premium_points!") else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the War Bear!") end end end shopsCustom:separator(" ") shopsCustom:register() Clique no item para ganhar pontos e poder comprar na store!
    local premiumPointsAction = Action() local function doPlayerAddPremiumPoints(player, count) local accountId = player:getAccountId() db.query('UPDATE accounts SET premium_points = premium_points +' .. count .. ' WHERE id = ' .. db.escapeString(accountId)) end function premiumPointsAction.onUse(player, item, fromPosition, target, toPosition) doPlayerAddPremiumPoints(player, 100) player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have received 100 store point(s) in your account.") player:getPosition():sendMagicEffect(28) item:remove(1) return true end premiumPointsAction:id(24774) premiumPointsAction:register()  
    AGORA É ZNOTE..
    magic sword.
    local StoreCustom = TalkAction("!shopteste") function StoreCustom.onSay(player, words, param) local pointsToDeduct = 10 -- Replace with the number of points to be deducted removePoints(player, pointsToDeduct) local newItemID = 2401 -- Replace with the ID of the item the player will receive local newItemCount = 1 -- Quantity of the new item to be added to the player's inventory player:addItem(newItemID, newItemCount) player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have successfully purchased a new item in exchange for " .. pointsToDeduct .. " premium points.") return false end function removePoints(player, amount) local accountId = player:getAccountId() local query = "UPDATE `znote_accounts` SET `points` = `points` - " .. amount .. " WHERE `id` = " .. accountId db.query(query) end StoreCustom:separator(" ") StoreCustom:register() !points
    local StoreCustom = TalkAction("!shopteste") function StoreCustom.onSay(player, words, param) local pointsToDeduct = 10 -- Replace with the number of points to be deducted removePoints(player, pointsToDeduct) local newItemID = 2401 -- Replace with the ID of the item the player will receive local newItemCount = 1 -- Quantity of the new item to be added to the player's inventory player:addItem(newItemID, newItemCount) player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have successfully purchased a new item in exchange for " .. pointsToDeduct .. " premium points.") return false end function removePoints(player, amount) local accountId = player:getAccountId() local query = "UPDATE `znote_accounts` SET `points` = `points` - " .. amount .. " WHERE `id` = " .. accountId db.query(query) end StoreCustom:separator(" ") StoreCustom:register() outfits ou addons.
    local outfitsCustom = TalkAction("!shopMage", "!shopCitizen", "!shopHunter", "!shopKnight", "!shopNoblewoman", "!shopNobleman", "!shopSummoner", "!shopWarrior", "!shopBarbarian", "!shopDruid", "!shopWizard", "!shopOriental", "!shopPirate", "!shopAssassin", "!shopBeggar", "!shopShaman", "!shopNorsewoman", "!shopNorseman", "!shopNightmare", "!shopJester", "!shopBrotherhood", "!shopDemon Hunter", "!shopYalaharian", "!shopNewly Wed", "!shopWarmaster", "!shopWayfarer", "!shopRetro Warrior", "!shopRetro Citizen", "!shopRetro Hunter", "!shopRetro Knight", "!shopRetro Mage", "!shopRetro Noblewoman", "!shopRetro Nobleman", "!shopRetro Summoner") function outfitsCustom.onSay(player, words, param) if words == "/shop" then return false end if words == "!shopMage" then local outfitId = (player:getSex() == PLAYERSEX_FEMALE) and 138 or 130 -- Mage outfit ID local outfitCost = 50 -- Cost in points to acquire the outfit if not player:hasOutfit(outfitId) or not player:hasOutfit(outfitId, 3) then db.query("UPDATE znote_accounts SET points = points - " .. outfitCost .. " WHERE account_id = " .. player:getAccountId()) player:addOutfitAddon(outfitId, 3) -- Add outfit / addons player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Mage outfit addons for " .. outfitCost .. " points!") else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Mage outfit!") end ---------------- elseif words == "!shopCitizen" then local outfitId = (player:getSex() == PLAYERSEX_FEMALE) and 136 or 128 -- Citizen outfit ID local outfitCost = 50 -- Cost in points to acquire the outfit if not player:hasOutfit(outfitId) or not player:hasOutfit(outfitId, 3) then db.query("UPDATE znote_accounts SET points = points - " .. outfitCost .. " WHERE account_id = " .. player:getAccountId()) player:addOutfitAddon(outfitId, 3) -- Add Citizen outfit / addons player:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Citizen outfit addons for " .. outfitCost .. " points!") else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Citizen outfit!") end ---------------- elseif words == "!shopHunter" then local outfitId = (player:getSex() == PLAYERSEX_FEMALE) and 137 or 129 -- Hunter outfit ID local outfitCost = 50 -- Cost in points to acquire the outfit if not player:hasOutfit(outfitId) or not player:hasOutfit(outfitId, 3) then db.query("UPDATE znote_accounts SET points = points - " .. outfitCost .. " WHERE account_id = " .. player:getAccountId()) player:addOutfitAddon(outfitId, 3) -- Add Hunter outfit / addons player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Hunter outfit addons for " .. outfitCost .. " points!") else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Hunter outfit!") end ---------------- elseif words == "!shopKnight" then local outfitId = (player:getSex() == PLAYERSEX_FEMALE) and 139 or 131 -- Knight outfit ID local outfitCost = 50 -- Cost in points to acquire the outfit if not player:hasOutfit(outfitId) or not player:hasOutfit(outfitId, 3) then db.query("UPDATE znote_accounts SET points = points - " .. outfitCost .. " WHERE account_id = " .. player:getAccountId()) player:addOutfitAddon(outfitId, 3) -- Add Knight outfit / addons player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Knight outfit addons for " .. outfitCost .. " points!") else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Knight outfit!") end ---------------- elseif words == "!shopNoblewoman" then local outfitId = (player:getSex() == PLAYERSEX_FEMALE) and 140 or 132 -- outfit ID local outfitCost = 50 -- Cost in points to acquire the outfit if not player:hasOutfit(outfitId) or not player:hasOutfit(outfitId, 3) then db.query("UPDATE znote_accounts SET points = points - " .. outfitCost .. " WHERE account_id = " .. player:getAccountId()) player:addOutfitAddon(outfitId, 3) -- Add outfit / addons player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Noblewoman outfit addons for " .. outfitCost .. " points!") else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Noblewoman outfit!") end -- Add more commands and messages as necessary end return false end outfitsCustom:separator(" ") outfitsCustom:register() Montaria.
    local shopsCustom = TalkAction("!shopMidnight Panther", "!shopWidow Queen", "!shopRacing Bird", "!shopWar Bear", "!shopBlack Sheep", "!shopDraptor", "!shopTitanica", "!shopTin Lizzard", "!shopBlazebringer", "!shopRapid Boar", "!shopStampor", "!shopUndead Cavebear", "!shopDonkey", "!shopTiger Slug", "!shopUniwheel", "!shopCrystal Wolf", "!shopWar Horse", "!shopKingly Deer", "!shopTamed Panda", "!shopDromedary", "!shopScorpion King", "!shopDarkbrown Rented Horse", "!shopArmoured War Horse", "!shopShadow Draptor", "!shopGrey Rented Horse", "!shopBrown Rented Horse", "!shopLady Bug", "!shopManta Ray", "!shopIronblight", "!shopMagma Crawler", "!shopDragonling", "!shopGnarlhound", "!shopCrimson Ray", "!shopSteelbeak", "!shopWater Buffalo", "!shopTombstinger", "!shopPlatesaurian", "!shopUrsagrodon", "!shopThe Hellgrip", "!shopNoble Lion", "!shopDesert King", "!shopShock Head", "!shopWalker", "!shopAzudocus", "!shopCarpacosaurus", "!shopDeath Crawler", "!shopFlamesteed", "!shopJade Lion", "!shopJade Pincer", "!shopNethersteed", "!shopTempest", "!shopWinter King", "!shopDoombringer", "!shopWoodland Prince", "!shopHailstorm Fury", "!shopSiegebreaker", "!shopPoisonbane", "!shopBlackpelt", "!shopGolden Dragonfly", "!shopSteel Bee", "!shopCopper Fly", "!shopTundra Rambler", "!shopHighland Yak", "!shopGlacier Vagabond", "!shopShadow Hart", "!shopBlack Stag", "!shopEmperor Deer", "!shopFlying Divan", "!shopMagic Carpet", "!shopFloating Kashmir", "!shopRingtail Waccoon", "!shopNight Waccoon", "!shopEmerald Waccoon", "!shopFlitterkatzen", "!shopVenompaw", "!shopBatcat", "!shopSea Devil", "!shopCoralripper", "!shopPlumfish", "!shopGorongra", "!shopNoctungra", "!shopSilverneck", "!shopSlagsnare", "!shopNightstinger", "!shopRazorcreep", "!shopRift Runner", "!shopNightdweller", "!shopFrostflare", "!shopCinderhoof", "!shopMouldpincer", "!shopBloodcurl", "!shopLeafscuttler", "!shopSparkion", "!shopSwamp Snapper", "!shopMould Shell", "!shopReed Lurker", "!shopNeon Sparkid", "!shopVortexion", "!shopIvory Fang", "!shopShadow Claw", "!shopSnow Pelt", "!shopJackalope", "!shopDreadhare", "!shopWolpertinger", "!shopStone Rhino", "!shopGold Sphinx", "!shopEmerald Sphinx", "!shopShadow Sphinx", "!shopJungle Saurian", "!shopEmber Saurian", "!shopLagoon Saurian", "!shopBlazing Unicorn", "!shopArctic Unicorn", "!shopPrismatic unicorn", "!shopCranium Spider", "!shopCave Tarantula", "!shopGloom Widow", "!shopMole", "!shopMarsh Toad", "!shopSanguine Frog", "!shopToxic Toad", "!shopEbony Tiger", "!shopFeral Tiger", "!shopJungle Tiger", "!shopFleeting Knowledge", "!shopTawny Owl", "!shopSnowy Owl", "!shopBoreal Owl", "!shopLacewing Moth", "!shopHibernal Moth", "!shopCold Percht Sleigh", "!shopBright Percht Sleigh", "!shopDark Percht Sleigh", "!shopFestive Snowman", "!shopMuffled Snowman", "!shopCaped Snowman", "!shopRabbit Rickshaw", "!shopBunny Dray", "!shopCony Cart", "!shopRiver Crocovile", "!shopSwamp Crocovile", "!shopNightmarish Crocovile", "!shopGryphon", "!shopJousting Eagle", "!shopCerberus Champion", "!shopCold Percht Sleigh Variant", "!shopBright Percht Sleigh Variant", "!shopDark Percht Sleigh Variant", "!shopCold Percht Sleigh Final", "!shopBright Percht Sleigh Final", "!shopDark Percht Sleigh Final", "!shopBattle Badger", "!shopEther Badger", "!shopZaoan Badger", "!shopBlue Rolling Barrel", "!shopRed Rolling Barrel", "!shopGreen Rolling Barrel", "!shopFloating Sage", "!shopFloating Scholar", "!shopFloating Augur", "!shopHaze", "!shopAntelope", "!shopSnow Strider", "!shopDusk Pryer", "!shopDawn Strayer", "!shopSpectral Horse", "!shopSavanna Ostrich", "!shopCoral Rhea", "!shopEventide Nandu", "!shopVoracious Hyaena", "!shopCunning Hyaena", "!shopScruffy Hyaena", "!shopWhite Lion", "!shopKrakoloss", "!shopMerry Mammoth", "!shopHoliday Mammoth", "!shopFestive Mammoth", "!shopVoid Watcher", "!shopRune Watcher", "!shopRift Watcher", "!shopPhant", "!shopShellodon", "!shopSingeing Steed", "!shopHyacinth", "!shopPeony", "!shopDandelion", "!shopRustwurm", "!shopBogwurm", "!shopGloomwurm", "!shopEmerald Raven", "!shopMystic Raven", "!shopRadiant Raven", "!shopGloothomotive", "!shopTopaz Shrine", "!shopJade Shrine", "!shopObsidian Shrine", "!shopPoppy Ibex", "!shopMint Ibex", "!shopCinnamon Ibex") function shopsCustom.onSay(player, words, param) if words == "/shop" then return false end if words == "!shopMidnight Panther" then local shopId = 1 -- Mount ID local shopCost = 20 -- Cost in points to acquire the shop if not player:hasMount(shopId) then db.query("UPDATE znote_accounts SET points = points - " .. shopCost .. " WHERE account_id = " .. player:getAccountId()) player:addMount(shopId) -- player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Midnight Panther for " .. shopCost .. " points!") else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Midnight Panther!") end elseif words == "!shopWidow Queen" then local shopId = 2 -- Mount ID local shopCost = 20 -- Cost in points to acquire the shop if not player:hasMount(shopId) then db.query("UPDATE znote_accounts SET points = points - " .. shopCost .. " WHERE account_id = " .. player:getAccountId()) player:addMount(shopId) -- player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Widow Queen for " .. shopCost .. " points!") else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Widow Queen!") end elseif words == "!shopRacing Bird" then local shopId = 3 -- Mount ID local shopCost = 20 -- Cost in points to acquire the shop if not player:hasMount(shopId) then db.query("UPDATE znote_accounts SET points = points - " .. shopCost .. " WHERE account_id = " .. player:getAccountId()) player:addMount(shopId) -- player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the Racing Bird for " .. shopCost .. " points!") else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the Racing Bird!") end elseif words == "!shopWar Bear" then local shopId = 4 -- Mount ID local shopCost = 20 -- Cost in points to acquire the shop if not player:hasMount(shopId) then db.query("UPDATE znote_accounts SET points = points - " .. shopCost .. " WHERE account_id = " .. player:getAccountId()) player:addMount(shopId) -- player:getPosition():sendMagicEffect(CONST_ME_MAGIC_GREEN) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You acquired the War Bear for " .. shopCost .. " points!") else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You already have the War Bear!") end end end shopsCustom:separator(" ") shopsCustom:register() Clique no item para ganhar pontos e poder comprar na store.
    local premiumPointsAction = Action() local function doPlayerAddPremiumPoints(player, count) local accountId = player:getAccountId() db.query('UPDATE znote_accounts SET points = points +' .. count .. ' WHERE account_id = ' .. db.escapeString(accountId)) end function premiumPointsAction.onUse(player, item, fromPosition, target, toPosition) doPlayerAddPremiumPoints(player, 100) player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have received 100 store point(s) in your account.") player:getPosition():sendMagicEffect(28) item:remove(1) return true end premiumPointsAction:id(24774) premiumPointsAction:register() É só baixar o module e colocar no seu OTClient... Pronto! Espero que tenha gostado!
    https://drive.google.com/file/d/1Cl06Dx2o1ix2AO7aUXJRe292tLvfgU45/view?usp=sharing  
  7. Gostei
    paulo thush deu reputação a Qwizer em MercadoPago Checkout Transparente (CC)   
    MercadoPago Checkout Transparente (CC)
     
    Abaixo Segue código PHP de pagamento via cartão de credito pelo mercado pago com retorno automático para quem quiser adaptar em seus sites ter uma direção de onde ir 
    testado em Znote e MyAcc.
     

     
     
    https://mega.nz/folder/m4QkWBLS#PIvJ_scVm7w8-5FLlStTHg  
  8. Gostei
    Olá vou disponibilizar aqui o sistema de pagamento automático do mercado pago via pix utilizando o myaac.
    O Sistema esta livre de sql injection e com o workflow 100% correto.

    Em breve solto o do cartão de crédito.

    Configuração
     Coloque os conteúdos das pastas systems e plugins dentro de suas respectivas pastas em seu website. Configure o arquivo plugins/mercadopago/config.php com os dados necessarios Lembre-se de configurar o seu domínio no arquivo system/pages/pix.php
    procure por mywebsite.online e troque pelo seu dominio.
      Lembre-se de configurar a variavel do mercadopago no seu config.php  
     
    Aproveite seu sistema automático de doações.

    Downloads
    Tibiaking Cloud
    mp_pix.rar
    GithubDev: Automatic mercadopagoPIX System Gateway · thetibiaking/ttk-my-aac@eae160d · GitHub
    Updates
    Fix: Add variable to pixStatusUrl added on pix config.php · thetibiaking/ttk-my-aac@0a05720 · GitHub
    Fix: Wrong way to get collector ID · thetibiaking/ttk-my-aac@397efc8 (github.com)
    Ultimo Update
    thetibiaking/ttk-my-aac at pix-automatic-mp (github.com)


    Tabela para o Banco de dados.
    status.sql


    @Clyfe
      
     
  9. Gostei
    paulo thush deu reputação a Forged em O Lançamento mais esperado de 2024!   
    Ravendawn Chega ao Brasil em 16 de Janeiro
     
    Para os fãs de MMORPG, o estúdio por trás de Ravendawn promete um jogo com foco em um mundo dinâmico, customização profunda de personagens e uma economia totalmente impulsionada pelos jogadores.
     
     
    São Paulo, Janeiro de 2024 ー A Tavernlight Games acabou de anunciar um novo Trailer de Gameplay do Lançamento Oficial de Ravendawn. O tão aguardado MMORPG será lançado oficialmente no Brasil em 16 de Janeiro. Oferecendo uma experiência visual nostálgica com elementos modernos de gameplay, o jogo será completamente gratuito para jogar ー basta criar uma conta no site oficial do jogo.
     
    Para conhecer as mecânicas do jogo e parte de seu conteúdo, confira o novo Trailer de Lançamento Oficial no vídeo  a cima ou aqui: https://youtu.be/shuULlsl6G8.

    Ravendawn é um MMORPG gratuito com visão top-down, destacando-se pela customização profunda de personagens e pela forte interação de comunidade em um mundo onde a economia é totalmente dirigida pelos jogadores. Os participantes influenciam ativamente esta economia dinâmica, seja através do transporte de mercadorias por terra ou mar, ou desempenhando funções variadas como fazendeiros, artesãos, mercenários, aventureiros e outras.

    O lançamento no Brasil não é apenas um marco para o Ravendawn, mas também uma afirmação do compromisso da empresa em oferecer experiências imersivas e relevantes para os jogadores brasileiros, visto que o jogo estará totalmente traduzido para o português do Brasil. Com uma comunidade em constante crescimento, Ravendawn chega para ser um jogo indispensável para os entusiastas do gênero.
     
    ‘’Muitos nos chamaram de um Tibia moderno. Nós nos inspiramos neste título nostálgico que amávamos na nossa juventude, mas evoluímos esse estilo retrô com um design de jogo mais moderno. A paixão e o amor da comunidade brasileira nos levaram a localizar o Ravendawn em português brasileiro e a fomentar uma forte comunidade brasileira em torno do Ravendawn", disse Nicolas 'Knighter' Schrik, CEO e Diretor de Jogos da Tavernlight.

    Ravendawn também apresenta um sistema de monetização muito amigável aos jogadores, diferente da maioria dos MMORPGs gratuitos. A equipe se dedica muito no desenvolvimento e tem como objetivo estabelecer um jogo que marcará época e permanecerá por muitos anos. “Acreditamos fortemente que um sistema de monetização justo e amigável ao jogador, que não obrigue os jogadores a gastar dinheiro, é vital para transformar Ravendawn em um grande sucesso”, disse Nicolas ‘Knighter’ Schrik. Ravendawn oferecerá um sistema de Premium opcional no jogo, chamado de Patron, que proporcionará benefícios de qualidade de vida sem impedir que jogadores que não adquirirem o Patron experimentem o conteúdo do jogo ou causem a eles um atraso significativo em relação aos jogadores Patron, fazendo com que o jogo não seja “Pay-to-Win”.

    Prepare-se para explorar terras, construir casas, administrar fazendas e participar de batalhas navais em um mundo vibrante e cheio de possibilidades. Registre-se agora em Ravendawn Online e prepare-se para o Lançamento Oficial.
  10. Gostei
    paulo thush deu reputação a xWhiteWolf em New Library v. 1.2   
    Fala galera, hoje vim trazer pra vocês uma nova biblioteca de funções que eu venho desenvolvendo, pretendo ir atualizando esse tópico constantemente sempre adicionando funções novas e explicando a utilização delas. Algumas funções que eu coloquei aqui estão presentes na OTAL também, porém algumas eu fiz pequenas correções de forma que essa lib poderia facilmente substituir a OTAL sem grandes problemas (pelo menos se você utilizava apenas as funções básicas da otal)
    Todas as funções que não tem -- nome do autor do lado dela foram feitas por mim, xWhiteWolf ou Night Wolf (NW). O restante delas são créditos dos devidos autores, apenas coloquei pois considero funções vitais no server de cada um. Crie um arquivo em data/lib chamado 075 - White Wolf Functions.lua e coloque o seguinte código dentro:



     
    Agora eu vou explicar oque cada função faz porque de nada adianta lançar uma lib e não explicar oque ela faz não é mesmo? hahaha
    Obs inicial: quando uma função tiver em seus parametros um [] significa que oque está dentro do colchetes não é um parâmetro obrigatório.



    Como usar: doShowTimeByPos(cid, getCreaturePosition(cid), 20, 20)
    Irá fazer uma contagem regressiva na posição que o player se encontra começando de 20 e mandando a mensagem na mesma cor da fala dos monstros.
    Essa função é bem útil em actions/spells para fazer contagem de tempo em runas como a magic wall e ver quanto tempo falta pra magic wall sumir)

     
    Obs: Espero que ajude bastante pessoas a entender sobre funções, eu utilizei cid como o principal uid das funções nos exemplos mas você pode muito bem utilizar outros uids, fica a critério seu.

    Qualquer dúvida comentem abaixo que eu vou tentar ajudar da melhor maneira.
    Ahhh, isso daí foi testado em 8.54 mas deve funcionar em quase todas as versões que tenham as funções básicas do TFS. 

    EDIT: Pessoal, agora é sério, essa lib tem fácil umas 600 linhas, das quais umas 500 eu devo ter codado sozinho (na mão, linha por linha). Eu tive todo o trabalho de testar cada uma delas e oque eu peço é o mínimo de gratidão e respeito. Se eu te ajudei clique em Gostei, se você tiver alguma dúvida eu to me colocando a disposição de responder qualquer coisa relacionada ao tópico, mesmo que você não saiba nem oque é uma lib apenas venha aqui e escreva sua dúvida.

    EDIT 2: Duas novas funções adicionas, espero que gostem!

    EDIT 3: Três novas funções adicionadas juntamente com suas respectivas explicações.
  11. Gostei
    paulo thush deu reputação a King Laker em (Resolvido)Ocultar msg do comando   
    <talkaction words="!storebuy10D" log="no" event="script" value="2023/10d.lua"/>
    Você pode utilizar tabelas na script desse modulo de store por comando, assim ficando apenas 1 script entregando infinitos itens configuráveis de sua escolha.
  12. Gostei
    paulo thush deu reputação a Fabi Marzan em (Resolvido)Ocultar msg do comando   
    Fiquei confuso, é return true
     
    function onSay(cid, words, param) local playerCoinsItemId = 2625 -- ID do item de moeda local itemToSellId = 10311 -- ID do item a ser vendido if doPlayerRemoveItem(cid, playerCoinsItemId, 8) then -- Verifica se o jogador tem as moedas necessárias local newItem = doPlayerAddItem(cid, itemToSellId, 1) -- Adiciona o item ao jogador if newItem > 0 then doItemSetAttribute(newItem, "owner", getPlayerGUID(cid)) -- Define o dono do item como o jogador atual doItemSetAttribute(newItem, "Descricao", "Item Comprado por " .. getCreatureName(cid) .. ".") -- Define a descrição do item doSendMagicEffect(getPlayerPosition(cid), CONST_ME_MORTAREA) doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Voce comprou o item.") else -- Lidar com o caso de falha ao adicionar o item ao jogador end else doPlayerSendCancel(cid, 'Voce nao tem 8 Fiapo Credito.') doSendMagicEffect(getPlayerPosition(cid), CONST_ME_FLAMEAREA) end return true end  
  13. Gostei
    PokeFans é um servidor feito em cima base disponibilizada pelo @pota. No inicio era um projeto para estudar a TFS 1.2, visto que sempre trabalhei com 0.3.6.
    Fiquei maravilhado com a simplicidade e as possibilidades quase infinitas da base. Comecei a me dedicar mais e eventualmente nos tornamos um servidor sério.
     
    O PokeFans possui diversos sistemas novos que foram implementados em cima da base POTA, muitos mesmos, seria incapaz de nomear todos neste post, então deixo o link do https://trello.com/b/ELrkzeTi/pokefans
     
    O servidor era muito popular por um tempo, atingindo números bem altos para um Poketibia (100 ~ 120 players), mas eventualmente tivemos problemas sérios com lag,
    não sei se por alguém atacando, conflito de código causado pela quantidade de mudanças que fiz, fato é que após muito buscar uma resposta, finalmente consegui resolver o lag, mas não sem antes perder certa de 70% da player base.
    Junto à isso tive problemas pessoas sérios e tudo isso acabou me desmotivando bastante, entretanto, PokeFans pra mim foi uma ótima fase, fiz muitos amigos, tive bons momentos e aprendi ainda mais sobre lua, c++ e até esse HTML esquisito que usamos no OTC. Por isso não podia deixar a base mofando no meu drive, ela merece estar online e proporcionar bons momentos à todos.
     
    E com esta longa carta introdutória, com vocês, PokeFans.
     
    IMAGENS/SISTEMAS/CONTEUDO
     
    DOWNLOAD
    https://mega.nz/file/zVBVgKIZ#mfJZjw93ir3Rrpb05qfnafMMw9dlU3KJL9hLUQCXoV8
    https://www.mediafire.com/file/ejry9qxpe71mkvz/pokefans.rar/file
    SCAN
    https://www.virustotal.com/gui/url/f5da18695fff6d14f92c75e6d211de27c450abc5c12bfe861466c6ee9ed37578/detection
    https://www.virustotal.com/gui/url/d750e2fad1faab64b5f549c854ecddb03a27ff938e03981f0f696aa16eb4a818?nocache=1
    (Deu flag ESTsecurity - Malicious, não faço ideia do que seja, se alguém puder me auxiliar no que seja)
     
    OBSERVAÇÕES
    Não prestarei suporte à base, entretanto, atuo como freelancer de luascript e modulos para OTC, você pode entrar em contato comigo pelo Discord: zayonowatari
    Para abrir o mapa no Remeres você precisa de um SPR/DAT sem transparência, basta salvar sem transparência diretamente do object builder.
    Caso você tenha gostado da base e tenha interesse em fazer uma doação, utilize essa chave pix: f3cb7525-2b8c-47f8-8db6-876c8cd68bde
     
    CRÉDITOS
    @pota - por todo o seu trabalho e humildade em disponibilizar sua base inicialmente, sem ela não estariamos aqui.
    theforgottenserver - sem eles nenhuma base estaria aqui.
    OTLand e Tibiaking - ambas as comunidades me auxiliaram a vida toda com todas as dúvidas que tive, respeito máximo à todos que fazem parte disso.
  14. Haha
    paulo thush recebeu reputação de Mateus Robeerto em (Resolvido)Mod Otc V8   
    Testei aqui funcionou msm achei que tinha que configurar alguma coisa, gosteeeei. vlw manim
  15. Gostei
    paulo thush deu reputação a Mateus Robeerto em (Resolvido)Mod Otc V8   
    Acabei de testar esse mod.. Gostei demais.. Você tem que adicionar seu nick do GM e vai aparecer em cima "ADMINISTRADOR", ou dá para colocar VIP.. e outros nomes que você quiser
     
     
    alterar o nome etc simples
    local playerTitles = {["GM Vortex"] = {title = "[Administrator]", color = "red"}}

  16. Gostei
    paulo thush deu reputação a koete em AJUDA "disconnected for exceeding packet per second limit."   
    Percebi que ninguém respondeu, e sei que já fazem 30 dias. Mas encontrei pelo google esse post e não vou deixar de responder pois há vários players que não sabem como resolver. Vai no config.lua e modifica "maxPacketsPerSecond = 25" para mais pacotes por segundos.
  17. Gostei
    paulo thush deu reputação a Evollutions em (RESOLVIDO) Znote AAC Erro nas sprites   
    .Qual servidor ou website você utiliza como base? 
    Znote AAC
    Qual o motivo deste tópico? 
    Ola pessoal do TK, estou com uma dificuldade no meu site, eu coloquei alguns itens no shop para vender, quase todos ficaram certos, porem alguns ficaram com a sprite errada no site:
    está aparecendo a sprite da coluna da esquerda, mas era pra aparecer da coluna da direita:
     
     

     
    Alguem sabe onde eu atualizo isso nos arquivos?
     
    Obrigado desde já!
     
    http://items.znote.eu/items.zip
     
    RESOLVIDO: 
    Consegui resolver,  usando um tutorial do Otland > https://otland.net/threads/znote-acc-shop-image.256046/
    Explicando:
    Você tem que alterar no config.php a parte onde está 
     
    tem que entrar nessa pagina -> http://items.znote.eu/ e no final dela tem um arquivo pra baixar "items.zip" ou usando o link " http://items.znote.eu/items.zip "
    então você cria uma pasta dentro da sua pasta htdos (ou na mesma pasta que estiver o config.php do seu website) e renomeie ela para qualquer nome, no meu caso eu coloquei sprites, entao você modifica o caminho do imageserver ficando assim
     
    e a parte que da um pouco de trabalho, é renomear os arquivos que estão com sprite errada, no meu caso eu tive que renomear cerca de 30 gifs (dentro da pasta sprites) para o numero correspondente aos do servidor.
     
  18. Gostei
    paulo thush deu reputação a luanluciano93 em [AJUDA]star.lua   
    O script é type startup, ou seja, ele executa apenas ao inciar o servidor. Pelo que pude ver ele executa 2 querys (comandos) na database ... 

    O nome dele normalmente é start.lua, mas pode ser star.lua tbem, rsrsrs

    Verifica no globalevents.xml se a tag dele esta correta, ela deve estar +/- assim .. 
    <globalevent name="server_start" type="startup" event="script" value="star.lua"/> OBS: verifique se é star ou start.

    Outra coisa importante, para executar uma query em algum script lua, precisa de determinado comando, e este comando depende da versão do seu TFS

    Ou seja, na versão 0.3.6 usamos "db.executeQuery" e na versão 0.4 usamos" db.query", bem simples né?

    Enfim, seu script deve ficar assim [TFS versão 0.3.6.]
    function onStartup() db.executeQuery("UPDATE `players` SET `online` = 0 WHERE `world_id` = " .. getConfigValue('worldId') .. ";") db.executeQuery("DELETE FROM `guild_wars` WHERE `status` = 0 AND `begin` < " .. (os.time() - 2 * 86400) .. ";") db.executeQuery("UPDATE `guild_wars` SET `status` = 5, `end` = " .. os.time() .. " WHERE `status` = 1 AND `end` > 0 AND `end` < " .. os.time() .. ";") return true end Ou assim  [TFS versão 0.4]
    function onStartup() db.query("UPDATE `players` SET `online` = 0 WHERE `world_id` = " .. getConfigValue('worldId') .. ";") db.query("DELETE FROM `guild_wars` WHERE `status` = 0 AND `begin` < " .. (os.time() - 2 * 86400) .. ";") db.query("UPDATE `guild_wars` SET `status` = 5, `end` = " .. os.time() .. " WHERE `status` = 1 AND `end` > 0 AND `end` < " .. os.time() .. ";") return true end Espero ter ajudado.

    edite --- 

    Resolvido? Se sim clique na melhor resposta!
     
  19. Gostei
    paulo thush deu reputação a Cat em Itens e Tokens   
    Eu fiz esses tokens menores e editei uns jewels do Tibia e estou disponibilizando pra vcs. Acompanha também uns anéis e colares que tem no Tibia porém versão holy/death.
     

  20. Gostei
    paulo thush deu reputação a Artur Teixeira em Erro SQL :/   
    cara
    sua solução é perfeita
    basta excluir o arquivo shop.lua que resolve o problema
  21. Gostei
    paulo thush deu reputação a Cat em Telhado Clássico do Tibia Completo [191 peças]   
    Veja também: • Telhado Venore do Tibia Completo (81 peças)
     

     
    TIBIA - TELHADO CLÁSSICO
     
       Fiz esse pack e decidi compartilhar com a comunidade. Aproveitei e fiz um rework em algumas peças auxiliares como Arcos, Corrimãos. Acompanha também no pack bordas, chaminés e fumaças.
     
       ?
     
    https://discord.gg/Ewu2J3qWhe.
     
     
    CONTEÚDO DO PACK










     

    »telhados_academia_de_mapping.rarspan widgetspan widget
  22. Gostei
    paulo thush deu reputação a Cat em Árvores do Tibia - Variações By Nolis   
    Fiz essas peças para deixar a natureza Tibiana mais variada, recomendado uso de pattern + peças individuais para melhor efeito.
    Créditos: Cipsoft
     
    Amostra:

     
    Download:
    arvores_tibia.rar
     

     
  23. Curtir
    paulo thush recebeu reputação de DarkRed em Dragon S L Outfit   
    E ai galera do Mal, Eu to com um servidor 8.60 e eu estou adicionando outfith do tibia atual, so que com os addon full. Muita gente ta me pedindo no discord, Whats, Vou disponibilizar aqui. Sei que e facil mais eu não vi em nenhum lugar então. Ate agora eu fiz somente Outfit Female, o male ainda estou editando quando termina eu posto também.
     

     
    Download
     
    SCAN
     
    CREDITOS: Não precisa nem dizer né... 
     
     
  24. Gostei
    paulo thush deu reputação a Forged em [Sistema de Ticket] Atendimento - Gesior Acc   
    SOLUÇÕES -  HelpDesk 100%
     



    Olaaa pessoal Tudo bemm ??? Entao consegui instalar aqui em meu gesior  1.0    
    E Consegui tbm salvar todas as imagens. Como vi que muitos estão procurando vou postar a solução aqui para vocês... 

    Se Possível Liberem um REP+  foi um prazer ajuda-los......

    Vamos la.
    Primeiramente para concertar o BUG de que admin nao pode responder os tickets, faça o seguinte:
     
    Vá até a linha que tem o código abaixo:
    $account = $ots->createObject('Account'); E substitua por:
    $account = new Account;
    Agora segue a pasta de Imagens, jogue ela dentro de www/imagens

    Link Mediafire: Opção de download:
    http://www.mediafire.com/download/vv1x3brp9axlq3h/bug.rar
     
     
    Se Possível Liberem um REP+  foi um prazer ajuda-los......

    Download diretamente do fórum:
    bug.rar
  25. Gostei
    paulo thush deu reputação a vine96 em Baiak-PvP [8.60] - Watch System + Cast Look   
    Bem simples de resolver ao criar o banco de dados para o server coloca como: utf8mb4_unicode_ci
    Galera vou fazer a minha boa ação de fim de ano.
     
    Explicando: essa base do Baiak PVP é realmente muito boa e bem estável eu estou a quase 2 meses ininterruptos com o server online e sem problemas de crash, rollback ou qualquer coisa do tipo, já testei diversos bugs conhecidos de derrubar servidor e nada acontece com essas sources, é uma base realmente muito sólida e ótima para um servidor 8.6.
     
    Porém recentemente descobri um bug que é o seguinte, ao player utilizar !leavehouse ou perder a house e afins, os seus itens não vão para o depot, eles simplesmente somem.
     
    O distro quem compilou foi eu com base nas sources disponibilizadas aqui mesmo, no caso compilei para ubuntu 14.04.
     
    Ao testar no testserver que possuo, e utilizando outra distro com sources acredito ser de outra revisão do TFS 0.4 esse bug não acontece, os itens são entregue normalmente ao depot do jogador.
     
    Descobri então que se trata de um bug nas sources, no caso a house.cpp
     
    Fiz uma alteração no arquivo e após isso ficou 100%, para tal vou disponibilizar o arquivo editado aqui para vocês.
     
    Troque todo o código do arquivo house.cpp por esse:
     
    //////////////////////////////////////////////////////////////////////// // OpenTibia - an opensource roleplaying game //////////////////////////////////////////////////////////////////////// // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. //////////////////////////////////////////////////////////////////////// #include "otpch.h" #include "house.h" #include "tools.h" #include "database.h" #include "beds.h" #include "town.h" #include "iologindata.h" #include "ioguild.h" #include "iomapserialize.h" #include "configmanager.h" #include "game.h" extern ConfigManager g_config; extern Game g_game; House::House(uint32_t houseId) { guild = pendingTransfer = isprotected = false; name = "OTX headquarter (Flat 1, Area 42)"; entry = Position(); id = houseId; rent = price = townId = paidUntil = owner = rentWarnings = lastWarning = 0; syncFlags = HOUSE_SYNC_NAME | HOUSE_SYNC_TOWN | HOUSE_SYNC_SIZE | HOUSE_SYNC_PRICE | HOUSE_SYNC_RENT | HOUSE_SYNC_GUILD; } void House::addTile(HouseTile* tile) { tile->setFlag(TILESTATE_PROTECTIONZONE); houseTiles.push_back(tile); } void House::addBed(BedItem* bed) { bedsList.push_back(bed); bed->setHouse(this); } void House::addDoor(Door* door) { door->addRef(); doorList.push_back(door); door->setHouse(this); updateDoorDescription("", door); } void House::removeDoor(Door* door) { HouseDoorList::iterator it = std::find(doorList.begin(), doorList.end(), door); if(it != doorList.end()) { (*it)->unRef(); doorList.erase(it); } } Door* House::getDoorByNumber(uint8_t doorId) const { for(HouseDoorList::const_iterator it = doorList.begin(); it != doorList.end(); ++it) { if((*it)->getDoorId() == doorId) return (*it); } return NULL; } Door* House::getDoorByPosition(const Position& pos) { for(HouseDoorList::iterator it = doorList.begin(); it != doorList.end(); ++it) { if((*it)->getPosition() == pos) return (*it); } return NULL; } void House::setOwner(uint32_t guid) { owner = guid; updateDoorDescription(); } bool House::setOwnerEx(uint32_t guid, bool transfer) { if(owner == guid) return true; if(isGuild() && guid) { Player* player = g_game.getPlayerByGuidEx(guid); if(!player) return false; guid = player->getGuildId(); if(player->isVirtual()) delete player; } if(owner) { rentWarnings = paidUntil = 0; if(transfer) clean(); setAccessList(SUBOWNER_LIST, "", !transfer); setAccessList(GUEST_LIST, "", !transfer); for(HouseDoorList::iterator it = doorList.begin(); it != doorList.end(); ++it) (*it)->setAccessList(""); } setOwner(guid); lastWarning = guid ? time(NULL) : 0; Database* db = Database::getInstance(); DBTransaction trans; if(!trans.begin()) return false; IOMapSerialize::getInstance()->saveHouse(db, this); return trans.commit(); } bool House::isGuild() const { return g_config.getBool(ConfigManager::GUILD_HALLS) && guild; } bool House::isBidded() const { Database* db = Database::getInstance(); DBResult_ptr result; DBQuery query; query << "SELECT `house_id` FROM `house_auctions` WHERE `house_id` = " << id << " LIMIT 1"; if(!(result = db->storeQuery(query.str()))) return false; return true; } void House::updateDoorDescription(std::string _name/* = ""*/, Door* door/* = NULL*/) { std::string tmp = "house"; if(isGuild()) tmp = "hall"; char houseDescription[200]; if(owner) { if(isGuild()) IOGuild::getInstance()->getGuildById(_name, owner); else if(_name.empty()) IOLoginData::getInstance()->getNameByGuid(owner, _name); sprintf(houseDescription, "It belongs to %s '%s'. %s owns this %s.", tmp.c_str(), name.c_str(), _name.c_str(), tmp.c_str()); } else sprintf(houseDescription, "It belongs to %s '%s'. Nobody owns this %s. It costs %d gold coins.", tmp.c_str(), name.c_str(), tmp.c_str(), price); if(!door) { for(HouseDoorList::iterator it = doorList.begin(); it != doorList.end(); ++it) (*it)->setSpecialDescription(houseDescription); } else door->setSpecialDescription(houseDescription); } void House::removePlayer(Player* player, bool ignoreRights) { if(!ignoreRights && player->hasFlag(PlayerFlag_CanEditHouses)) return; Position curPos = player->getPosition(), newPos = g_game.getClosestFreeTile(player, entry, false, false); if(g_game.internalTeleport(player, newPos, false) == RET_NOERROR && !player->isGhost()) { g_game.addMagicEffect(curPos, MAGIC_EFFECT_POFF); g_game.addMagicEffect(newPos, MAGIC_EFFECT_TELEPORT); } } void House::removePlayers(bool ignoreInvites) { PlayerVector kickList; for(HouseTileList::iterator it = houseTiles.begin(); it != houseTiles.end(); ++it) { CreatureVector* creatures = (*it)->getCreatures(); if(!creatures) continue; Player* player = NULL; for(CreatureVector::iterator cit = creatures->begin(); cit != creatures->end(); ++cit) { if((player = (*cit)->getPlayer()) && !player->isRemoved() && (ignoreInvites || !isInvited(player))) kickList.push_back(player); } } if(kickList.empty()) return; for(PlayerVector::iterator it = kickList.begin(); it != kickList.end(); ++it) removePlayer((*it), false); } bool House::kickPlayer(Player* player, Player* target) { if(!target || target->isRemoved()) return false; HouseTile* houseTile = target->getTile()->getHouseTile(); if(!houseTile || houseTile->getHouse() != this) return false; bool self = player == target; if(getHouseAccessLevel(player) < getHouseAccessLevel(target) && !self) return false; removePlayer(target, self); return true; } void House::clean() { for(HouseBedList::iterator bit = bedsList.begin(); bit != bedsList.end(); ++bit) { if((*bit)->getSleeper()) (*bit)->wakeUp(); } removePlayers(true); transferToDepot(); } bool House::transferToDepot() { if(!townId) return false; Player* player = NULL; if(owner) { uint32_t tmp = owner; if(isGuild() && !IOGuild::getInstance()->swapGuildIdToOwner(tmp)) tmp = 0; if(tmp) player = g_game.getPlayerByGuidEx(tmp); } Item* item = NULL; Container* tmpContainer = NULL; ItemList moveList; for(HouseTileList::iterator it = houseTiles.begin(); it != houseTiles.end(); ++it) { for(uint32_t i = 0; i < (*it)->getThingCount(); ++i) { if(!(item = (*it)->__getThing(i)->getItem())) continue; if(item->isPickupable()) moveList.push_back(item); else if((tmpContainer = item->getContainer())) { for(ItemList::const_iterator it = tmpContainer->getItems(); it != tmpContainer->getEnd(); ++it) moveList.push_back(*it); } } } if(player) { Depot* depot = player->getDepot(townId, true); for(ItemList::iterator it = moveList.begin(); it != moveList.end(); ++it) g_game.internalMoveItem(NULL, (*it)->getParent(), depot, INDEX_WHEREEVER, (*it), (*it)->getItemCount(), NULL, FLAG_NOLIMIT); if(player->isVirtual()) { IOLoginData::getInstance()->savePlayer(player); delete player; } } else { for(ItemList::iterator it = moveList.begin(); it != moveList.end(); ++it) g_game.internalRemoveItem(NULL, (*it), (*it)->getItemCount(), false, FLAG_NOLIMIT); } return true; } bool House::isInvited(const Player* player) { return getHouseAccessLevel(player) != HOUSE_NO_INVITED; } AccessHouseLevel_t House::getHouseAccessLevel(const Player* player) { if(!player) return HOUSE_NO_INVITED; if(player->hasFlag(PlayerFlag_CanEditHouses)) return HOUSE_OWNER; if(!owner) return HOUSE_NO_INVITED; AccessHouseLevel_t tmp = HOUSE_NO_INVITED; if(isGuild()) { if(player->getGuildId() == owner) { switch(player->getGuildLevel()) { case GUILDLEVEL_LEADER: return HOUSE_OWNER; case GUILDLEVEL_VICE: return HOUSE_SUBOWNER; default: tmp = HOUSE_GUEST; } } } else if(player->getGUID() == owner/* || player->marriage == owner*/) return HOUSE_OWNER; if(subOwnerList.isInList(player)) return HOUSE_SUBOWNER; if(guestList.isInList(player)) return HOUSE_GUEST; return tmp; } bool House::canEditAccessList(uint32_t listId, const Player* player) { switch(getHouseAccessLevel(player)) { case HOUSE_OWNER: return true; case HOUSE_SUBOWNER: return listId == GUEST_LIST; default: break; } return false; } bool House::getAccessList(uint32_t listId, std::string& list) const { if(listId == GUEST_LIST) { guestList.getList(list); return true; } if(listId == SUBOWNER_LIST) { subOwnerList.getList(list); return true; } if(Door* door = getDoorByNumber(listId)) return door->getAccessList(list); #ifdef __DEBUG_HOUSES__ std::clog << "[Failure - House::getAccessList] door == NULL, listId = " << listId <<std::endl; #endif return false; } void House::setAccessList(uint32_t listId, const std::string& textlist, bool teleport/* = true*/) { if(listId == GUEST_LIST) guestList.parseList(textlist); else if(listId == SUBOWNER_LIST) subOwnerList.parseList(textlist); else { if(Door* door = getDoorByNumber(listId)) door->setAccessList(textlist); #ifdef __DEBUG_HOUSES__ else std::clog << "[Failure - House::setAccessList] door == NULL, listId = " << listId <<std::endl; #endif return; } if(teleport) removePlayers(false); } TransferItem* TransferItem::createTransferItem(House* house) { TransferItem* transferItem = new TransferItem(house); transferItem->addRef(); transferItem->setID(ITEM_HOUSE_TRANSFER); char buffer[150]; sprintf(buffer, "It is a %s transfer document for '%s'.", house->isGuild() ? "guild hall" : "house", house->getName().c_str()); transferItem->setSpecialDescription(buffer); transferItem->setSubType(1); return transferItem; } bool TransferItem::onTradeEvent(TradeEvents_t event, Player* owner, Player* seller) { switch(event) { case ON_TRADE_TRANSFER: { if(house) house->setOwnerEx(owner->getGUID(), true); g_game.internalRemoveItem(NULL, this, getItemCount()); seller->transferContainer.setParent(NULL); break; } case ON_TRADE_CANCEL: { owner->transferContainer.setParent(NULL); owner->transferContainer.__removeThing(this, getItemCount()); g_game.freeThing(this); break; } default: return false; } return true; } void AccessList::getList(std::string& _list) const { _list = list; } bool AccessList::parseList(const std::string& _list) { playerList.clear(); guildList.clear(); expressionList.clear(); regexList.clear(); list = _list; if(_list.empty()) return true; std::stringstream listStream(_list); std::string line; while(getline(listStream, line)) { trimString(line); trim_left(line, "\t"); trim_right(line, "\t"); trimString(line); toLowerCaseString(line); if(line.empty()) break; if(line.substr(0, 1) == "#" || line.length() > 100) continue; if(line.find("@") != std::string::npos) { std::string::size_type pos = line.find("@"); addGuild(line.substr(pos + 1), line.substr(0, pos)); } else if(line.find("!") != std::string::npos || line.find("*") != std::string::npos || line.find("?") != std::string::npos) addExpression(line); else addPlayer(line); } return true; } bool AccessList::isInList(const Player* player) { std::string name = player->getName(); boost::cmatch what; try { toLowerCaseString(name); for(RegexList::iterator it = regexList.begin(); it != regexList.end(); ++it) { if(boost::regex_match(name.c_str(), what, it->first)) return it->second; } } catch(...) {} if(playerList.find(player->getGUID()) != playerList.end()) return true; for(GuildList::iterator git = guildList.begin(); git != guildList.end(); ++git) { if(git->first == player->getGuildId() && ((uint32_t)git->second == player->getRankId() || git->second == -1)) return true; } return false; } bool AccessList::addPlayer(std::string& name) { std::string tmp = name; uint32_t guid; if(!IOLoginData::getInstance()->getGuidByName(guid, tmp) || playerList.find(guid) != playerList.end()) return false; playerList.insert(guid); return true; } bool AccessList::addGuild(const std::string& guildName, const std::string& rankName) { uint32_t guildId; if(!IOGuild::getInstance()->getGuildId(guildId, guildName)) return false; std::string tmp = rankName; int32_t rankId = IOGuild::getInstance()->getRankIdByName(guildId, tmp); if(!rankId && (tmp.find("?") == std::string::npos || tmp.find("!") == std::string::npos || tmp.find("*") == std::string::npos)) rankId = -1; if(!rankId) return false; for(GuildList::iterator git = guildList.begin(); git != guildList.end(); ++git) { if(git->first == guildId && git->second == rankId) return true; } guildList.push_back(std::make_pair(guildId, rankId)); return true; } bool AccessList::addExpression(const std::string& expression) { for(ExpressionList::iterator it = expressionList.begin(); it != expressionList.end(); ++it) { if((*it) == expression) return false; } std::string out, meta = ".[{}()\\+|^$"; for(std::string::const_iterator it = expression.begin(); it != expression.end(); ++it) { if(meta.find(*it) != std::string::npos) out += "\\"; out += (*it); } replaceString(out, "**", ""); replaceString(out, "*", ".*"); replaceString(out, "?", ".?"); try { if(out.length() > 0) { expressionList.push_back(out); if(out.substr(0, 1) == "!") { if(out.length() > 1) regexList.push_front(std::make_pair(boost::regex(out.substr(1)), false)); } else regexList.push_back(std::make_pair(boost::regex(out), true)); } } catch(...) {} return true; } Door::~Door() { delete accessList; } Attr_ReadValue Door::readAttr(AttrTypes_t attr, PropStream& propStream) { if(attr != ATTR_HOUSEDOORID) return Item::readAttr(attr, propStream); uint8_t _doorId = 0; if(!propStream.getByte(_doorId)) return ATTR_READ_ERROR; doorId = _doorId; return ATTR_READ_CONTINUE; } void Door::copyAttributes(Item* item) { Item::copyAttributes(item); if(Door* door = item->getDoor()) { doorId = door->getDoorId(); std::string list; if(door->getAccessList(list)) setAccessList(list); } } void Door::onRemoved() { Item::onRemoved(); if(house) house->removeDoor(this); } bool Door::canUse(const Player* player) { if(!house || house->getHouseAccessLevel(player) >= HOUSE_SUBOWNER) return true; return accessList->isInList(player); } void Door::setHouse(House* _house) { if(house) return; house = _house; if(!accessList) accessList = new AccessList(); } bool Door::getAccessList(std::string& list) const { if(!house) return false; accessList->getList(list); return true; } void Door::setAccessList(const std::string& textlist) { if(!accessList) accessList = new AccessList(); accessList->parseList(textlist); } Houses::Houses() { rentPeriod = RENTPERIOD_NEVER; std::string strValue = asLowerCaseString(g_config.getString(ConfigManager::HOUSE_RENT_PERIOD)); if(strValue == "yearly") rentPeriod = RENTPERIOD_YEARLY; else if(strValue == "monthly") rentPeriod = RENTPERIOD_MONTHLY; else if(strValue == "weekly") rentPeriod = RENTPERIOD_WEEKLY; else if(strValue == "daily") rentPeriod = RENTPERIOD_DAILY; } bool Houses::loadFromXml(std::string filename) { xmlDocPtr doc = xmlParseFile(filename.c_str()); if(!doc) { std::clog << "[Warning - Houses::loadFromXml] Cannot load houses file." << std::endl; std::clog << getLastXMLError() << std::endl; return false; } xmlNodePtr houseNode, root = xmlDocGetRootElement(doc); if(xmlStrcmp(root->name,(const xmlChar*)"houses")) { std::clog << "[Error - Houses::loadFromXml] Malformed houses file." << std::endl; xmlFreeDoc(doc); return false; } int32_t intValue; std::string strValue; houseNode = root->children; while(houseNode) { if(xmlStrcmp(houseNode->name,(const xmlChar*)"house")) { houseNode = houseNode->next; continue; } int32_t houseId = 0; if(!readXMLInteger(houseNode, "houseid", houseId)) { std::clog << "[Error - Houses::loadFromXml] Could not read houseId" << std::endl; xmlFreeDoc(doc); return false; } House* house = Houses::getInstance()->getHouse(houseId); if(!house) { std::clog << "[Error - Houses::loadFromXml] Unknown house with id: " << houseId << std::endl; xmlFreeDoc(doc); return false; } Position entry(0, 0, 0); if(readXMLInteger(houseNode, "entryx", intValue)) entry.x = intValue; if(readXMLInteger(houseNode, "entryy", intValue)) entry.y = intValue; if(readXMLInteger(houseNode, "entryz", intValue)) entry.z = intValue; if(readXMLString(houseNode, "name", strValue)) house->setName(strValue); else house->resetSyncFlag(House::HOUSE_SYNC_NAME); house->setEntry(entry); if(!entry.x || !entry.y) { std::clog << "[Warning - Houses::loadFromXml] House entry not set for: " << house->getName() << " (" << houseId << ")" << std::endl; } if(readXMLInteger(houseNode, "townid", intValue)) house->setTownId(intValue); else house->resetSyncFlag(House::HOUSE_SYNC_TOWN); if(readXMLInteger(houseNode, "size", intValue)) house->setSize(intValue); else house->resetSyncFlag(House::HOUSE_SYNC_SIZE); if(readXMLString(houseNode, "guildhall", strValue)) house->setGuild(booleanString(strValue)); else house->resetSyncFlag(House::HOUSE_SYNC_GUILD); uint32_t rent = 0; if(readXMLInteger(houseNode, "rent", intValue)) rent = intValue; uint32_t price = (house->getSize() + house->getBedsCount()) * g_config.getNumber(ConfigManager::HOUSE_PRICE); // we should let players to pay only for walkable tiles + beds as single units not two items. if(g_config.getBool(ConfigManager::HOUSE_RENTASPRICE) && rent) price = rent; house->setPrice(price); if(g_config.getBool(ConfigManager::HOUSE_PRICEASRENT)) house->setRent(price); else house->setRent(rent); house->setOwner(0); houseNode = houseNode->next; } xmlFreeDoc(doc); return true; } void Houses::check() { uint64_t start = OTSYS_TIME(); std::clog << "> Checking houses..." << std::endl; time_t currentTime = time(NULL); for(HouseMap::iterator it = houseMap.begin(); it != houseMap.end(); ++it) payHouse(it->second, currentTime, 0); std::clog << "Houses checked in " << (OTSYS_TIME() - start) / (1000.) << " seconds." << std::endl; } bool Houses::payRent(Player* player, House* house, uint32_t bid, time_t _time/* = 0*/) { if(rentPeriod == RENTPERIOD_NEVER || !house->getOwner() || house->getPaidUntil() > _time || !house->getRent() || player->hasCustomFlag(PlayerCustomFlag_IgnoreHouseRent)) return true; Town* town = Towns::getInstance()->getTown(house->getTownId()); if(!town) return false; bool paid = false; uint32_t amount = house->getRent() + bid; if(g_config.getBool(ConfigManager::BANK_SYSTEM) && player->balance >= amount) { player->balance -= amount; paid = true; } else if(Depot* depot = player->getDepot(town->getID(), true)) paid = g_game.removeMoney(depot, amount, FLAG_NOLIMIT); if(!paid) return false; if(!_time) _time = time(NULL); uint32_t paidUntil = _time; switch(rentPeriod) { case RENTPERIOD_DAILY: paidUntil += 86400; break; case RENTPERIOD_WEEKLY: paidUntil += 7 * 86400; break; case RENTPERIOD_MONTHLY: paidUntil += 30 * 86400; break; case RENTPERIOD_YEARLY: paidUntil += 365 * 86400; break; default: break; } house->setLastWarning(0); house->setRentWarnings(0); house->setPaidUntil(paidUntil); return true; } bool Houses::payHouse(House* house, time_t _time, uint32_t bid) { if(rentPeriod == RENTPERIOD_NEVER || !house->getOwner() || house->getPaidUntil() > _time || !house->getRent()) return true; Town* town = Towns::getInstance()->getTown(house->getTownId()); if(!town) return false; uint32_t owner = house->getOwner(); if(house->isGuild() && !IOGuild::getInstance()->swapGuildIdToOwner(owner)) { house->setOwnerEx(0, true); return false; } std::string name; if(!IOLoginData::getInstance()->getNameByGuid(owner, name)) { house->setOwnerEx(0, true); return false; } Player* player = g_game.getPlayerByNameEx(name); if(!player) return false; if(!player->isPremium() && g_config.getBool(ConfigManager::HOUSE_NEED_PREMIUM)) { house->setOwnerEx(0, true); if(player->isVirtual()) delete player; return false; } int32_t loginClean = g_config.getNumber(ConfigManager::HOUSE_CLEAN_OLD); if(loginClean && _time >= (player->getLastLogin() + loginClean)) { house->setOwnerEx(0, true); if(player->isVirtual()) delete player; return false; } if(payRent(player, house, bid, _time) || _time < (house->getLastWarning() + 86400)) { if(player->isVirtual()) { IOLoginData::getInstance()->savePlayer(player); delete player; } return true; } uint32_t warningsLimit = 7; switch(rentPeriod) { case RENTPERIOD_DAILY: warningsLimit = 1; break; case RENTPERIOD_WEEKLY: warningsLimit = 3; break; case RENTPERIOD_YEARLY: warningsLimit = 14; break; default: break; } uint32_t warnings = house->getRentWarnings(); if(warnings >= warningsLimit) { house->setOwnerEx(0, true); if(player->isVirtual()) delete player; return false; } if(Depot* depot = player->getDepot(town->getID(), true)) { if(Item* letter = Item::CreateItem(ITEM_LETTER_STAMPED)) { if(g_game.internalAddItem(NULL, depot, letter, INDEX_WHEREEVER, FLAG_NOLIMIT) == RET_NOERROR) { letter->setWriter(g_config.getString(ConfigManager::SERVER_NAME)); letter->setDate(std::time(NULL)); std::stringstream s; s << "Warning!\nThe "; switch(rentPeriod) { case RENTPERIOD_DAILY: s << "daily"; break; case RENTPERIOD_WEEKLY: s << "weekly"; break; case RENTPERIOD_MONTHLY: s << "monthly"; break; case RENTPERIOD_YEARLY: s << "annual"; break; default: break; } s << " rent of " << house->getRent() << " gold for your " << (house->isGuild() ? "guild hall" : "house") << " \"" << house->getName() << "\" has to be paid. Have it within " << (warningsLimit - warnings) << " days or you will lose your " << (house->isGuild() ? "guild hall" : "house") << "."; letter->setText(s.str().c_str()); if(player->isVirtual()) IOLoginData::getInstance()->savePlayer(player); } else g_game.freeThing(letter); } } house->setLastWarning(_time); house->setRentWarnings(++warnings); if(player->isVirtual()) delete player; return false; } House* Houses::getHouse(uint32_t houseId, bool add/*= false*/) { HouseMap::iterator it = houseMap.find(houseId); if(it != houseMap.end()) return it->second; if(!add) return NULL; houseMap[houseId] = new House(houseId); return houseMap[houseId]; } House* Houses::getHouseByPlayer(Player* player) { if(!player || player->isRemoved()) return NULL; HouseTile* houseTile = player->getTile()->getHouseTile(); if(!houseTile) return NULL; if(House* house = houseTile->getHouse()) return house; return NULL; } House* Houses::getHouseByPlayerId(uint32_t playerId) { for(HouseMap::iterator it = houseMap.begin(); it != houseMap.end(); ++it) { if(!it->second->isGuild() && it->second->getOwner() == playerId) return it->second; } return NULL; } House* Houses::getHouseByGuildId(uint32_t guildId) { for(HouseMap::iterator it = houseMap.begin(); it != houseMap.end(); ++it) { if(it->second->isGuild() && it->second->getOwner() == guildId) return it->second; } return NULL; } uint32_t Houses::getHousesCount(uint32_t accId) { Account account = IOLoginData::getInstance()->loadAccount(accId); uint32_t guid, count = 0; for(Characters::iterator it = account.charList.begin(); it != account.charList.end(); ++it) { #ifndef __LOGIN_SERVER__ if(IOLoginData::getInstance()->getGuidByName(guid, (*it)) && getHouseByPlayerId(guid)) #else if(IOLoginData::getInstance()->getGuidByName(guid, (std::string&)it->first) && getHouseByPlayerId(guid)) #endif count++; } return count; } Após recompile e o server não vai mais possuir este bug xD, feliz ano novo a todos!

Informação Importante

Confirmação de Termo