• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

[Help] Other kind of money?

tosse12

Panchira Project Member
Joined
Jun 10, 2007
Messages
864
Reaction score
9
Location
Sweden
okey this question is about "tibia money"

Is it possible to have like skulls, corrots or scarab coin as money?

you know when you change 100 gold - 1platium
and when you change 100 platium - 1 crystal coin
and now, when you change 100 cc to 1 skull, will that skull be avible to use when you want to buy items from npc's, or do you need to make a new script for it?
 
What about this one...
Code:
function doPlayerRemoveMoney(cid, n)
local money = {
      {2160, 10000}, -- crystal coin
      {2152, 100}, -- platinum coin
      {2148, 1} -- gold coin
}
      for k,v in pairs(money) do
           if (doPlayerTakeItem(cid,k,math.floor(n/v))) then
               n = n - math.floor(n/v) * v
           else
               return 0
           end    
      end
      return 1
end
 
And the change?

I'm done now I think... Tested and works, but would be good if you tested it yourself with different amount of money.
PHP:
function math.roof(n)
    -- Function by Colandus.
    local v = math.floor(n)
    return v + (n - v > 0 and 1 or 0)
end

local money = {
    {
        name = "gold coin",
        itemid = ITEM_GOLD_COIN,
        value = 1
    },
    {
        name = "platinum coin",
        itemid = ITEM_PLATINUM_COIN,
        value = 100
    },
    {
        name = "crystal coin",
        itemid = ITEM_CRYSTAL_COIN,
        value = 10000
    }
}

function getPlayerMoney(cid)
    -- Function by Colandus.
    local playerMoney = 0
    for _, moneyInfo in pairs(money) do
        playerMoney = playerMoney + getPlayerItemCount(cid, moneyInfo.itemid) * moneyInfo.value
    end
    return playerMoney
end

function doPlayerRemoveMoney(cid, n)
    -- Function by Colandus.
    if getPlayerMoney(cid) < n then
        return FALSE
    end
    -- Sort the table by lowest value.
    table.sort(money, function(a, b) return a.value < b.value end)
    for _, moneyInfo in pairs(money) do
        local moneyCount = getPlayerItemCount(cid, moneyInfo.itemid)
        local removeMoney = math.min(math.floor(moneyCount * moneyInfo.value), n)
        n = n - removeMoney
        local takeMoney = (removeMoney / moneyInfo.value)
        doPlayerTakeItem(cid, moneyInfo.itemid, math.roof(takeMoney))
        takeMoney = moneyCount - takeMoney
        local change = math.floor((takeMoney - math.floor(takeMoney)) * moneyInfo.value)
        if change > 0 then
            -- Sort the table by highest value.
            table.sort(money, function(a, b) return a.value > b.value end)
            for _, moneyInfo in pairs(money) do
                local giveChange = (math.floor(change / moneyInfo.value) * moneyInfo.value)
                if giveChange > 0 then
                    doPlayerGiveItem(cid, moneyInfo.itemid, giveChange / moneyInfo.value)
                    change = change - giveChange
                    if change == 0 then
                        break
                    end
                end
            end
        end
        if n == 0 then
            break
        end
    end
    return TRUE
end

I will make more functions soon, like givePlayerMoney :p

the math.roof function does the opposit of math.floor, if the value given is e.g. 4 it will stay as 4, but if it's like 4.2 or so, it'll turn into 5.
 
Last edited:
You can call it functions not scripts and yes in global.lua :p

But yet you need the other functions to make it work 100% in NPC's and stuff :p
 
..... Ehm, maybe a stupid question, but.... could you make a scrpit/function or w/e it is ^_^, cause when I see it once I "Maybe" understand :p
 
Alright, I've made the doPlayerAddMoney function now, plus another thing that will allow your NPC's to trade with different currencies.

For example, normal NPC's trade with gold, platinum and crystal but maybe an Orc NPC trade with apples, oranges and bananas or whatever :p

Please copy all functions and remove the old as they've been updated. And you should also remove the existing doPlayerAddMoney that was made by Jiddo I guess from global.lua.
PHP:
function math.roof(n)
    -- Function by Colandus.
    local v = math.floor(n)
    return v + (n - v > 0 and 1 or 0)
