Ir para conteúdo

Anderson Sacani

Membro
  • Registro em

  • Última visita

Tudo que Anderson Sacani postou

  1. São muitas informações, e tem tutoriais aqui no fórum que podem te ajudar, mas se precisar, posso te dar uma força. Me manda mensagem no privado.
  2. A função getPlayerDamageMultiplier não foi encontrada. Ela existe no teu servidor?
  3. Anderson Sacani postou uma resposta no tópico em Suporte Tibia OTServer
    No primeiro resultado ele ta tentando passar o valor 19876 para a key inexistente. Observa: (, 0, '19876') E to vendo mais possíveis problemas porque tem alguns casos que tem uma string no lugar de value, e não deveria. Deveira ser apenas INT. Pode mandar uma print da tabela global_storage para eu ver?
  4. Isso só acontece com o item custom ou acontece com qualquer outro item que tenha duração?
  5. Então faz o seguinte: No teu banco de dados procura por uma tabela com o nome de guilds ou player_guilds, algo assim. Nessa tabela me passa o nome de cada coluna existente. Não sei como está o seu banco de dados, mas estou considerando que existe a tabela "guilds" e dentro dela há as colunas "name" e "id": local function getGuildNameById(guildId) if type(guildId) ~= "number" or math.floor(guildId) ~= guildId then error("[getGuildNameById] O guildId precisa ser um numero inteiro.") end local query = db.getResult("SELECT `name` FROM `guilds` WHERE `id` = " .. guildId) if query then local guildName = query:getDataString("name") query:free() return guildName else error("[getGuildNameById] Erro ao obter nome da guilda do banco de dados.") end end function onLogin(cid) local castleGuildName = "Nenhuma Guilda Dominante" local castleGuildId = getGlobalStorageValue(123123) if castleGuildId > 0 then castleGuildName = getGuildNameById(castleGuildId) end doPlayerSendTextMessage(cid, 22, "[CASTLE24H]\nGuilda dominante: " .. castleGuildName) return true end
  6. Só adicionar isso no arquivo de login.lua: local castleGuildId = getGlobalStorageValue(123123) local guildName = getGuildNameById(castleGuildId) doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "[CASTLE24H]\nGuilda dominante: " .. guildName) Minha dúvida é, será que teu servidor possui a função "getGuildNameById"? Faça o teste e me retorne porque se precisar, eu crio essa função.
  7. Boa tarde, eu estava de bobeira e criei uma magia com base em uma skill do Metin2. A magia se chama Sword Attack. Essa magia dá dano físico em uma pequena área à sua frente e também aplica o efeito de paralyze em seus inimigos. Essa magia possui um sistema de nível, então quanto maior o nível da magia, maior será o dano, maior será a probabilidade de paralizar o inimigo e maior será o gasto de mana. Testado hoje 17/11/2023 na versão mais atual do Canary Esse é o script: local config = { --[[ * addManaSpentSystem: In Metin2, there is no magic level system based on spent mana points, commonly known as addManaSpent. If you want the magic to increase the player's magic level, leave this option as true. * limitSkillCombatLevel: In Metin2, the maximum combat level with swords that a player can reach is 90; however, in Tibia, there is no such limit. This option is used to restrict the maximum damage that the magic will deal. * damageBasedOnSkillOnly: In Metin2, the damage of spells is solely based on the player's sword skill. In Tibia, however, the damage may also include the weapon's attack. * isDamageBasedOnSwords: In Metin2, only swords exist. In Tibia, there are swords, axes, and clubs. ]] addManaSpentSystem = false, limitSkillCombatLevel = true, damageBasedOnSkillOnly = true, isDamageBasedOnSwords = true, } local combat = Combat() combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) combat:setArea(createCombatArea(AREA_WAVE6, AREADIAGONAL_WAVE6)) function onGetFormulaValues(player, skill, attack, factor) local spellLevel = player:getSpellLevelById(SPELL_SWORD_ATTACK) local formula = spellLevel >= 4 and 25.333 or spellLevel >= 3 and 19.6 or spellLevel >= 2 and 15.333 or 9.333 if config.isDamageBasedOnSwords then skill = player:getSkillLevel(SKILL_SWORD) or 1 end if config.limitSkillCombatLevel then if skill > 90 then skill = 90 end end local damage = formula * skill * attack * 0.0175 if config.damageBasedOnSkillOnly then damage = formula * skill end return -damage, -damage end combat:setCallback(CALLBACK_PARAM_SKILLVALUE, "onGetFormulaValues") local spell = Spell("instant") function spell.onCastSpell(creature, var) local player = Player(creature) local spellLevel = player:getSpellLevelById(SPELL_SWORD_ATTACK) local mana = spellLevel >= 4 and 190 or spellLevel >= 3 and 138 or spellLevel >= 2 and 100 or 46 if player:getMana() < mana then player:sendCancelMessage("Not enough mana.") return false end player:addMana(-mana) if config.addManaSpentSystem then player:addManaSpent(mana) end local paralyzeChance = spellLevel >= 4 and 30 or spellLevel >= 3 and 23 or spellLevel >= 2 and 18 or 10 local targets = combat:getTargets(creature, var) for _, target in ipairs(targets) do if target:isCreature() then local condition = Condition(CONDITION_PARALYZE) condition:setParameter(CONDITION_PARAM_TICKS, 20000) condition:setFormula(-0.9, 0, -0.9, 0) if math.random(1, 100) <= paralyzeChance then target:addCondition(condition) target:say("OH, I'M SLOW!", TALKTYPE_MONSTER_SAY) end end end return true end spell:group("attack") spell:name("Sword Attack") spell:words("exori ico immo") spell:needDirection(true) spell:cooldown(20 * 1000) spell:groupCooldown(1 * 1000) spell:needWeapon(true) spell:needLearn(true) spell:vocation("knight;true", "elite knight;true") spell:register() E aqui estão dois novos métodos que deverão adicionar à biblioteca para funcionar: SPELL_SWORD_ATTACK = 599961 function Player.getSpellLevelById(self, spellId) if self:isPlayer() then local storage = self:getStorageValue(spellId) local minValue, maxValue = 1, 4 if storage then storage = math.min(math.max(storage, minValue), maxValue) return storage else error("Invalid spellId in Player.getSpellLevelById.") end end error("Invalid player in Player.getSpellLevelById.") end function Player.setSpellLevelById(self, spellId, value) if self:isPlayer() then local minValue, maxValue = 1, 4 if value <= minValue then value = minValue elseif value >= maxValue then value = maxValue end self:setStorageValue(spellId, value) else error("Invalid player in Player.setSpellLevelById.") end end
  8. Sobre clonar os itens tu ta certo. Sempre que um jogador desloga os dados do personagem saem da memória e vão para o banco de dados. E sim, este procedimento está correto e sempre deverá ser dessa maneira por questões de performance. Ataques DDoS não fazem rollback, ou seja, não cracham o servidor, então não é um ataque DDoS. Sugiro começar a depurar tudo em algum arquivo de log para descobrir qual é a última ação antes do servidor crachar, fazendo isso tu vai saber como tão derrubando. E mais um detalhe, a pessoa que clona os itens certamente sabe como derrubar o servidor, então está fazendo de propósito.
  9. std::stringstream ss; ss << (uint64_t)gainExp; std::string expText = "EXP: " + ss.str(); g_game.addAnimatedText(getPosition(), (uint8_t)color, expText); }
  10. Já leu o nome do método? onGainSharedExperience; Tente fazer modificações também em onGainExperience; void Creature::onGainExperience(double& gainExp, bool fromMonster, bool multiplied) { if(gainExp <= 0) return; if(master) { gainExp = gainExp / 2; master->onGainExperience(gainExp, fromMonster, multiplied); } else if(!multiplied) gainExp *= g_config.getDouble(ConfigManager::RATE_EXPERIENCE); int16_t color = g_config.getNumber(ConfigManager::EXPERIENCE_COLOR); if(color < 0) color = random_range(0, 255); std::stringstream ss; ss << "Exp: " << (uint64_t)gainExp; g_game.addAnimatedText(getPosition(), (uint8_t)color, ss.str()); }
  11. Eu faria um contador utilizando a function onKill dessa maneira: function onKill(cid, target, lastHit) if isMonster(target) then local monsterName = getCreatureName(target) if monsterName == "Altaboss" then local playerKills = getPlayerStorageValue(cid, 225463) if playerKills == -1 then playerKills = 0 end setPlayerStorageValue(cid, 225463, playerKills + 1) local globalKills = getGlobalStorageValue(316141) if globalKills == -1 then globalKills = 0 end setGlobalStorageValue(316141, globalKills + 1) doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "Voce matou o Altaboss!") end end return true end E também um talkaction para conferir quantas vezes o boss já morreu: function onSay(cid, words, param) if param:lower() == "!altabosscount" then local playerKills = getPlayerStorageValue(cid, 225463) if playerKills == -1 then playerKills = 0 end local globalKills = getGlobalStorageValue(316141) if globalKills == -1 then globalKills = 0 end local message = "Voce matou o Altaboss " .. playerKills .. " vezes. " message = message .. "O Altaboss foi morto globalmente " .. globalKills .. " vezes." doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, message) end return true end
  12. Quer tirar a prova real se irá funcionar ou não? Ta aqui: function onDeath(creature, corpse, killer) local creatureName = getCreatureName(creature) print(creatureName .. " died.") if isSummon(creature) then print(creatureName .. " is a summon.") else print(creatureName .. " is not a summon.") end return true end Sempre faça depuração de um código quando há dúvidas. Registra esse script no summon e vai perceber que nenhum print aparecerá, porque ele não morre.
  13. Não vai funcionar porque summon não morre, não adianta... Pode ser o evento que for. O correto é alterar na source e fazer com que summon também morra.
  14. Eu só usaria o stopEvent caso não estivesse verificando a storage do player, nesse caso não há necessidade. E agora um detalhe muito importante: Sempre que usar addEvent com player, é bom criar condição para verificar se ele está online, caso contrário o servidor poderá crashar. local MAX_HEAL_LEVEL = 717217 local STORAGE_VALUE = 98910 local HEAL_INTERVAL = 4 * 1000 local HEAL_AMOUNT = 1000000000 local HEAL_TEXT = "|ROX|..." function doHealPlayer(cid) if not cid or not isPlayer(cid) then return true end if getPlayerStorageValue(cid, STORAGE_VALUE) == 1 then doCreatureAddHealth(cid, HEAL_AMOUNT) doPlayerAddMana(cid, HEAL_AMOUNT) doSendAnimatedText(getCreaturePos(cid), HEAL_TEXT, 138) doSendMagicEffect(getCreaturePosition(cid), 53) addEvent(doHealPlayer, HEAL_INTERVAL, cid) end return true end function onStepIn(cid, item, position, lastPosition, fromPosition) if getPlayerLevel(cid) >= MAX_HEAL_LEVEL then doPlayerSendCancel(cid, "Você já está acima do nível " .. MAX_HEAL_LEVEL .. ", portanto não será curado.") return true end setPlayerStorageValue(cid, STORAGE_VALUE, 1) doHealPlayer(getPlayerGUID(cid)) return true end function onStepOut(cid, item, position, lastPosition, fromPosition) setPlayerStorageValue(cid, STORAGE_VALUE, 0) return true end
  15. Refiz teu script: function onUse(cid, item, frompos, item2, topos) local dexsoftCoinId = 6535 if getPlayerItemCount(cid, dexsoftCoinId) < 1 then doPlayerSendCancel(cid, "Voce precisa de 1 DexSoft Coin para comprar!") return true end doPlayerRemoveItem(cid, dexsoftCoinId, 1) doPlayerAddItem(cid, 7881, 1) doSendMagicEffect(topos, 14) doBroadcastMessage("O jogador " .. getPlayerName(cid) .. " comprou donate axe", MESSAGE_STATUS_CONSOLE_BLUE) return true end
  16. Eu faria o seguinte para não precisar mexer em C++: Aumentaria a vida dele para o dobro, e quando ele estiver com metade da vida, usaria a magia para explodir, sacrificando-se e dando dano aos monstros.
  17. Nunca vai funcionar. Observem: A função se chama onDeath, e como sabemos, os summons não morrem, mas desaparecem, ou seja, são removidos. Para corrigir isto, somente em C++, ou então pensar em outra solução.
  18. Muito estranho, pois, já era pra ter funcionado em alguma das versões anteriores. Uma última tentativa: local position = { x = 33295, y = 32779, z = 7 } local ladder_id = 419 function onUse(cid, item, fromPosition, itemEx, toPosition) local tile = getTileItemById(position, ladder_id) if tile then doRemoveItem(tile.uid, 1) doSendMagicEffect(position, CONST_ME_POFF) else doCreateItem(ladder_id, 1, position) doSendMagicEffect(position, CONST_ME_MAGIC_BLUE) addEvent(function() local tile = getTileItemById(position, ladder_id) if tile then doRemoveItem(tile.uid, 1) doSendMagicEffect(position, CONST_ME_POFF) end end, 15000) end return true end Se não funcionar, provavelmente teu servidor está com algum problema na source.
  19. Qual dos efeitos aparece no sqm?
  20. Testou com a atualização do stackpos ?
  21. Só para eu entender. Pergunta 1: Quando tu aperta pela primeira vez ele já remove o piso ou cria uma escada? Pergunta 2: Se tu apertar de novo, a escada é removida junto com o piso ou somente o piso? Acredito que deve ser problema com stapos. Teste agora: local position = { x = 33295, y = 32779, z = 7, stackpos = 1 } local ladder_id = 419 function onUse(cid, item, fromPosition, itemEx, toPosition) local ladderItem = getThingfromPos(position) if ladderItem.itemid == ladder_id then doRemoveItem(ladderItem.uid, 1) doSendMagicEffect(position, CONST_ME_POFF) else doCreateItem(ladder_id, 1, position) doSendMagicEffect(position, CONST_ME_MAGIC_BLUE) addEvent(function() local ladderItem = getThingfromPos(position) if ladderItem.itemid == ladder_id then doRemoveItem(ladderItem.uid, 1) doSendMagicEffect(position, CONST_ME_POFF) end end, 15000) end return true end
  22. Testa agora: local position = { x = 33295, y = 32779, z = 7 } local ladder_id = 419 function onUse(cid, item, fromPosition, itemEx, toPosition) local ladderItem = getThingfromPos(position) if ladderItem.itemid == ladder_id then doRemoveItem(ladderItem.uid, 1) doSendMagicEffect(position, CONST_ME_POFF) else doCreateItem(ladder_id, 1, position) doSendMagicEffect(position, CONST_ME_MAGIC_BLUE) addEvent(function() local ladderItem = getThingfromPos(position) if ladderItem.itemid == ladder_id then doRemoveItem(ladderItem.uid, 1) doSendMagicEffect(position, CONST_ME_POFF) end end, 15000) end return true end
  23. Recentemente to postando bastante revscripts, entao no início do tópico eu coloco [Revscripts] manualmente mesmo, então sugiro colocar [Canary] no início.
  24. O problema provavelmente é porque não está passando o local em que será reproduzido o efeito mágico. No caso tem que ser assim: doSendMagicEffect(positions[i].pos, CONST_ME_POFF) O parâmetro que coloquei "positions[i].pos" retorna a posição criada dentro da variável positions, e como o efeito foi colocado dentro de uma estrutura de repetição, servirá para qualquer outra posição que adicionar após o primeiro índice. -- EditeD by: Yuri -- Passagem Secreta BOSS: Sunfyre the Golden local positions = { [1] = { pos = { x = 33295, y = 32779, z = 7 }, id = 419, toid = 411 } } local tempo = 15 function onUse(cid, item, frompos, item2, topos) if getTileItemById(positions[1].pos, positions[1].id).uid < 100 then doPlayerSendTextMessage(cid, 19, "Is already open.") return true end doPlayerSendTextMessage(cid, 19, "The passage will close in " .. tempo .. " seconds.") function criar_paredes(buff) for i = 1, #positions do if i <= (#positions / 2) then doCreateItem(positions[i].id, 1, positions[i].pos) doRemoveItem(obst, 1) elseif i > (#positions / 2) then local obst = getTileItemById(positions[i].pos, positions[i].toid).uid doTransformItem(obst, positions[i].id) end end return true end for i = 1, #positions do local obst = getTileItemById(positions[i].pos, positions[i].id).uid if i <= (#positions / 2) and obst ~= 0 then doRemoveItem(obst, 1) doSendMagicEffect(positions[i].pos, CONST_ME_POFF) elseif i > (#positions / 2) and obst ~= 0 then doTransformItem(obst, positions[i].toid) end end addEvent(criar_paredes, tempo * 1000) return true end Eu alterei o script que o @Aragllov passou, por tanto, o efeito só vai aparecer quando a pedra for removida. Eu deixei o script um pouco menor, porque vi muitas coisas desnecessárias: local position = { x = 33295, y = 32779, z = 7 } local ladder_id = 419 function onUse(cid, item, fromPosition, itemEx, toPosition) local ladderItem = getTileItemById(position, ladder_id) if ladderItem then doRemoveItem(ladderItem.uid, 1) doSendMagicEffect(position, CONST_ME_POFF) else doCreateItem(ladder_id, 1, position) doSendMagicEffect(position, CONST_ME_MAGIC_BLUE) addEvent(function() local ladderItem = getTileItemById(position, ladder_id) if ladderItem then doRemoveItem(ladderItem.uid, 1) doSendMagicEffect(position, CONST_ME_POFF) end end, 15000) end return true end
  25. Qual a versão do TFS e qual a versão do servidor?

Informação Importante

Confirmação de Termo