-
Total de Posts
20 -
Registro em
-
Última visita
Tipo de Conteúdo
Perfis
Fóruns
Galeria
Downloads
Tudo que Kevin Luzetti postou
-
Skill Id perdendo xp
Kevin Luzetti postou um tópico no fórum em TFS 0.X, Compartilhe seu código C++, LUA, PHP e etc
Oi galera boa noite, estava com um problema na minha source, e resolvi ele da seguinte maneira: bool Player::onDeath() { Item* preventLoss = NULL; Item* preventDrop = NULL; if(getZone() == ZONE_PVP) { setDropLoot(LOOT_DROP_NONE); setLossSkill(false); } else if(skull < SKULL_RED && g_game.getWorldType() != WORLD_TYPE_PVP_ENFORCED) { Item* item = NULL; for(int32_t i = SLOT_FIRST; ((skillLoss || lootDrop == LOOT_DROP_FULL) && i < SLOT_LAST); ++i) { if(!(item = getInventoryItem((slots_t)i)) || (g_moveEvents->hasEquipEvent(item) && !isItemAbilityEnabled((slots_t)i))) continue; const ItemType& it = Item::items[item->getID()]; if(lootDrop == LOOT_DROP_FULL && it.abilities.preventDrop) { setDropLoot(LOOT_DROP_PREVENT); preventDrop = item; } if(skillLoss && !preventLoss && it.abilities.preventLoss) preventLoss = item; } } if(!Creature::onDeath()) { if(preventDrop) setDropLoot(LOOT_DROP_FULL); return false; } if(preventLoss) { setLossSkill(false); if(preventLoss->getCharges() > 1) //weird, but transform failed to remove for some hosters g_game.transformItem(preventLoss, preventLoss->getID(), std::max(0, ((int32_t)preventLoss->getCharges() - 1))); else g_game.internalRemoveItem(NULL, preventDrop); } if(preventDrop && preventDrop != preventLoss) { if(preventDrop->getCharges() > 1) //weird, but transform failed to remove for some hosters g_game.transformItem(preventDrop, preventDrop->getID(), std::max(0, ((int32_t)preventDrop->getCharges() - 1))); else g_game.internalRemoveItem(NULL, preventDrop); } removeConditions(CONDITIONEND_DEATH); if(skillLoss) { uint64_t lossExperience = getLostExperience(); removeExperience(lossExperience, false); double percent = 1. - ((double)(experience - lossExperience) / experience); //Magic level loss uint32_t sumMana = 0; uint64_t lostMana = 0; for(uint32_t i = 1; i <= magLevel; ++i) sumMana += vocation->getReqMana(i); sumMana += manaSpent; lostMana = (uint64_t)std::ceil(sumMana * ((double)(percent * lossPercent[LOSS_MANA]) / 100.)); while(lostMana > manaSpent && magLevel > 0) { lostMana -= manaSpent; manaSpent = vocation->getReqMana(magLevel); magLevel--; } manaSpent -= std::max((int32_t)0, (int32_t)lostMana); uint64_t nextReqMana = vocation->getReqMana(magLevel + 1); if(nextReqMana > vocation->getReqMana(magLevel)) magLevelPercent = Player::getPercentLevel(manaSpent, nextReqMana); else magLevelPercent = 0; //Skill loss uint32_t lostSkillTries, sumSkillTries; for(int16_t i = 0; i < 7; ++i) //for each skill { lostSkillTries = sumSkillTries = 0; for(uint32_t c = 11; c <= skills[i][SKILL_LEVEL]; ++c) //sum up all required tries for all skill levels sumSkillTries += vocation->getReqSkillTries(i, c); sumSkillTries += skills[i][SKILL_TRIES]; lostSkillTries = (uint32_t)std::ceil(sumSkillTries * ((double)(percent * lossPercent[LOSS_SKILLS]) / 100.)); while(lostSkillTries > skills[i][SKILL_TRIES]) { lostSkillTries -= skills[i][SKILL_TRIES]; skills[i][SKILL_TRIES] = vocation->getReqSkillTries(i, skills[i][SKILL_LEVEL]); if(skills[i][SKILL_LEVEL] < 11) { skills[i][SKILL_LEVEL] = 10; skills[i][SKILL_TRIES] = lostSkillTries = 0; break; } else skills[i][SKILL_LEVEL]--; } skills[i][SKILL_TRIES] = std::max((int32_t)0, (int32_t)(skills[i][SKILL_TRIES] - lostSkillTries)); } blessings = 0; loginPosition = masterPosition; if(!inventory[SLOT_BACKPACK]) __internalAddThing(SLOT_BACKPACK, Item::CreateItem(g_config.getNumber(ConfigManager::DEATH_CONTAINER))); sendIcons(); sendStats(); sendSkills(); sendReLoginWindow(); g_game.removeCreature(this, false); } else { setLossSkill(true); if(preventLoss) { loginPosition = masterPosition; sendReLoginWindow(); g_game.removeCreature(this, false); } } return true; } substitui essa parte: for(int16_t i = 0; i < 7; ++i) //for each skill { lostSkillTries = sumSkillTries = 0; for(uint32_t c = 11; c <= skills[i][SKILL_LEVEL]; ++c) //sum up all required tries for all skill levels sumSkillTries += vocation->getReqSkillTries(i, c); sumSkillTries += skills[i][SKILL_TRIES]; lostSkillTries = (uint32_t)std::ceil(sumSkillTries * ((double)(percent * lossPercent[LOSS_SKILLS]) / 100.)); while(lostSkillTries > skills[i][SKILL_TRIES]) { lostSkillTries -= skills[i][SKILL_TRIES]; skills[i][SKILL_TRIES] = vocation->getReqSkillTries(i, skills[i][SKILL_LEVEL]); if(skills[i][SKILL_LEVEL] < 11) { skills[i][SKILL_LEVEL] = 10; skills[i][SKILL_TRIES] = lostSkillTries = 0; break; } else skills[i][SKILL_LEVEL]--; } skills[i][SKILL_TRIES] = std::max((int32_t)0, (int32_t)(skills[i][SKILL_TRIES] - lostSkillTries)); } por essa: for(int16_t i = 0; i < 7; ++i) // for each skill { // Protege as skills 3 (Fishing), 4 (Shielding) e 6 (Headbutt/Torneio) if(i == 3 || i == 4 || i == 6) continue; lostSkillTries = sumSkillTries = 0; for(uint32_t c = 11; c <= skills[i][SKILL_LEVEL]; ++c) sumSkillTries += vocation->getReqSkillTries(i, c); sumSkillTries += skills[i][SKILL_TRIES]; lostSkillTries = (uint32_t)std::ceil(sumSkillTries * ((double)(percent * lossPercent[LOSS_SKILLS]) / 100.)); while(lostSkillTries > skills[i][SKILL_TRIES]) { lostSkillTries -= skills[i][SKILL_TRIES]; skills[i][SKILL_TRIES] = vocation->getReqSkillTries(i, skills[i][SKILL_LEVEL]); if(skills[i][SKILL_LEVEL] < 11) { skills[i][SKILL_LEVEL] = 10; skills[i][SKILL_TRIES] = lostSkillTries = 0; break; } else { skills[i][SKILL_LEVEL]--; } } skills[i][SKILL_TRIES] = std::max((int32_t)0, (int32_t)(skills[i][SKILL_TRIES] - lostSkillTries)); } no meu caso coloquei pra skills 3 4 e 6 n perderem xp bom é isso. -
lançamento Drunken Wanderer Pokemon
Kevin Luzetti postou um tópico no fórum em TFS 0.X, Compartilhe seu código C++, LUA, PHP e etc
Este sistema faz com que, ao pisar em um tile específico, o Pokémon summon entre em um estado temporário de "embriaguez" por 30 segundos. Durante esse período, o Pokémon se movimenta de forma aleatória e emite frases engraçadas a cada 2 segundos, simulando um comportamento instável e descontraído. O efeito é controlado por uma variável interna que indica quando o Pokémon está sob essa condição. O estado de "bêbado" dura o tempo total estipulado (30 segundos), independentemente de o Pokémon permanecer sobre o tile ou não. Caso ele saia do tile, o efeito continua até seu término natural. Se o Pokémon voltar a pisar no tile depois que o efeito terminar, ele receberá o efeito novamente. local drunkPhrases = { "Hic! Isso é suco de berry?", "Wobba wobba wobba!", "Onde tá meu treinador?!", "Eu vejo dois Pikachus... ou três...", "Esse chão tá girando..." } local DRUNK_DURATION = 30 -- segundos local INTERVAL = 2 -- segundos local STORAGE_DRUNK = 25887 function isWalkable(pos) local tile = getTileThingByPos(pos) if tile.itemid == 0 or hasProperty(tile.uid, CONST_PROP_BLOCKSOLID) then return false end if getTopCreature(pos).uid > 0 then return false end return true end function getRandomWalkablePos(pos) local directions = { {x = pos.x + 1, y = pos.y, z = pos.z}, {x = pos.x - 1, y = pos.y, z = pos.z}, {x = pos.x, y = pos.y + 1, z = pos.z}, {x = pos.x, y = pos.y - 1, z = pos.z} } local valid = {} for _, newPos in ipairs(directions) do if isWalkable(newPos) then table.insert(valid, newPos) end end if #valid > 0 then return valid[math.random(#valid)] else return nil end end function simulateDrunkBehavior(cid, ticks) if not isCreature(cid) or getCreatureStorage(cid, STORAGE_DRUNK) ~= 1 then return end if ticks <= 0 then doCreatureSetStorage(cid, STORAGE_DRUNK, 0) return end doCreatureSay(cid, drunkPhrases[math.random(#drunkPhrases)], TALKTYPE_MONSTER) local currentPos = getThingPos(cid) local newPos = getRandomWalkablePos(currentPos) if newPos then doTeleportThing(cid, newPos, true) end addEvent(simulateDrunkBehavior, INTERVAL * 1000, cid, ticks - 1) end function onStepIn(cid, item, pos) if isSummon(cid) and getCreatureStorage(cid, STORAGE_DRUNK) ~= 1 then doCreatureSetStorage(cid, STORAGE_DRUNK, 1) simulateDrunkBehavior(cid, math.floor(DRUNK_DURATION / INTERVAL)) print("[DEBUG] " .. getCreatureName(cid) .. " ficou bêbado (summon).") end return true end function onStepOut(cid, item, pos) if isSummon(cid) and getCreatureStorage(cid, STORAGE_DRUNK) == 1 then doCreatureSetStorage(cid, STORAGE_DRUNK, 0) print("[DEBUG] " .. getCreatureName(cid) .. " saiu do efeito bêbado (summon).") end return true end <movevent type="StepIn" actionid="5013" event="script" value="beldo.lua"/> Também coloquei pra que caso ele receba esse DRUNK ele não consiga utilizar os ataques, então em move1.lua vocês coloquem. if getCreatureStorage(mypoke, 25887) == 1 then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_RED, "Seu Pokémon está tonto e não pode usar esse movimento.") return true -- bloqueia o uso do movimento end -
problema com nature system
Kevin Luzetti respondeu ao tópico de seilaeusou em Suporte C++, LUA E etc
Antes do loop, adicione um print e uma verificação de segurança if not nature then print("Erro: nature é nil. Verifique se está sendo atribuída corretamente.") return false -- Interrompe a execução para evitar mais erros end Se nature vier de uma storage, garanta que ela não seja -1 antes de prosseguir: nature = getPlayerStorageValue(pk, STORAGE_NATURE) if not nature or nature == -1 then print("Erro: Natureza do Pokémon não definida!") return false end -
problema com nature system
Kevin Luzetti respondeu ao tópico de seilaeusou em Suporte C++, LUA E etc
tente isso: for i = 1, 5 do if NATURE_TABLE_SYSTEM[nature] then local nature_data = NATURE_TABLE_SYSTEM[nature] local operator = nature_data.list_operator[i] local bonus = nature_data.list[i] if operator == "+" then setPlayerStorageValue(pk, 1000 + i, getPlayerStorageValue(pk, 1000 + i) + bonus) elseif operator == "-" then setPlayerStorageValue(pk, 1000 + i, getPlayerStorageValue(pk, 1000 + i) - bonus) elseif operator == "*" then setPlayerStorageValue(pk, 1000 + i, getPlayerStorageValue(pk, 1000 + i) * bonus) end else -- Caso não encontre a nature, pode exibir um erro ou retornar um valor padrão print("Nature não encontrada: " .. nature) end end -
VÁ ATÉ CREATURESCRIPT CRIE UM LUA E COLOQUE: local healingStoneID = 10559 local healAmount = 1000000000 -- 1 bilhão de HP/MP local cooldownReduction = 100 -- Redução de 100ms -- Função para reduzir cooldown das spells local function reduceCooldowns(cid) if not isPlayer(cid) then return end for spell, info in pairs(getPlayerInstantSpellInfo(cid)) do local currentCooldown = getPlayerSpellCooldown(cid, spell) if currentCooldown > 0 then local newCooldown = math.max(0, currentCooldown - (cooldownReduction / 1000)) -- Convertendo para segundos doPlayerSetSpellCooldown(cid, spell, newCooldown) end end end function onThink(cid, interval) if not isPlayer(cid) then return true end if getPlayerItemCount(cid, healingStoneID) > 0 then doCreatureAddHealth(cid, healAmount) doCreatureAddMana(cid, healAmount) doSendMagicEffect(getThingPos(cid), CONST_ME_MAGIC_BLUE) doSendAnimatedText(getThingPos(cid), "FULL HEAL!", TEXTCOLOR_GREEN) -- Reduz o cooldown chamando a função reduceCooldowns(cid) end return true end NO XML: <event type="think" name="HealingStone" script="healing_stone.lua"/> E REGISTRA EM onLogin...NÃO SEI SE EM 8.60 TEM login.lua, PORÉM SE TIVER COLOCA LA ISSO: registerCreatureEvent(cid, "HealingStone")
-
pokemon Spawn de Pokémon Dinâmico: Encontros Inesperados Baseados no Horário!
Kevin Luzetti postou um tópico no fórum em Tfs 0.x ( forgottenserver )
Oi! Vou explicar o funcionamento desse sistema como se eu fosse o responsável por ele. Vamos lá! Apresentação do Sistema de Spawn de Pokémon (Local Pokes) Esse sistema que você está vendo foi desenvolvido para adicionar um toque especial ao mundo de PokéTibia, trazendo uma experiência única para os jogadores. O principal objetivo é criar momentos inesperados e emocionantes ao fazer com que Pokémon sejam "spawnados" perto do jogador, mas com uma chance variável dependendo do horário do dia! Quando um jogador se aproxima de uma área específica, o código entra em ação, verificando algumas condições para ver se o Pokémon pode ou não aparecer. As condições incluem verificações se o jogador já tem Pokémon, se está em uma missão ou se não é uma invocação de outro NPC, garantindo que o spawn aconteça em momentos apropriados. Horário é tudo! Cada momento do dia traz uma oportunidade diferente de captura. Durante a madrugada (00:00 - 03:00), por exemplo, há uma chance maior de aparecer Ditto, enquanto Zorua e Zoroark são mais difíceis de encontrar, porque a noite traz maior tensão e mistério, certo? Já na noite tardia, entre 19:00 e 19:44, a chance de ver um Pokémon desses aumenta drasticamente, chegando quase a 100%! É o tipo de "surpresa" que um bom treinador de Pokémon adora encontrar. Como funciona o Spawn? O sistema usa um sorteio baseado no horário e uma chance aleatória. Caso a sorte esteja ao lado do jogador, um Pokémon é criado instantaneamente e aparece ao seu lado! O Pokémon pode ser Zorua, Zoroark ou Ditto, e o mais interessante é que ele vai assumir a mesma aparência do Pokémon do treinador que o encontrou, o que dá um toque especial à captura. Além disso, o Pokémon spawnado também recebe algumas características do jogador, como o nome, e ele desaparece assim que a ação termina — um processo fluido que mantém o jogo dinâmico e emocionante! Por fim, se o Pokémon não aparecer, o código mantém tudo em ordem, registrando que o evento ocorreu e configurando a chance para a próxima rodada de possíveis encontros. E se nada acontecer? Simplesmente, a chance de spawn será registrada para o jogador, e ele pode tentar novamente em outro momento! O sistema garante que, mesmo quando não há sorte, o ambiente ainda esteja sempre preparado para novos encontros. A ideia é sempre dar aquele frio na barriga, onde o jogador nunca sabe exatamente o que vai acontecer a seguir. Isso mantém o jogo instigante, desafiador e muito mais envolvente! Então, basicamente, é um sistema dinâmico, que leva em conta o tempo, as condições do jogador e a diversão imprevisível de encontrar Pokémon diferentes no caminho. Como qualquer bom mistério Pokémon, você nunca sabe o que esperar, mas com certeza vai ser emocionante! OBSERVAÇÃO: TESTADO VARIAS VEZES EM TFS 0.3.6 Em: Creaturescripts/scripts/spawn.lua Procure por: local function doShiny(cid) Abaixo dessa função adicione o seguinte: local function doLocalPokesSpaw(cid) if isCreature(cid) then if isSummon(cid) then return true end if getPlayerStorageValue(cid, 74469) >= 1 then return true end if getPlayerStorageValue(cid, 22546) >= 1 then return true end if isNpcSummon(cid) then return true end if getPlayerStorageValue(cid, 637500) >= 1 then return true end --alterado v1.9 local chance = 0 -- Manhã, Zorua e Zoroark difíceis, Ditto mais fácil if os.date("%X") >= "00:00:00" and os.date("%X") <= "03:00:00" then chance = 0.30 -- Noite, Zorua e Zoroark fáceis, Ditto mais difícil elseif os.date("%X") >= "03:01:00" and os.date("%X") <= "05:00:00" then chance = 0.25 -- Manhã, Zorua e Zoroark difíceis, Ditto mais fácil elseif os.date("%X") >= "05:01:00" and os.date("%X") <= "07:00:00" then chance = 0.20 -- Tarde, Zorua e Zoroark difíceis, Ditto mais fácil elseif os.date("%X") >= "07:00:00" and os.date("%X") <= "09:00:00" then chance = 0.15 -- Tarde, Zorua e Zoroark difíceis, Ditto mais fácil elseif os.date("%X") >= "09:01:00" and os.date("%X") <= "12:00:00" then chance = 0.10 -- Tarde, Zorua e Zoroark difíceis, Ditto mais fácil elseif os.date("%X") >= "12:01:00" and os.date("%X") <= "14:00:00" then chance = 0.05 -- Final da tarde, Zorua e Zoroark difíceis, Ditto mais fácil elseif os.date("%X") >= "14:01:00" and os.date("%X") <= "16:00:00" then chance = 0.10 -- Noite, Zorua e Zoroark fáceis, Ditto mais difícil elseif os.date("%X") >= "16:01:00" and os.date("%X") <= "18:00:00" then chance = 0.10 -- Zorua e Zoroark mais fáceis à noite elseif os.date("%X") >= "18:01:00" and os.date("%X") <= "19:00:00" then chance = 0.75 -- Zorua e Zoroark mais fáceis, Ditto mais difícil elseif os.date("%X") >= "19:01:00" and os.date("%X") <= "20:00:00" then chance = 1.5 -- Zorua e Zoroark mais fáceis, Ditto mais difícil elseif os.date("%X") >= "20:01:00" and os.date("%X") <= "22:00:00" then chance = 0.25 -- Zorua e Zoroark mais fáceis à noite elseif os.date("%X") >= "22:01:00" and os.date("%X") <= "23:59:59" then chance = 0.80 else chance = 0 end local test = math.random(1, 20000) if test <= chance * 5 then doSendMagicEffect(getThingPos(cid), 18) local lvl = math.random(10, 30) local pos = getThingPos(cid) local possibleSpawns = {"Zorua", "Zoroark", "Ditto"} local name = possibleSpawns[math.random(1, #possibleSpawns)] local shi = doCreateMonster(name, pos , false) doSetCreatureOutfit(shi, getCreatureOutfit(cid), -1) doCreatureSetNick(shi, getCreatureName(cid)) doRemoveCreature(cid) setPlayerStorageValue(shi, 74469, 1) print("Um " .. name .. " foi spawnado em X=" .. pos.x .. " Y=" .. pos.y .. " Z=" .. pos.z) else setPlayerStorageValue(cid, 74469, 1) end else return true end end Logo em seguida procure por: if isSummon(cid) then registerCreatureEvent(cid, "SummonDeath") return true end E abaixo dele coloque: addEvent(doLocalPokesSpaw, 10, cid) Feito isso, sempre que for iniciar o servidor irá aparecer um print nas posições de spawn dos pokémons da função, sendo eles: Zorua, Zoroark, Ditto, ajuste os horarios como quiserem e as % a seus gostos. Sistema de Zorua feito por Marshmello, eu apenas fiz alterações pra mais de um pokémon. -
actions [ACTIONS] Abertura com quantidade
Kevin Luzetti postou um tópico no fórum em Tfs 0.x ( forgottenserver )
🔓 Missão de Resgate: Salve os Slowpokes! 🔓 🐾 Os Slowpokes estão em apuros! Eles foram capturados e trancados em jaulas. Sua missão? Libertá-los antes que seja tarde demais! ✨ Como funciona? 🔑 Use uma chave especial para abrir as jaulas. 🐢 Cada vez que resgata um Slowpoke, seu progresso é registrado. 📊 Você recebe atualizações sobre quantos já foram libertos. 🎁 Quando todos estiverem a salvo, uma recompensa especial espera por você! 💡 Por que adicionar esse sistema? ✔ Torna a jornada do jogador mais envolvente. ✔ Cria um senso de progresso e realização. ✔ Perfeito para eventos temáticos ou missões especiais! 📜 Código completo abaixo! Se precisar de ajustes ou ideias, só chamar. 🚀 LUA local itemChave = 12231 local itemJaula = 25767 local jaulaAberta = 25771 local quantidadeParaAbrir = 30 local storageInicial = 30602 local rewardSto = 30603 function onUse(cid, item, fromPosition, itemEx, toPosition) if item.itemid ~= itemChave or itemEx.itemid ~= itemJaula then return false end local quantidadeAberta = getPlayerStorageValue(cid, storageInicial) if quantidadeAberta < 0 then quantidadeAberta = 0 end doTransformItem(itemEx.uid, jaulaAberta) quantidadeAberta = quantidadeAberta + 1 setPlayerStorageValue(cid, storageInicial, quantidadeAberta) doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Você libertou um Slowpoke da armadilha! Até agora, você ja resgatou " .. quantidadeAberta .. " de " .. quantidadeParaAbrir .. ". Continue abrindo as jaulas para salvar todos!") if quantidadeAberta >= quantidadeParaAbrir then if getPlayerStorageValue(cid, rewardSto) ~= 1 then setPlayerStorageValue(cid, rewardSto, 1) doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "Parabéns! Você resgatou todos os Slowpoke e impediu que fossem capturados! Sua recompensa aguarda.") end end return true end XML <action itemid="12231" script="contador.lua"/> obrigado a todos, espero que façam bom proveito. -
Item que dobra a chance de captura
Kevin Luzetti respondeu ao tópico de seilaeusou em Pedidos de códigos LUA, C++ etc.
Olá boa noite, segue o que pediu: Crie uma actions nova e coloque isso dentro local BOOST_ITEM_ID = 12231 -- ID do item de booster local BOOST_STORAGE = 912361 -- Storage do tempo do boost local BOOST_DURATION = 1800 -- Tempo de duração do boost (em segundos) local BONUS_PERCENT = 10 -- Porcentagem de aumento na captura function onUse(cid, item, frompos, itemEx, topos) local currentTime = os.time() local boostEnd = getPlayerStorageValue(cid, BOOST_STORAGE) -- Se o bônus estiver ativo, avisa o jogador if boostEnd > currentTime then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Você já tem um bônus ativo!") return true end -- Ativa o bônus e define a expiração do bônus setPlayerStorageValue(cid, BOOST_STORAGE, currentTime + BOOST_DURATION) doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Você ativou um bônus de captura por 30 minutos!") doSendMagicEffect(getCreaturePosition(cid), CONST_ME_MAGIC_BLUE) doRemoveItem(item.uid, 1) -- Remove o item após uso -- Define um evento para remover o bônus após 5 segundos addEvent(function() local currentTime = os.time() local boostEnd = getPlayerStorageValue(cid, BOOST_STORAGE) -- Verifica se o bônus expirou if boostEnd > 0 and boostEnd <= currentTime then setPlayerStorageValue(cid, BOOST_STORAGE, -1) -- Limpa o storage (sem bônus) doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Seu bônus de captura expirou.") end end, BOOST_DURATION * 1000) -- O evento será executado após o tempo de BOOST_DURATION (5 segundos) return true end No seu catch.lua coloque isso local boostStorage = 912361 local bonusPercent = 10 -
npc NPC TRUCO
Kevin Luzetti postou um tópico no fórum em TFS 0.X, Compartilhe seu código C++, LUA, PHP e etc
🎴 Apresentação do NPC - Jogo de Cartas 🎴 🤵♂️ "Aposte sua sorte contra mim e veja se consegue vencer no truco!" Este NPC é um desafiante habilidoso que convida os jogadores para uma partida de cartas. Ele inicia um jogo dinâmico onde estratégia e sorte se combinam para decidir o vencedor! 🃏 Regras do Jogo: ✅ Cada jogador recebe 3 cartas aleatórias. ✅ As cartas possuem hierarquia de força, e algumas vencem outras. ✅ Aposta inicial é 1x, mas pode ser aumentada com "truco"! ✅ Uma carta coringa pode mudar o rumo da partida. ✅ O jogo termina quando todas as cartas forem jogadas! 💬 Comandos principais: 🔹 "iniciar" - Começa uma nova partida. 🔹 "jogar carta <número> de <naipe>" - Joga uma carta. 🔹 "truco" - Aumenta a aposta! 🔹 "regras" - Exibe as regras do jogo. 🔹 "proxima" - Começa uma nova rodada. 🔹 "bye" - Sai do jogo. 🎲 Você tem coragem de desafiar este NPC? Teste sua sorte e estratégia agora! local keywordHandler = KeywordHandler:new() local npcHandler = NpcHandler:new(keywordHandler) NpcSystem.parseParameters(npcHandler) local talkState = {} local playerGames = {} -- Armazenar o estado do jogo para cada jogador -- Cartas e suas descrições local cardNames = {"zap", "copas", "ouro", "espada"} local cardNumbers = {1, 2, 3, 4} -- Prefixos possíveis para o nome do NPC local npcPrefixes = {"- Kevin", "- Max", "- Alex", "- Mike"} -- Função para obter um número de carta correspondente ao nome local function getCardNumber(name) for i, cardName in ipairs(cardNames) do if cardName == name then return cardNumbers[i] end end return nil end -- Função para obter o nome da carta a partir do número local function getCardName(number) for i, cardNumber in ipairs(cardNumbers) do if cardNumber == number then return cardNames[i] end end return nil end -- Função para obter uma carta aleatória local function getRandomCard() local index = math.random(#cardNames) return cardNumbers[index], cardNames[index] end -- Função para obter um prefixo aleatório para o NPC local function getRandomPrefix() return npcPrefixes[math.random(#npcPrefixes)] end -- Inicializa o jogo local function initializeGame(cid) local npcPrefix = getRandomPrefix() -- Gera um prefixo aleatório local cardDeck = {} for _, cardNumber in ipairs(cardNumbers) do for _, cardName in ipairs(cardNames) do table.insert(cardDeck, {number = cardNumber, name = cardName}) end end -- Embaralhar cartas for i = #cardDeck, 2, -1 do local j = math.random(i) cardDeck[i], cardDeck[j] = cardDeck[j], cardDeck[i] end local playerHand = {table.remove(cardDeck, 1), table.remove(cardDeck, 1), table.remove(cardDeck, 1)} local npcHand = {table.remove(cardDeck, 1), table.remove(cardDeck, 1), table.remove(cardDeck, 1)} local jokerCardNumber, jokerCardName = getRandomCard() -- Verifique se getRandomCard retorna valores válidos if not jokerCardNumber or not jokerCardName then selfSay(npcPrefix .. ": Erro ao sortear a carta coringa. Por favor, tente novamente.", cid) return end local jokerCard = {number = jokerCardNumber, name = jokerCardName} playerGames[cid] = { playerHand = playerHand, npcHand = npcHand, jokerCard = jokerCard, -- Carta coringa currentMultiplier = 1, -- Multiplicador inicial npcPrefix = npcPrefix -- Armazenar o prefixo gerado } -- Informar sobre a carta coringa sorteada selfSay(npcPrefix .. ": A carta coringa sorteada é " .. jokerCard.number .. " de " .. jokerCard.name .. ".", cid) end -- Converte uma mão de cartas em uma string local function handToString(hand) local handString = "" for _, card in ipairs(hand) do handString = handString .. card.number .. " de " .. card.name .. ", " end return handString:sub(1, -3) -- Remove a última vírgula e espaço end local function determineWinner(playerCard, npcCard) -- Carta 4 vence todas as outras cartas if playerCard.number == 4 then return "player" elseif npcCard.number == 4 then return "npc" -- Carta 3 vence Carta 2 e Carta 1 elseif playerCard.number == 3 then return (npcCard.number == 1 or npcCard.number == 2) and "player" or "npc" elseif npcCard.number == 3 then return (playerCard.number == 1 or playerCard.number == 2) and "npc" or "player" -- Carta 2 vence Carta 1 elseif playerCard.number == 2 then return (npcCard.number == 1) and "player" or "npc" elseif npcCard.number == 2 then return (playerCard.number == 1) and "npc" or "player" -- Carta 1 perde para todas as outras cartas elseif playerCard.number == 1 then return "npc" elseif npcCard.number == 1 then return "player" end -- Comparar naipes se os números forem iguais if playerCard.number == npcCard.number then return compareSuits(playerCard.name, npcCard.name) and "player" or "npc" end end local function npcDecide() local actions = {"accept", "increase", "run"} -- Define as probabilidades para cada ação (soma deve ser 100) local probabilities = {80, 10, 10} local randomChance = math.random(100) local cumulativeChance = 0 for i, action in ipairs(actions) do cumulativeChance = cumulativeChance + probabilities[i] if randomChance <= cumulativeChance then if action == "increase" then local npcTrucoPhrase = playerTrucoPhrases[math.random(#playerTrucoPhrases)] selfSay(npcTrucoPhrase:format(game.currentMultiplier * 2), cid) end return action end end end -- Função para resolver uma rodada e verificar se o jogo terminou local function resolveRound(cid, multiplier, chosenCardNumber, chosenCardName) local game = playerGames[cid] local npcPrefix = game.npcPrefix -- Verifique se o jogo está definido if not game then selfSay(npcPrefix .. ": Erro no jogo. O jogo não foi iniciado corretamente.", cid) return false end -- Encontrar o índice da carta escolhida na mão do jogador local playerCardIndex = nil for i, card in ipairs(game.playerHand) do if card.number == chosenCardNumber and card.name == chosenCardName then playerCardIndex = i break end end -- Verificar se a carta escolhida está na mão do jogador if not playerCardIndex then selfSay(npcPrefix .. ": Você não tem essa carta. Escolha uma carta válida.", cid) return false end -- Remover a carta escolhida da mão do jogador local playerCard = table.remove(game.playerHand, playerCardIndex) -- Selecionar uma carta aleatória para o NPC local npcCard = game.npcHand[math.random(#game.npcHand)] -- Exibir as cartas jogadas selfSay(npcPrefix .. ": Você jogou: " .. playerCard.number .. " de " .. playerCard.name .. ".", cid) selfSay(npcPrefix .. ": Eu joguei: " .. npcCard.number .. " de " .. npcCard.name .. ".", cid) -- Verificar a vitória com base na lógica definida if playerCard.number == game.jokerCard.number and playerCard.name == game.jokerCard.name then selfSay(npcPrefix .. ": Você jogou o valete (coringa) e ganhou automaticamente esta rodada!", cid) elseif npcCard.number == game.jokerCard.number and npcCard.name == game.jokerCard.name then selfSay(npcPrefix .. ": Eu joguei o valete (coringa) e ganhei automaticamente esta rodada!", cid) elseif determineWinner(playerCard, npcCard) == "player" then selfSay(npcPrefix .. ": Você venceu esta rodada. Vamos continuar. Diga 'proxima' para uma nova rodada!", cid) else selfSay(npcPrefix .. ": Eu venci esta rodada. Vamos continuar. Diga 'proxima' para uma nova rodada!", cid) end -- Verificar se alguém ganhou o jogo if #game.playerHand == 0 and #game.npcHand == 0 then selfSay(npcPrefix .. ": A partida acabou. Diga 'próxima' para começar um novo jogo ou 'bye' para encerrar.", cid) endGame(cid) return true end end -- Frases aleatórias para quando o NPC aumenta a aposta local trucoPhrases = { "Desafio aceito! A aposta é agora de %dx.", "Ótimo! Aposta elevada para %dx!", "Vamos lá, a aposta agora é de %dx!", "Aposta dobrada! Agora está em %dx.", "Você quer jogar pesado! Aposta ajustada para %dx." } -- Frases aleatórias para quando o jogador pede truco local playerTrucoPhrases = { "Você quer aumentar a aposta? Muito bem, a nova aposta é %dx!", "Aposta aumentada! Está agora em %dx.", "Você está apostando alto! Agora é %dx.", "Aposte mais se conseguir! O novo valor é %dx.", "Aposta ajustada para %dx, vamos ver o que você tem!" } -- Função para finalizar o jogo e limpar o estado local function endGame(cid) playerGames[cid] = nil end function onCreatureAppear(cid) npcHandler:onCreatureAppear(cid) end function onCreatureDisappear(cid) npcHandler:onCreatureDisappear(cid) end function onCreatureSay(cid, type, msg) npcHandler:onCreatureSay(cid, type, msg) end function onThink() npcHandler:onThink() end function creatureSayCallback(cid, type, msg) if not npcHandler:isFocused(cid) then return false end local state = talkState[cid] if state == nil then state = {} talkState[cid] = state end local game = playerGames[cid] -- Exibe as regras do jogo if msg == "regras" then selfSay("Regras do Jogo:\n1. O jogo é uma disputa de cartas entre você e o NPC.\n2. Cada jogador começa com 3 cartas.\n3. A carta 4 vence todas as outras.\n4. A carta 3 vence as cartas 1 e 2.\n5. A carta 2 vence a carta 1.\n6. A carta 1 perde para todas as outras.\n7. Se as cartas tiverem o mesmo número, o naipe decide.\n8. Aposta inicial é 1x, mas você pode aumentar dizendo 'truco'.\n9. O jogo termina quando todas as cartas são jogadas. Boa sorte!", cid) return true end -- Inicia o jogo if msg == "iniciar" then initializeGame(cid) local handDescription = "Suas cartas são: " .. handToString(playerGames[cid].playerHand) selfSay(playerGames[cid].npcPrefix .. ": " .. handDescription .. ". Diga 'jogar carta <número> de <naipe>' para jogar uma carta ou 'truco' para aumentar a aposta.", cid) return true end -- Verifica se o jogador quer jogar uma carta local playCardPattern = "jogar carta (%d) de (%a+)" local chosenCardNumber, chosenCardName = msg:match(playCardPattern) if chosenCardNumber and chosenCardName then chosenCardNumber = tonumber(chosenCardNumber) return resolveRound(cid, game.currentMultiplier, chosenCardNumber, chosenCardName) end -- Função para tratar o aumento da aposta if msg == "truco" then local maxMultiplier = 12 local increment = 3 -- Verifica se a aposta está no valor inicial (1 ponto) ou já foi aumentada if game.currentMultiplier == 1 then game.currentMultiplier = 3 else local nextMultiplier = game.currentMultiplier + increment -- Verifica se o próximo valor da aposta não excede o máximo permitido if nextMultiplier <= maxMultiplier then game.currentMultiplier = nextMultiplier else selfSay(game.npcPrefix .. ": O máximo de aposta já foi atingido.", cid) return true end end -- Exibe a frase com o novo valor da aposta local trucoPhrase = trucoPhrases[math.random(#trucoPhrases)] selfSay(trucoPhrase:format(game.currentMultiplier), cid) return true end -- Verifica se o jogador quer terminar o jogo if msg == "bye" then selfSay(game.npcPrefix .. ": Obrigado por jogar! Até a próxima.", cid) endGame(cid) npcHandler:releaseFocus(cid) return true end -- Verifica se o jogador quer iniciar uma nova partida if msg == "proxima" then initializeGame(cid) local handDescription = "Suas cartas são: " .. handToString(playerGames[cid].playerHand) selfSay(playerGames[cid].npcPrefix .. ": " .. handDescription .. ". Diga 'jogar carta <número> de <naipe>' para jogar uma carta ou 'truco' para aumentar a aposta.", cid) return true end return true end npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) npcHandler:addModule(FocusModule:new()) -
reward Login Diário
Kevin Luzetti postou um tópico no fórum em TFS 0.X, Compartilhe seu código C++, LUA, PHP e etc
Olá hoje trago a voces um sistema de login diario feito diretamete em login.lua...vamos la. em login.lua antes de onLogin(cid) coloque: local STORAGE_LOGIN_DAYS = 50012 -- Armazena o número de dias de login do jogador local STORAGE_LAST_LOGIN = 50013 -- Armazena a data do último login do jogador -- Número máximo de dias para o prêmio de login antes de resetar local MAX_LOGIN_DAYS = 30 -- Tabela de prêmios diários. Cada entrada representa um dia com um item e uma quantidade local dailyRewards = { {itemId = 2148, count = 100}, -- Exemplo: 100 gold coins no Dia 1 {itemId = 2152, count = 10}, -- Exemplo: 10 platinum coins no Dia 2 {itemId = 2160, count = 1}, -- Exemplo: 1 crystal coin no Dia 3 {itemId = 7632, count = 5}, -- Exemplo: 5 health potions no Dia 4 {itemId = 7620, count = 3}, -- Exemplo: 3 mana potions no Dia 5 -- Adicione mais dias e prêmios aqui até o dia 30 } -- Função para dar o prêmio do dia específico ao jogador local function giveDailyReward(cid, day) local reward = dailyRewards[day] if reward then local itemName = getItemNameById(reward.itemId) -- Obtém o nome do item doPlayerAddItem(cid, reward.itemId, reward.count) -- Exibe uma mensagem animada de recompensa de login local playerPosition = getCreaturePosition(cid) doSendAnimatedText(playerPosition, "Login Reward!", TEXTCOLOR_GREEN) doSendMagicEffect(playerPosition, CONST_ME_GIFT_WRAPS) doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Você recebeu um prêmio de login: " .. reward.count .. " unidades de " .. itemName .. "!") else print("Erro: prêmio para o dia " .. day .. " não encontrado.") end end Antes do return true do arquivo coloque: local lastLoginDate = getPlayerStorageValue(cid, STORAGE_LAST_LOGIN) local currentDate = os.time() if lastLoginDate <= 0 or os.difftime(currentDate, lastLoginDate) >= 86400 then local loginDays = getPlayerStorageValue(cid, STORAGE_LOGIN_DAYS) if loginDays < 0 then loginDays = 0 end if lastLoginDate > 0 and os.difftime(currentDate, lastLoginDate) > 86400 then loginDays = 0 doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Você perdeu a sequência de login diária. A sequência foi reiniciada.") end loginDays = loginDays + 1 if loginDays > MAX_LOGIN_DAYS then loginDays = 1 doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Você completou 30 dias de login! A sequência foi reiniciada.") end setPlayerStorageValue(cid, STORAGE_LOGIN_DAYS, loginDays) setPlayerStorageValue(cid, STORAGE_LAST_LOGIN, currentDate) giveDailyReward(cid, loginDays) else doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Bem-vindo de volta! Você já recebeu o prêmio de login nas últimas 24 horas.") end VAMOS AS EXPLICAÇÕES: ESSE SITEMA VAI ARMAZENANDO OS DIAS QUE VOCÊ ENTRA NO GAME, CASO NÃO ENTRE UM DIA ELE RESETA OS DIAS VOLTANDO DO 1º DIA.- 4 respostas
-
- 8
-
-
-
- login
- sem modulo
-
(e 3 mais)
Tags:
-
pokemon NPC de Corrida Pokemon
Kevin Luzetti postou um tópico no fórum em TFS 0.X, Compartilhe seu código C++, LUA, PHP e etc
Fala, galera! Aqui é o Kevin, e trago uma novidade fresquinha para vocês: o sistema de corrida de Pokémons com apostas acabou de sair do forno! 🏁🔥 Passei algumas boas horas ajustando e refinando cada detalhe para garantir que a experiência fosse divertida, justa e com aquele toque de adrenalina. Foram ajustes em timers, balanceamento dos multiplicadores de premiação, e até mesmo a implementação de uma taxa de 20% para manter as coisas mais realistas e estratégicas. Tudo isso pra deixar a mecânica bem afinada e trazer uma sensação de imersão para quem gosta de jogos de azar e corridas emocionantes! O que esperar? Escolha seu Pokémon favorito: Temos seis Pokémons disponíveis para as apostas. Quem será o mais rápido? Apostas e prêmios: A cada corrida, você pode apostar 100 HD. Se o seu Pokémon vencer, o prêmio será multiplicado entre 2x e 5x, com desconto de taxa. Corrida dinâmica: Posições atualizadas em tempo real a cada 5 segundos, direto no console. Competitividade e sorte: Será que você confia no seu instinto ou prefere a sorte do acaso? Ajustes e desafios durante o desenvolvimento Foram vários testes para garantir que as distâncias fossem atualizadas corretamente e que o vencedor fosse determinado de forma justa. Trabalhei no bloqueio de movimentação dos jogadores durante a corrida para evitar "truques" durante o evento — ninguém trapaceia por aqui! Refinamento das mensagens de texto para garantir que todos entendam como participar e acompanhar o progresso da corrida. Próximos passos? Já estou pensando em novas ideias para deixar a corrida ainda mais interessante. Quem sabe incluir eventos especiais ou Pokémons lendários em corridas futuras? Se vocês tiverem sugestões, manda aí! Agora é com vocês: aproveitem, apostem com responsabilidade e divirtam-se! 😎 💬 Kevin NPC Corrida de Pokémons – Sistema de Apostas Divertido e Dinâmico 💥 Descrição: Este NPC traz um sistema de corridas de Pokémons com apostas emocionantes para o seu servidor baseado no TFS 0.3.6. Os jogadores escolhem seu Pokémon favorito entre seis opções e apostam uma quantia fixa. O objetivo é torcer para que o escolhido seja o mais rápido e vença a corrida! A recompensa varia de 2x a 5x o valor apostado, com uma taxa de 20% aplicada ao prêmio final. Características 🏃 Simulação de Corrida: Cada Pokémon avança aleatoriamente a cada segundo, simulando uma corrida dinâmica. 🏆 Sistema de Apostas: Jogadores escolhem entre Bulbasaur, Charmander, Squirtle, Pikachu, Jigglypuff e Meowth para apostar 100 HD. 💰 Multiplicadores de Prêmio: O prêmio é definido aleatoriamente entre 2x e 5x o valor apostado, após a dedução de uma taxa de 20%. 📊 Atualizações de Posições: Posições atualizadas a cada 5 segundos para os jogadores que apostaram. 🔐 Restrição de Movimentação: Durante a corrida, os jogadores são imobilizados para evitar fraudes. Comandos Disponíveis "apostar": Inicia o processo de aposta escolhendo um Pokémon. "detalhes": Explica as regras e funcionamento do sistema de apostas e corrida. "voltar": Retorna ao menu inicial de escolha de Pokémon. CÓDIGO LUA. local keywordHandler = KeywordHandler:new() local npcHandler = NpcHandler:new(keywordHandler) NpcSystem.parseParameters(npcHandler) local talkState = {} local pokemons = {"Bulbasaur", "Charmander", "Squirtle", "Pikachu", "Jigglypuff", "Meowth"} local raceInProgress = false local racePositions = {} local raceUpdateInterval = 1000 -- Atualiza a cada 1 segundo local raceDuration = 30000 -- Corrida dura 30 segundos (ajustável) local raceEndTime = 0 local playersBetting = {} local chosenPokemon = "" local betAmount = 0 local lastMessageTime = 0 -- Controle para mensagens a cada 5 segundos -- Função para finalizar a corrida local function finishRace() raceInProgress = false -- Determina o vencedor baseado no Pokémon que atingiu 300 metros primeiro local winner = nil for _, racer in ipairs(racePositions) do if racer.meters >= 300 then winner = racer.name break end end if winner then -- Gera um multiplicador aleatório entre 2x e 5x local prizeMultiplier = math.random(2, 5) for _, player in ipairs(playersBetting) do if winner == chosenPokemon then local prize = betAmount * prizeMultiplier -- Aplica o custo de 20% no prêmio local fee = prize * 0.2 local finalPrize = prize - fee -- Entrega a recompensa com desconto doPlayerAddMoney(player, finalPrize) doPlayerSendTextMessage(player, MESSAGE_STATUS_CONSOLE_BLUE, "Parabéns! O Pokémon " .. winner .. " venceu! Você ganhou " .. finalPrize .. " HD com um multiplicador de " .. prizeMultiplier .. "x! (Após desconto de 20% de taxa)") -- Informa o valor da taxa de desconto doPlayerSendTextMessage(player, MESSAGE_STATUS_CONSOLE_BLUE, "Uma taxa de 20% foi aplicada ao prêmio. Taxa: " .. fee .. " HD") else doPlayerSendTextMessage(player, MESSAGE_STATUS_CONSOLE_BLUE, "Que pena! O Pokémon " .. winner .. " venceu. Você perdeu.") end -- Desbloquear o movimento do jogador após a corrida doCreatureSetNoMove(player, false) -- Libera o movimento end end -- Reseta o estado para nova aposta betAmount = 0 chosenPokemon = "" playersBetting = {} racePositions = {} end -- Atualiza as posições na corrida local function updateRacePositions() if not raceInProgress then return end -- Incrementa os "metros percorridos" dos Pokémons local addedPositions = {} -- Tabela para armazenar as novas distâncias for _, racer in ipairs(racePositions) do if racer.meters < 300 then local newMeters = racer.meters + math.random(1, 10) -- Incremento aleatório entre 1 e 10 metros -- Garantir que a distância não seja repetida while table.contains(addedPositions, newMeters) do newMeters = newMeters + 1 -- Aumenta 1 metro até que a distância seja única end racer.meters = newMeters table.insert(addedPositions, newMeters) -- Armazena a nova distância end end -- Envia mensagens para os jogadores a cada 5 segundos if os.time() * 1000 >= lastMessageTime + 5000 then local positionText = "Atualização das posições:\n" for i, racer in ipairs(racePositions) do positionText = positionText .. i .. ". " .. racer.name .. " percorreu " .. racer.meters .. " metros.\n" end for _, player in ipairs(playersBetting) do doPlayerSendTextMessage(player, MESSAGE_STATUS_CONSOLE_BLUE, positionText) end lastMessageTime = os.time() * 1000 -- Atualiza o tempo da última mensagem end -- Verifica se a corrida terminou local finished = false for _, racer in ipairs(racePositions) do if racer.meters >= 300 then finished = true break end end if finished then finishRace() -- Certifique-se de que a função 'finishRace' é chamada corretamente else -- Continua a corrida addEvent(updateRacePositions, raceUpdateInterval) end end -- Inicia a corrida local function startRace() raceInProgress = true raceEndTime = os.time() * 1000 + raceDuration lastMessageTime = os.time() * 1000 -- Inicializa a corrida com os Pokémons e "metros percorridos" em 0 racePositions = {} for _, pokemon in ipairs(pokemons) do table.insert(racePositions, {name = pokemon, meters = 0}) end -- Bloquear o movimento dos jogadores que apostaram for _, player in ipairs(playersBetting) do doCreatureSetNoMove(player, true) -- Bloqueia o movimento doPlayerSendTextMessage(player, MESSAGE_STATUS_CONSOLE_BLUE, "A corrida começou! As posições serão atualizadas a cada 5 segundos.\n") end -- Inicia a atualização das posições addEvent(updateRacePositions, raceUpdateInterval) end -- Função para verificar se a tabela contém um valor function table.contains(tbl, value) for _, v in pairs(tbl) do if v == value then return true end end return false end function onCreatureAppear(cid) npcHandler:onCreatureAppear(cid) end function onCreatureDisappear(cid) npcHandler:onCreatureDisappear(cid) end function onCreatureSay(cid, type, msg) npcHandler:onCreatureSay(cid, type, msg) end function onThink() npcHandler:onThink() end function creatureSayCallback(cid, type, msg) if not npcHandler:isFocused(cid) then return false end if raceInProgress then selfSay("A corrida está em andamento. Você não pode apostar no momento.", cid) return true end if msgcontains(msg, "apostar") then selfSay("Muito bem, escolha um Pokémon para apostar: Bulbasaur, Charmander, Squirtle, Pikachu, Jigglypuff, Meowth.", cid) talkState[cid] = 1 elseif talkState[cid] == 1 then local chosen = msg:lower():gsub("^%l", string.upper) -- Formata para inicial maiúscula if table.contains(pokemons, chosen) then chosenPokemon = chosen betAmount = 100 -- Valor fixo da aposta selfSay("Você escolheu " .. chosen .. "! A aposta é de " .. betAmount .. " HD. Deseja continuar? (yes/no)", cid) talkState[cid] = 2 else selfSay("Esse Pokémon não existe. Escolha um válido.", cid) end elseif talkState[cid] == 2 then if msgcontains(msg, "yes") then -- Verificar se o jogador tem HD suficiente (100 HD ou 1 HD) if getPlayerItemCount(cid, 2152) >= 100 then removeBetAmount(cid, 2152, 100) -- Remove 100 HD (item 2152) table.insert(playersBetting, cid) selfSay("A corrida começará em breve! Boa sorte!", cid) startRace() talkState[cid] = nil elseif getPlayerItemCount(cid, 2160) >= 1 then removeBetAmount(cid, 2160, 1) -- Remove 1 HD (item 2160) table.insert(playersBetting, cid) selfSay("A corrida começará em breve! Boa sorte!", cid) startRace() talkState[cid] = nil else selfSay("Você não tem dinheiro suficiente.", cid) talkState[cid] = nil end elseif msgcontains(msg, "no") then selfSay("Aposta cancelada. Escolha outro Pokémon.", cid) talkState[cid] = 1 else selfSay("Por favor, responda 'yes' ou 'no'.", cid) end elseif msgcontains(msg, "detalhes") then selfSay("O objetivo do jogo é apostar em um Pokémon para participar de uma corrida. A corrida dura 30 segundos e as posições dos Pokémons serão atualizadas a cada 5 segundos. A cada aposta, você escolhe um Pokémon e paga 100 HD. Se o Pokémon que você escolheu vencer a corrida, você ganhará o dobro ou até mesmo o quíntuplo da sua aposta. Se o seu Pokémon não ganhar, você perde a aposta. Após isso, você pode escolher outro Pokémon para apostar ou voltar à escolha do Pokémon. Para voltar ao início, basta digitar 'voltar'.", cid) talkState[cid] = nil elseif msgcontains(msg, "voltar") then selfSay("Agora, escolha um Pokémon para apostar: Bulbasaur, Charmander, Squirtle, Pikachu, Jigglypuff, Meowth.", cid) talkState[cid] = 1 end return true end -- Função para remover a aposta function removeBetAmount(cid, itemId, amount) local hdCount = getPlayerItemCount(cid, itemId) if hdCount >= amount then doPlayerRemoveItem(cid, itemId, amount) else selfSay("Você não tem HDs suficientes para realizar a aposta.", cid) end end npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) npcHandler:addModule(FocusModule:new()) CÓDIGO XML. <?xml version="1.0" encoding="UTF-8"?> <npc name="Apostador" script="aposta.lua" walkinterval="350000" floorchange="0" speed="0" lookdir="2"> <health now="150" max="150"/> <look type="511" head="22" body="0" legs="19" feet="82"/> <parameters> <parameter key="message_greet" value="Olá |PLAYERNAME|, se você busca emoção e adrenalina, venha fazer sua aposta na corrida de pokémons! São 300 metros de pura emoção, onde só os mais rápidos chegam à linha de chegada. Quer {apostar} e saber {detalhes}?"/> </parameters> </npc> -
Apresento a vocês um novo sistema de armazenamento de dinheiro que foi desenvolvido com base na PXG. Este sistema visa oferecer uma maneira prática e eficiente para os jogadores gerenciarem seus recursos financeiros no jogo. Além das funcionalidades básicas, adicionei algumas melhorias para tornar a experiência mais envolvente. Funcionalidades Armazenamento de Dinheiro Armazenamento e Retorno: O jogador pode armazenar todo o seu dinheiro ao usar um item específico (ID 22951). Se o jogador não tiver dinheiro, uma mensagem informará que não há fundos disponíveis. Retorno do Dinheiro: O jogador pode recuperar seu dinheiro armazenado a qualquer momento, desde que não esteja armazenado. Uma mensagem confirma a quantidade de dinheiro retornada. Formatação de Valores Visualização Atraente: O sistema inclui uma função para formatar os valores monetários, exibindo-os de maneira mais compreensível, incluindo bilhões, milhões, milhares, dólares e centavos. Isso facilita a leitura e o entendimento dos recursos financeiros do jogador. Exibição de Dinheiro Armazenado Consulta Rápida: O jogador pode verificar quanto dinheiro tem armazenado através de uma talkaction. Se não houver dinheiro armazenado, uma mensagem apropriada será exibida. Essa parte deve ser criada em: data/actions/cofre.lua function onUse(cid, item, fromPosition, itemEx, toPosition) local storageItemId = 22951 if item.itemid ~= storageItemId then return false end if not isPlayer(cid) then return false end local storedMoney = getPlayerStorageValue(cid, 303030) -- Função para formatar o valor corretamente, incluindo bilhões local function formatMoney(value) local billions = math.floor(value / 1e9) -- bilhões local millions = math.floor((value % 1e9) / 1e6) -- milhões local thousands = math.floor((value % 1e6) / 1e3) -- milhares local dollars = math.floor(value % 1e3) -- dólares local cents = value % 100 -- centavos (baseados no item 12416) local formatted = "" if billions > 0 then formatted = formatted .. billions .. " bilhões " end if millions > 0 then formatted = formatted .. millions .. " milhões " end if thousands > 0 then formatted = formatted .. thousands .. " mil " end if dollars > 0 then formatted = formatted .. dollars .. " dólares " end if cents > 0 then formatted = formatted .. cents .. " centavos" end if formatted == "" then formatted = "0 centavos" end return formatted end if storedMoney == -1 then local money = getPlayerMoney(cid) if money > 0 then doPlayerRemoveMoney(cid, money) setPlayerStorageValue(cid, 303030, money) doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Todo o seu dinheiro foi armazenado: " .. formatMoney(money) .. ".") else doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Você não tem dinheiro para armazenar.") end else doPlayerAddMoney(cid, storedMoney) setPlayerStorageValue(cid, 303030, -1) doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Seu dinheiro foi retornado: " .. formatMoney(storedMoney) .. ".") end return true end Já essa parte em: data/talkaction/checkmoney.lua function onSay(cid, words, param) if not isPlayer(cid) then return false end local storedMoney = getPlayerStorageValue(cid, 303030) -- Função para formatar o valor corretamente, incluindo bilhões local function formatMoney(value) local billions = math.floor(value / 1e9) -- bilhões local millions = math.floor((value % 1e9) / 1e6) -- milhões local thousands = math.floor((value % 1e6) / 1e3) -- milhares local dollars = math.floor(value % 1e3) -- dólares local cents = value % 100 -- centavos local formatted = "" if billions > 0 then formatted = formatted .. billions .. " bilhões " end if millions > 0 then formatted = formatted .. millions .. " milhões " end if thousands > 0 then formatted = formatted .. thousands .. " mil " end if dollars > 0 then formatted = formatted .. dollars .. " dólares " end if cents > 0 then formatted = formatted .. cents .. " centavos" end if formatted == "" then formatted = "0 centavos" end return formatted end if storedMoney == -1 then doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Você não tem dinheiro armazenado.") else doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Você tem " .. formatMoney(storedMoney) .. " armazenado(s).") end return true end Action: <action itemid="22951" event="script" value="cofre.lua"/> Talk: <talkaction words="!checkmoney" separator=" " script="checkmoney.lua" /> Conclusão Este sistema foi projetado para proporcionar uma experiência mais rica e intuitiva ao gerenciamento de dinheiro dentro do jogo. Agradeço à PXG pela inspiração e espero que os jogadores aproveitem as novas funcionalidades adicionadas.
- 1 resposta
-
- 3
-
-
-
- actions
- talkaction
-
(e 1 mais)
Tags:
-
Efeito no jogador ao andar
Kevin Luzetti respondeu ao tópico de gutinha em TFS 0.X, Compartilhe seu código C++, LUA, PHP e etc
Tem como fazer direto na source né...
- Criar Novo...