end

money = {
    {
        name = "gold coin",
        itemid = ITEM_GOLD_COIN,
        value = 1
    },
    {
        name = "platinum coin",
        itemid = ITEM_PLATINUM_COIN,
        value = 100
    },
    {
        name = "crystal coin",
        itemid = ITEM_CRYSTAL_COIN,
        value = 10000
    }
}

function getPlayerMoney(cid, t)
    -- Function by Colandus.
    local currency = money
    if t ~= nil then
        currency = t
    end
    local playerMoney = 0
    for _, moneyInfo in pairs(currency) do
        playerMoney = playerMoney + (getPlayerItemCount(cid, moneyInfo.itemid) * moneyInfo.value)
    end
    return playerMoney
end

function doPlayerAddMoney(cid, n, t)
    local currency = money
    if t ~= nil then
        currency = t
    end
    -- Function by Colandus.
    -- Sort the table by highest value.
    table.sort(currency, function(a, b) return a.value > b.value end)
    for _, moneyInfo in pairs(currency) do
        local giveChange = (math.floor(n / moneyInfo.value) * moneyInfo.value)
        if giveChange > 0 then
            if doPlayerGiveItem(cid, moneyInfo.itemid, giveChange / moneyInfo.value) ~= LUA_NO_ERROR then
                return LUA_ERROR
            end
            n = n - giveChange
            if n == 0 then break end
        end
    end
    return TRUE
end

function doPlayerRemoveMoney(cid, n, t)
    -- Function by Colandus.
    local currency = money
    if t ~= nil then
        currency = t
    end
    if getPlayerMoney(cid, currency) < n then
        return FALSE
    end
    -- Sort the table by lowest value.
    table.sort(currency, function(a, b) return a.value < b.value end)
    for _, moneyInfo in pairs(currency) do
        local moneyCount = getPlayerItemCount(cid, moneyInfo.itemid)
        local removeMoney = math.min(math.floor(moneyCount * moneyInfo.value), n)
        n = n - removeMoney
        local takeMoney = (removeMoney / moneyInfo.value)
        if doPlayerTakeItem(cid, moneyInfo.itemid, math.roof(takeMoney)) ~= LUA_NO_ERROR then
            return LUA_ERROR
        end
        takeMoney = moneyCount - takeMoney
        local change = math.floor((takeMoney - math.floor(takeMoney)) * moneyInfo.value)
        if change > 0 then
            if doPlayerAddMoney(cid, change, currency) ~= LUA_NO_ERROR then
                return LUA_ERROR
            end
        end
        if n == 0 then break end
    end
    return TRUE
end

To do that, you simply just make up a new table, like this:
PHP:
orcMoney = {
    {
        name = "apple",
        itemid = ITEMID_OF_APPLE,
        value = 1
    },
    {
        name = "orange",
        itemid = ITEMID_OF_ORANGE,
        value = 10
    },
    {
        name = "banana",
        itemid = ITEMID_OF_BANANA,
        value = 100
    }
}

And ofcourse you can add as many as you want and you mustn't have the same values. And to use it you simply just do:
PHP:
doPlayerRemoveMoney(cid, 40, orcMoney) -- remove 40 of the orc's currency
doPlayerAddMoney(cid, 14, orcMoney) -- give 14 of the orc's currency

But for normal money you don't need to write anything extra. Here's a test code:
PHP:
function onSay(cid, words, param)
    if doPlayerRemoveMoney(cid, 6777) == FALSE then
        doPlayerSendCancel(cid, "Not enough money!")
    end
    return TRUE
end
 
Last edited:
One question about this... Is it possible to make it like this?
Code:
money = {
    {
        name = "gold coin",
        itemid = ITEM_GOLD_COIN,
        value = 1
    },
    {
        name = "platinum coin",
        itemid = ITEM_PLATINUM_COIN,
        value = 100
    },
    {
        name = "crystal coin",
        itemid = ITEM_CRYSTAL_COIN,
        value = 10000
    },
{ name = "skull",
  itemid = 2229,
  value = 1000000
}
}
 
