-
Total de itens
338 -
Registro em
-
Última visita
Posts postados por Nostradamus
-
-
Como todos já sabem por meio de meu keynote, estou saindo do OpenTibia, e resolvi preparar um último release, e claro, sem deixar tudo pronto, incentivando o desenvolvimento e para que as pessoas se virem um pouco sozinhas, resolvi criar um sistema de banco dinâmico, funcional em qualquer servidor, e sem uso de I/O ou mesmo LuaSQL.
Features
- Função para depósito
- Função para saque
- Função para depositar tudo
- Função para sacar tudo
- Conversão dinâmica de dinheiro para a forma mais fácil (concedida de Jovial)
- Transferência de quantias
- Função para balanço bancário
- Função de checagem de valor (para ver se é válido)
- Função para pegar a quantidade de dinheiro que o jogador possui
Vamos então a essa classe:
Bank = {} Bank.__index = Bank STORAGE_BANK = 666 function Bank:getPlayerMoney(cid) return ((getPlayerItemCount(cid, ITEM_CRYSTAL_COIN) * 10000) + (getPlayerItemCount(cid, ITEM_PLATINUM_COIN) * 100) + getPlayerItemCount(cid, ITEM_GOLD_COIN)) end function Bank:isValidValue(value) if ((type(value) == "number") and (value > 0)) then return TRUE end return FALSE end function Bank:getBalance(cid) return getPlayerStorageValue(cid, STORAGE_BANK) end function Bank:doConvertMoney(value) local crystal, platinum, gold if (value >= 10000) then crystal = math.floor(value / 10000) value = value - (crystal * 10000) else crystal = 0 end if (value >= 100) then platinum = math.floor(value / 100) value = value - (platinum * 100) else platinum = 0 end if (value >= 0) then gold = value else debug('[Bank:doConvertMoney] Unknown Error') end return gold, platinum, crystal end function Bank:doWithdraw(cid, value) if ((self:isValidValue(value) == TRUE) and (self:getBalance(cid) >= value)) then doPlayerAddMoney(cid, value) setPlayerStorageValue(cid, STORAGE_BANK, self:getBalance(cid) - value) end return FALSE end function Bank:doWithdrawAll(cid) self:doWithdraw(cid, self:getPlayerMoney(cid)) return TRUE end function Bank:doDeposit(cid, value) if ((self:isValidValue(value) == TRUE) and (self:getPlayerMoney(cid) >= value)) then doPlayerRemoveMoney(cid, value) setPlayerStorageValue(cid, self:getBalance(cid) + value) end return FALSE end function Bank:doDepositAll(cid) self:doDeposit(cid, self:getPlayerMoney(cid)) return TRUE end function Bank:doTransfer(cid, name, value) local target = getPlayerByName(name) if ((self:isValidValue(value) == TRUE) and (self:getPlayerMoney(cid) >= value) and (isPlayer(target) == TRUE)) then self:doWithdraw(cid, self:getBalance(cid) - value) self:doDeposit(target, self:getBalance(target) + value) end return FALSE end
Aqui vai um exemplo de pig bank que você dá use no mesmo e depois no dinheiro e este então, é depositado.
function onUse(cid, item, frompos, item2, topos) local coins = {ITEM_GOLD_COIN, ITEM_PLATINUM_COIN, ITEM_CRYSTAL_COIN} local coinValue = {[ITEM_GOLD_COIN] = 1, [ITEM_PLATINUM_COIN] = 100, [ITEM_CRYSTAL_COIN] = 10000} if ((item2.type >= 0) and (isInArray(coins, item2.itemid) then Bank:doDeposit(cid, item2.type * coinValue[item2.itemid]) doRemoveItem(item2.itemid, item2.type) end return FALSE end
- Função para depósito
-
Introdução
Esse é um sistema que consiste na administração pelo usuário (gamemaster, gods e etc) de locais, ou seja, a fácil ida de um local a outra que pode ser (ou não) distante e com isso, facilitar a vida de todo mundo.
Instruções
O script se trata de uma talkaction, e a sintaxe dela é o seguinte:
-
!set "Nome do local
-
!unset "Nome do local
-
!teleport "Nome do local
Além disso, é requerido que se crie uma tabela no banco de dados para guardar-se os nomes de cada local.
Tabela: Teleports
Campos: pos, name
Observações
O script utiliza-se da biblioteca LuaSQL, presente no servidor The Forgotten Server. Portanto, só funcionará em tal versão (a não ser que você tenha uma versão com tal biblioteca).
O script não foi testado, mas tenho 90% de certeza de que irá funcionar.
Estou liberando talk código, pois desenvolvi o mesmo usando apenas tabelas para mim mesmo, e que seria interessante para fins didáticos à se compreender o uso de LuaSQL.
Código
talkactions.xml
<talkaction words="!set" script="teleporter.lua" /> <talkaction words="!unset" script="teleporter.lua" /> <talkaction words="!teleport" script="teleporter.lua" />
teleporter.lua
local ITEM_TELEPORT = 1387 dofile('./config.lua') env = assert(luasql.mysql()) connect = assert(env:connect(mysqlDatabase, mysqlUser, mysqlPass, mysqlHost, mysqlPort)) Waypoint = { -- pos here should be a table (e.g: {x = 10, y = 10, z = 10} set = function (pos, name) if (string.find(name, '^[a-zA-Z0-9 -_]+$')) then debugPrint('[Waypoint System] Wrong characteres to the name of waypoint.') return FALSE end local cursor = assert(connect:execute("SELECT * FROM `teleports` WHERE `pos` = " .. pos .. ";")) if (cursor:numrows() > 0) then local query = assert(connect:execute("UPDATE `teleports` SET `pos` = " .. pos .. " WHERE `name` = " .. name .. ");")) return TRUE else local query = assert(connect:execute("INSERT INTO `teleports` (`pos`, `name`) VALUES (" .. pos .. ", " .. name .. ");")) return TRUE end end, unset = function (pos) local cursor = assert(connect:execute("SELECT * FROM `teleports` WHERE `pos` = " .. pos .. ";")) if (cursor:numrows() > 0) then local query = assert(connect:execute("DELETE FROM `teleports` WHERE `pos ` = " .. pos ";")) return TRUE else return FALSE end end, get = function (name) local cursor = assert(connect:execute("SELECT * FROM `teleports` WHERE `name` = " .. name .. ";")) local arr = {} if (cursor:numrows() > 0) then cursor:fetch(arr) position = arr[1] return position else return FALSE end end } onSay = function (cid, words, param) local playerPos, playerDir = getCreaturePosition(cid), getPlayerLookDir(cid) if (string.find(param, '^[a-zA-Z0-9 -_]+$')) then if (words == "!set") then Waypoint.set(playerPos, param) doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "New waypoint: " .. param .. " ( " .. playerPos .. ").") elseif (words == "!unset") then Waypoint.unset(playerPos) else local posTo = Waypoint.get(param) local pos if (playerDir == NORTH) then pos = {x = playerPos.x , y = playerPos.y + 1, z = playerPos.z, stackpos = 253} elseif (playerDir == SOUTH) then pos = {x = playerPos.x, y = playerPos.y - 1, z = playerPos.z, stackpos = 253} elseif (playerDir == EAST) then pos = {x = playerPos.x + 1, y = playerPos.y, z = playerPos.z, stackpos = 253} elseif (playerDir == WEST) then pos = {x = playerPos.x - 1, y = playerPos.y, z = playerPos.z, stackpos = 253} else debugPrint('[Waypoint System] Wrong direction spoted.') end local doCreateTeleport(ITEM_TELEPORT, pos, posTo) --doTeleportThing(cid, position) doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Teleported to waypoint " .. param .. " ( " .. posTo .. ").") end end end
Créditos
Os créditos são totalmente meus, Nostradamus.
-
!set "Nome do local
-
@h3online
A maioria dos servidores (mais atualizados) não suportam comandos em doPlayerSay, não sei quanto ao seu, mas você chegou a testar?
-
@Eingenlieb
O me.show serve para esconder/aparecer o formulário que está sendo manipulado, por isso o uso do "me", mas caso você queira com outro formulário, basta colocar o nome do mesmo.
-
Vocês só sabem reclamar, por isso mesmo que parei de desenvolver a StarterKit...
Vão aprender ao menos a ligar um servidor para depois ficar baixando..
-
Pensem comigo, a implementação de sons ao jogo teria que ser completa, e como sons são arquivos grandes mesmo tendo durações pequenas, o cliente Tibia ficaria dez vezes ou mais pesado. Além disso, para quem quer ver som no Tibia, existe o projeto Brabexia (www.brabexia.com) que fez isso.
-
na verdade o newszoftzz não tem crédito algum pelo código, e sim pela idéia apenas. O código foi totalmente feito pelo SuperGillis.
-
Ele é o spriter da BlackOnix
E claro, nem precisa falar que ele é ótimo com perspercitva.
-
Como muitos sabem, sou desenvolvedor LUA oficial do projeto OpenTibia, e, recentemente andei padronizando toda a pasta data com alguns dados que julguei-os necessários para o melhor desenvolvimento por parte de outros programadores não-oficiais que constantemente ajudam no projeto, os scripters. Tal padronização também é usada como parte da mediação interna dos programadores da BlackOnix, um projeto de minha autoria.
Sem mais delongas, vamos as "regras" a serem seguidas:
-
Estruturação de códigos
Quanto melhor a estruturação, mais fácil fica a leitura do código, baseando-se na seguinte hierarquia:
Classe Função Condições (se existir) Ação da condição Fim da Condição Fim da Função Fim da Classe
A tabulação deve ser equivalente a quatro espaços, que é o mesmo que se apertar TAB.
-
Condições
-
Estética
-
Use parênteses nas condições, pois isso pode tornar mais fácil o entendimento do código.
-
-
Performace
-
Caso tenha uma série de condições, começe com as mais usuais e eficientes (interpretadas com facilidade)
-
Caso seja mais normal de acontecer uma condição mesmo que esta seja menos eficiente, ignore o primeiro passo
-
Use nas condições "atalhos" com os operadores "or" e "and" para evitar condições dentro de condições
-
Evite comparar strings, pois ao fazer isso você checa cada letra, e isso pode ser prejudicial
-
-
Variáveis
-
Estética
-
Evite criar variáveis com nomes que não identificam a "função" da mesma no código
-
-
Performace
-
Caso for usar uma variável usada apenas em uma função, declare a mesma como "local".
-
Sempre que possível, declare variáveis fora de função.
-
-
Constantes
-
Estética
-
Crie nome de constantes usando apenas usando letras maiúsculas e "_".
-
Utilize-se de "grupos" para organizar as constantes, são eles:
-
Storages
-
(STORAGE_)
[*]ActionIDs-
(ACTIONID_)
[*]UniqueIDs-
(UNIQUEID_)
-
-
-
-
Performace
-
Sempre declare constantes fora de funções.
-
Nunca use os valores correspondentes a constante ao invés delas mesmas.
-
Caso tenha mais dúvidas, consule o manual do LUA em -
Estruturação de códigos
-
Tipo cara, vou ser sincero e dar minha opinião real, está bem amador, mas vou lhe dar umas dicas de como melhorar:
- Estruture seus códigos
- Algumas magias ocupam apenas poucos espaços, por isso, não há necessidade de uma array tão extensa.
Espero que essas dicas te ajudem.
- Estruture seus códigos
-
Gostei mesmo é dos efeitos novos, vai dar pra fazer muita magia legal.
-
@laairoy
Não é assim que se faz um IP Changer...
-
Muito bom sistema, e assemelha-se ao da BlackOnix, apesar de ser muito melhor o da BlackOnix.
-
Detalhe :
Se você clicar na pumpkinhead acesa , ela apaga e NÃO devolve a Torch.
Use doCreateItem ou doPlayerAddItem para "devolver" a torch.
-
@erichtibiano
Seu demente, você não tem cérebro não? Ou não sabe pensar? Olha onde postou...
-
Use isInArray(array, element) muito melhor em termos de performace, e diminui o código para mais de 70%
-
VisualBasic pra mim, é sempre ruim, então pra mim não faz muita diferença.
-
Muito bom, bem recortado o formato, bem legal mesmo.
-
Warmode Enforced KIT
Depois de jogar alguns servidores enforced, tive a idéia de criar um, mas, devido a falta de tempo, não pude completar tal objetivo. Mas apesar disso, desenvolvi alguns códigos para aqueles que gostam de um servidor Enforced.
OBS: Os códigos a seguir utilizam-se de funções apenas presentes no Forgotten Server.
global.lua
include('functions.lua')
functions.lua
ITEM_DE = 6500 STORAGE_KILLS = 666 ACTIONID_CORPSE = 667 -- function 'isWearing' by Colex function isWearing(cid, outfit) _outfit = getCreatureOutfit(cid) table.foreach(otufit,function (a,b) if b ~= _outfit[a] then doSetCreatureOutfit(cid, outfit, 0) end) end function doAddDE(cid, count) doPlayerAddItem(cid, ITEM_DE, count) return TRUE end function doRemoveDE(cid, count) doPlayerRemoveItem(cid, ITEM_DE, count) return TRUE end function doCountDE(cid) local count = getPlayerItemCount(cid, ITEM_DE) if (count > 1) then doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'You have ' .. count .. ' Demonic Essences.') elseif (count == 1) then doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'You have ' .. count .. ' Demonic Essence.') else doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'You do not have any DE.') end return TRUE end function getPlayerKills(cid) local kills = getPlayerStorageValue(cid, STORAGE_KILLS) if (kills > 1) then doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'You have killed ' .. kills .. ' players.') elseif (kills == 1) then doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'You have killed ' .. kills .. ' player.') else doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'You have not killed anyone.') end return TRUE end function addPlayerKills(cid) local kills = getPlayerStorageValue(cid, STORAGE_KILLS) if (kills < 0) then setPlayerStorageValue(cid, STORAGE_KILLS, 0) else setPlayerStorageValue(cid, STORAGE_KILLS, kills + 1) end return TRUE end function doBroadcastPowergamer(cid) local kills = getPlayerStorageValue(cid, STORAGE_KILLS) local levels = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100} if (isInArray(levels, kills) == TRUE) then broadcastMessage(getPlayerName(cid) .. ' killed ' .. kills .. ' players!', TALKTYPE_BROADCAST) return TRUE end end
creaturescripts/scripts/playerdeath.lua
function onDeath(cid, corpse, killer) if ((isPlayer(cid) == TRUE) and (isPlayer(killer) == TRUE)) then doSetItemActionId(corpse, ACTIONID_CORPSE) doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_RED, 'You got killed by ' .. killer .. '.') doSendAnimatedText(getCreaturePosition(cid), 'Owned!', TEXTCOLOR_RED) doSendAnimatedText(getCreaturePosition(killer), 'Kill!', TEXTCOLOR_CRYSTAL) end end
actions/scripts/corpse.lua
function onUse(cid, item, frompos, item2, topos) if (item.actionid == ACTIONID_CORPSE) then doCreatureAddHealth(cid, (getCreatureHealth(cid) * 0.5) doPlayerAddMana(cid, (getPlayerMana(cid) * 0.4) doSendAnimatedText(getCreaturePosition(cid), 'Power!', TEXTCOLOR_GOLD) doRemoveItem(item.itemid, 1) else return FALSE end return TRUE end
talkactions/scripts/info.lua
function onSay(cid, words, param) if (words == !kills) then getPlayerKills(cid) elseif (words == !talons) then doCountTalons(cid) end return TRUE end
Bom proveito.
-
Manual de introdução à programação em Lua 3.1, em formato PDF
Só pra lembrar que estamos na versão LUA 5.1
-
Desenvolvi algumas funções para tratamento de arquivos fácilmente, não é como a do Colex, que por sinal, é mais completa, mas, já ajuda.
function File:Exists(filename) local file = io.open(filename, "r") if (file == nil) then return false else file:close() return true end end function File:Create(filename, content) if (content == nil) then return false end local file = io.open(filename, "w") if (file == nil) then return false end file:write(content) file:flush() file:close() return true end function File:Save(filename, content) if (content == nil) then return false end local file = io.open(filename, "w+b") if (file == nil) then return false end file:write(content) file:flush() file:close() return true end function File:Load(filename) local file = io.open(filename, "r") if (file == nil) then return nil end local load = file:read("*all") file:close() return (load) end function File:LoadAsTable(filename) local file = io.open(filename, "r") if (file == nil) then return nil end local load = {} while true do local line = file:read("*l") if (line == nil) then break end table.insert(load, line) end file:close() return load, table.getn(load) end function File:GetExtension(filename) local fileExt = nil for w in string.gfind(filename, "(%.%a*)") do fileExt = string.lower(string.sub(w, 2, 10)) end return fileExt end function File:GetName(filename) local rFileName = nil for w in string.gfind(filename,"(%w*%.%w*)") do rFileName = string.lower(string.sub(w, 1, string.find(w, "%.")-1)) end return rFileName end
Creio que o nome das funções se auto-explicam, mas se tiverem dúvidas, é só postarem.
-
Muito bom tutorial, eu até leria, se não soubesse, como já sei tudo disso, só me resta comentar.
-
Só acho bobeira colocar idioma inglês, já que o conteúdo é em português.
-
Conteúdo Removido
Motivo: Leia
-
Quem Está Navegando 0 membros estão online
- Nenhum usuário registrado visualizando esta página.
Natacao Perfeita!
em Actions e Talkactions
Postado · Editado por Nostradamus
Além de estar faltando os créditos o título está incorreto, para algo estar perfeito o código também deve estar impecável, o que não é o caso.
E já que você acha ter tal "mínimo conhecimento de script possível", aprenda a edentar e usar TABs nos códigos, para mostrar isso, caso contrário, seja humilde e ajude sem humilhar as pessoas, pois você não tem cacife para isso.