Ir para conteúdo

Nostradamus

Visconde
  • Total de itens

    338
  • Registro em

  • Última visita

Posts postados por Nostradamus

  1. 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.

  2. 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

  3. 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.

  4. 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

  5. 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.

  6. 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.

  • Quem Está Navegando   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.
×
×
  • Criar Novo...