Yes, but please think about making it "structured" xD
PHP:
money = {
    {
        name = "gold coin",
        itemid = ITEM_GOLD_COIN,
        value = 1
    },
    {
        name = "platinum coin",
        itemid = ITEM_PLATINUM_COIN,
        value = 100
    },
    {
        name = "crystal coin",
        itemid = ITEM_CRYSTAL_COIN,
        value = 10000
    },
    {
        name = "skull",
        itemid = 2229,
        value = 1000000
    }
}

Btw, I made a "change gold" script (untested) that will work for this system (although, the difference of each money type must me * 100, which it normally has and your as well), so you could try it out [data/actions/scripts/money.lua]:
PHP:
function onUse(cid, item, frompos, item2, topos)
    table.sort(money, function(a, b) return a.value < b.value end)
    for k, moneyInfo in pairs(money) do
        if item.itemid == moneyInfo.itemid then
            local previousItem = money[k - 1]
            local nextItem = money[k + 1]
            if item.type < 100 or nextItem == nil then
                if previousItem == nil then
                    doPlayerSendTextMessage(cid, 22, "You have to got 100 " .. moneyInfo.name .. "'s to change for a " .. nextItem.name .. ".")
                else
                    doTransformItem(item.uid, previousItem.itemid)
                    doChangeTypeItem(item.uid, 100)
                    doPlayerSendTextMessage(cid, 22, "You have changed a " .. moneyInfo.name .. " to 100 " .. previousItem.name .. ".")
                end
            elseif item.type == 100 and nextItem ~= nil then
                doRemoveItem(item.uid,item.type)
                doPlayerAddItem(cid, 2152, 1)
                doPlayerSendTextMessage(cid,22, "You have changed 100 gp to 1 platnium coin")
            end
        end
    end
    return TRUE
end

And then the XML part [data/actions/actions.xml]:
Code:
<action itemid="2148" script="money.lua" />
<action itemid="2152" script="money.lua" />
<action itemid="2160" script="money.lua" />
<action itemid="2229 script="money.lua" />

Also make sure it does not exist in any other script!
 
Last edited:
I will test it right away :)

Okey now I don't get any errors :) but it didn't change the gold to the skull.... but I edited on the "Changegold.lua" a bit ^_^

Before:
Code:
function onUse(cid, item, fromPosition, itemEx, toPosition)
    if item.itemid == ITEM_GOLD_COIN and item.type == ITEMCOUNT_MAX then
        doChangeTypeItem(item.uid, item.type - item.type)
        doPlayerAddItem(cid, ITEM_PLATINUM_COIN, 1)
        doSendAnimatedText(fromPosition, "$$$", TEXTCOLOR_PLATINUMBLUE)
    elseif item.itemid == ITEM_PLATINUM_COIN and item.type == ITEMCOUNT_MAX then
        doChangeTypeItem(item.uid, item.type - item.type)
        doPlayerAddItem(cid, ITEM_CRYSTAL_COIN, 1)
        doSendAnimatedText(fromPosition, "$$$", TEXTCOLOR_TEAL)
    elseif item.itemid == ITEM_PLATINUM_COIN and item.type < ITEMCOUNT_MAX then
        doChangeTypeItem(item.uid, item.type - 1)
        doPlayerAddItem(cid, ITEM_GOLD_COIN, ITEMCOUNT_MAX)
        doSendAnimatedText(fromPosition, "$$$", TEXTCOLOR_YELLOW)
    elseif item.itemid == ITEM_CRYSTAL_COIN then
        doChangeTypeItem(item.uid, item.type - 1)
        doPlayerAddItem(cid, ITEM_PLATINUM_COIN, ITEMCOUNT_MAX)
        doSendAnimatedText(fromPosition, "$$$", TEXTCOLOR_PLATINUMBLUE)
    else
        return FALSE
    end
    return TRUE
