-
Anderson Sacani alterou sua foto pessoal
-
Dar item quando char pegar determinado level
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.
-
Transformar script em action
A função getPlayerDamageMultiplier não foi encontrada. Ela existe no teu servidor?
-
Erro MYSQL
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?
-
[OTX] bug com decay items, item fica infinito (do items.xml)
Isso só acontece com o item custom ou acontece com qualquer outro item que tenha duração?
-
Mostrar o dono da guild no default onLogin(cid)
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
-
Mostrar o dono da guild no default onLogin(cid)
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.
-
-
-
-
[Revscripts][Spell] Sword Attack - Metin2
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
-
Players clonando itens
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.
-
-
Botar EXP no codigo da source antes do numeros
std::stringstream ss; ss << (uint64_t)gainExp; std::string expText = "EXP: " + ss.str(); g_game.addAnimatedText(getPosition(), (uint8_t)color, expText); }
-
-
Botar EXP no codigo da source antes do numeros
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()); }
-
Contagem de quantas vezes matei o mostro (especifico)
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
-
-
[AJUDA] Summon que explode
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.
-
[AJUDA] Summon que explode
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.
-
-
Muvukaa reagiu a uma resposta no tópico: [SQLite] -=[TFS]=- 0.4 8.60 Piso solta letra |ROX|... Porem continua com efeito do piso
-
[SQLite] -=[TFS]=- 0.4 8.60 Piso solta letra |ROX|... Porem continua com efeito do piso
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
-
[SQLite] -=[TFS]=- 0.4 8.60 Puxar Alavanca e Ganhar um item ' X ' moeda. E aparece mensagem console blue azul para todos e MESSAGE_EVENT_DEFAULT tambem
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