end
Now:
Code:
function onUse(cid, item, fromPosition, itemEx, toPosition)
    if item.itemid == ITEM_GOLD_COIN and item.type == ITEMCOUNT_MAX then
        doChangeTypeItem(item.uid, item.type - item.type)
        doPlayerAddItem(cid, ITEM_PLATINUM_COIN, 1)
        doSendAnimatedText(fromPosition, "$$$", TEXTCOLOR_PLATINUMBLUE)
    elseif item.itemid == ITEM_PLATINUM_COIN and item.type == ITEMCOUNT_MAX then
        doChangeTypeItem(item.uid, item.type - item.type)
        doPlayerAddItem(cid, ITEM_CRYSTAL_COIN, 1)
        doSendAnimatedText(fromPosition, "$$$", TEXTCOLOR_TEAL)
    elseif item.itemid == ITEM_PLATINUM_COIN and item.type < ITEMCOUNT_MAX then
        doChangeTypeItem(item.uid, item.type - 1)
        doPlayerAddItem(cid, ITEM_GOLD_COIN, ITEMCOUNT_MAX)
        doSendAnimatedText(fromPosition, "$$$", TEXTCOLOR_YELLOW)
    elseif item.itemid == ITEM_CRYSTAL_COIN and item.type < ITEMCOUNT_MAX then
        doChangeTypeItem(item.uid, item.type - 1)
        doPlayerAddItem(cid, ITEM_PLATINUM_COIN, ITEMCOUNT_MAX)
        doSendAnimatedText(fromPosition, "$$$", TEXTCOLOR_PLATINUMBLUE)
    elseif item.itemid == ITEM_CRYSTAL_COIN and item.type == ITEMCOUNT_MAX then
        doChangeTypeItem(item.uid, item.type - item.type)
        doPlayerAddItem(cid, ITEM_SKULL, 1)
        doSendAnimatedText(fromPosition, "$$$", TEXTCOLOR_TEAL)
    elseif item.itemid == ITEM_SKULL then
        doChangeTypeItem(item.uid, item.type - 1)
        doPlayerAddItem(cid, ITEM_CRYSTAL_COIN, ITEMCOUNT_MAX)
        doSendAnimatedText(fromPosition, "$$$", TEXTCOLOR_TEAL)
    else
        return FALSE
    end
    return TRUE
end
and this time it worked, I will now test how the buy thing work :)
 
Last edited by a moderator:
Okey... got some problems with this npc scriping...

Shall it look like this?
Code:
local focus = 0
local talk_start = 0
local target = 0
local days = 0

function onThingMove(creature, thing, oldpos, oldstackpos)

end


function onCreatureAppear(creature)

end


function onCreatureDisappear(cid, pos)
if focus == cid then
selfSay('Good bye then.')
focus = 0
talk_start = 0
end
end


function onCreatureTurn(creature)

end


function msgcontains(txt, str)
return (string.find(txt, str) and not string.find(txt, '(%w+)' .. str) and not string.find(txt, str .. '(%w+)'))
end


function onCreatureSay(cid, type, msg)
msg = string.lower(msg)

if (msgcontains(msg, 'hi') and (focus == 0)) and getDistanceToCreature(cid) < 4 then
selfSay('Hello ' .. getPlayerName(cid) .. '! I buy beginners items.')
focus = cid
talk_start = os.clock()

elseif msgcontains(msg, 'hi') and (focus ~= cid) and getDistanceToCreature(cid) < 4 then
selfSay('Sorry, ' .. getPlayerName(cid) .. '! I talk to you in a minute.')

elseif focus == cid then
talk_start = os.clock()

if msgcontains(msg, 'armor') then
selfSay('Do you want to buy Juggernuts armor, for just 10 miljons?')
talk_state = 1
end

elseif msgcontains(msg, 'helmet') then
selfSay('Do you want to buy Juggernuts helmet, for just 5 miljons?')
talk_state = 2

elseif talk_state == 1 then
if msgcontains(msg, 'yes') then
if doPlayerRemoveMoney(cid,10000000, Money) == TRUE then
doPlayeradditem(cid, 2656, 1)
selfSay('Thank you very much!')
else
selfSay('Sorry, you do not have enough money.')
end
end
talk_state = 0

elseif talk_state == 2 then
if msgcontains(msg, 'yes') then
if doPlayerRemoveMoney(cid,5000000) == TRUE then
dpPlayeradditem(cid, 2663, 1)
selfSay('Thank you for buying this helmet!')
else
selfSay('Sorry, you do not have enough money.')
end
end
talk_state = 0

elseif msgcontains(msg, 'bye') and getDistanceToCreature(cid) < 4 then
selfSay('Good bye, ' .. creatureGetName(cid) .. '!')
focus = 0
talk_start = 0
end
end
end



function onThink()
doNpcSetCreatureFocus(focus)
if (os.clock() - talk_start) > 30 then
if focus > 0 then
selfSay('Next Please...')
end
focus = 0
end
if focus ~= 0 then
if getDistanceToCreature(focus) > 5 then
selfSay('Good bye then.')
focus = 0
end
end
end

Is that correct or what shall I write?! I am noob at this :p
 
First of all, you can't make a big M at the Money while the variable name is money and second if you're going to use the normal money you don't need to write money, actually all the old functions will work... Plus that doPlayeradditem is nil, please be very exact with upper/lowercase letters! It's very important!

Here's how you do:
PHP:
if doPlayerBuyItem(cid, 2663, 1, 5000000) ~= LUA_ERROR then
	selfSay('Thank you for buying this helmet!')
else
	selfSay('Sorry, you do not have enough money.')
end
 
I think I am almost done :)
Just got one more error on this script:
Code:
[28/08/2008  16:42:53] [Warning - NpcScript::NpcScript] Can not load script: data/npc/scripts/test.lua
[28/08/2008  16:42:53] data/npc/scripts/test.lua:70: '<eof>' expected near 'elseif'

This is the script:
PHP:
local focus = 0
local talk_start = 0
local target = 0
local days = 0

function onThingMove(creature, thing, oldpos, oldstackpos)

end


function onCreatureAppear(creature)

end


function onCreatureDisappear(cid, pos)
if focus == cid then
selfSay('Good bye then.')
focus = 0
talk_start = 0
end
end


function onCreatureTurn(creature)

end


function msgcontains(txt, str)
return (string.find(txt, str) and not string.find(txt, '(%w+)' .. str) and not string.find(txt, str .. '(%w+)'))
end


function oncreatureSay(cid, type, msg)
msg = string.lower(msg)

if (msgcontains(msg, 'hi') and (focus == 0)) and getDistanceToCreature(cid) < 4 then
selfSay('Hello ' .. getPlayerName(cid) .. '! I buy beginners items.')
focus = cid
talk_start = os.clock()

elseif msgcontains(msg, 'hi') and (focus ~= cid) and getDistanceToCreature(cid) < 4 then
selfSay('Sorry, ' .. getPlayerName(cid) .. '! I talk to you in a minute.')

elseif focus == cid then
talk_start = os.clock()

if msgcontains(msg, 'armor') then
selfSay('Do you want to buy Juggernuts armor, for just 10 miljons?')
talk_state = 1
end

elseif msgcontains(msg, 'helmet') then
selfSay('Do you want to buy Juggernuts helmet, for just 5 miljons?')
talk_state = 2

elseif talk_state == 1 then
if msgcontains(msg, 'yes') then
if doPlayerBuyItem(cid, 2656, 1, 10000000) ~= LUA_ERROR then
    selfSay('Thank you for buying this armor!')
else
    selfSay('Sorry, you do not have enough money.')
end
end
end
end
talk_state = 0

elseif talk_state == 2 then
if msgcontains(msg, 'yes') then
if doPlayerBuyItem(cid, 2663, 1, 5000000) ~= LUA_ERROR then
    selfSay('Thank you for buying this helmet!')
else
    selfSay('Sorry, you do not have enough money.')
end
end
talk_state = 0

elseif msgcontains(msg, 'bye') and getDistanceToCreature(cid) < 4 then
selfSay('Good bye, ' .. creatureGetName(cid) .. '!')
focus = 0
talk_start = 0
end
end
end



function onThink()
doNpcSetCreatureFocus(focus)
if (os.clock() - talk_start) > 30 then
if focus > 0 then
selfSay('Next Please...')
end
focus = 0
end
if focus ~= 0 then
if getDistanceToCreature(focus) > 5 then
selfSay('Good bye then.')
focus = 0
end
end
end
 
PHP:
local focus = 0
local talk_start = 0
local target = 0
local days = 0

function onThingMove(creature, thing, oldpos, oldstackpos)

end


function onCreatureAppear(creature)

end


function onCreatureDisappear(cid, pos)
	if focus == cid then
		selfSay('Good bye then.')
		focus = 0
		talk_start = 0
	end
end


function onCreatureTurn(creature)

end


function msgcontains(txt, str)
	return (string.find(txt, str) and not string.find(txt, '(%w+)' .. str) and not string.find(txt, str .. '(%w+)'))
end


function oncreatureSay(cid, type, msg)
	msg = string.lower(msg)

	if (msgcontains(msg, 'hi') and (focus == 0)) and getDistanceToCreature(cid) < 4 then
		selfSay('Hello ' .. getPlayerName(cid) .. '! I buy beginners items.')
		focus = cid
		talk_start = os.clock()

	elseif msgcontains(msg, 'hi') and (focus ~= cid) and getDistanceToCreature(cid) < 4 then
		selfSay('Sorry, ' .. getPlayerName(cid) .. '! I talk to you in a minute.')

	elseif focus == cid then

		if msgcontains(msg, 'armor') then
			selfSay('Do you want to buy Juggernuts armor, for just 10 miljons?')
			talk_state = 1
			
		elseif msgcontains(msg, 'helmet') then
			selfSay('Do you want to buy Juggernuts helmet, for just 5 miljons?')
			talk_state = 2

		elseif talk_state == 1 then
			if msgcontains(msg, 'yes') then
				if doPlayerBuyItem(cid, 2656, 1, 10000000) ~= LUA_ERROR then
					selfSay('Thank you for buying this armor!')
				else
					selfSay('Sorry, you do not have enough money.')
				end
			end
			talk_state = 0
			
		elseif talk_state == 2 then
			if msgcontains(msg, 'yes') then
				if doPlayerBuyItem(cid, 2663, 1, 5000000) ~= LUA_ERROR then
					selfSay('Thank you for buying this helmet!')
				else
					selfSay('Sorry, you do not have enough money.')
				end
				talk_state = 0
			end
			
		elseif msgcontains(msg, 'bye') and getDistanceToCreature(cid) < 4 then
			selfSay('Good bye, ' .. creatureGetName(cid) .. '!')
			focus = 0
			talk_start = 0
		end
	end
end



function onThink()
	doNpcSetCreatureFocus(focus)
	if (os.clock() - talk_start) > 30 then
		if focus > 0 then
			selfSay('Next Please...')
		end
		focus = 0
	end
	if focus ~= 0 then
		if getDistanceToCreature(focus) > 5 then
			selfSay('Good bye then.')
			focus = 0
		end
	end
end

try that
 
Btw, here's an update and fully working change gold, now tested!
PHP:
function onUse(cid, item, frompos, item2, topos)
    table.sort(money, function(a, b) return a.value < b.value end)
    for k, moneyInfo in pairs(money) do
        if item.itemid == moneyInfo.itemid then
            local previousItem = money[k - 1]
            local nextItem = money[k + 1]
            if item.type < 100 or nextItem == nil then
                if previousItem == nil and nextItem ~= nil then
                    doPlayerSendTextMessage(cid, 22, "You have to got 100 " .. moneyInfo.name .. "'s to change for 1 " .. nextItem.name .. ".")
                else
					doRemoveItem(item.uid, 1)
					doPlayerAddItem(cid, previousItem.itemid, 100)
                    doPlayerSendTextMessage(cid, 22, "You have changed a " .. moneyInfo.name .. " to 100 " .. previousItem.name .. ".")
                end
            elseif item.type == 100 and nextItem ~= nil then
				doTransformItem(item.uid, nextItem.itemid)
                doChangeTypeItem(item.uid, 1)
                doPlayerSendTextMessage(cid,22, "You have changed 100 " .. moneyInfo.name .. "'s to 1 " .. nextItem.name .. ".")
            end
        end
    end
    return TRUE
end
 
Back
Top