• 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!

Lua Gold coin rate and gold coin to bank

E

Evil Puncker

Guest
Hey everyone, I was wondering on how to add a gold coin rate to my server (TFS 1.3), for example monsters would drop 2x gold coins etc, I found a way to do it but since it is done AFTER the loot is created, the loot message is ugly (not accurate), so I would like to know how to do it BEFORE the loot is created (maybe is this file?)


second one: would it be possible as well to make all money (2148, 2152, 2160) dropped by monsters, be sent to bank (p:setBankBalance) for all premium players?


thanks in advance to all moon experts in this forum (yes, "moon" is a joke)
😁
 
Solution
Yes, that is the correct file. I'm guessing you want it something along the likes of this?

Lua:
function Monster:onDropLoot(corpse)
	if configManager.getNumber(configKeys.RATE_LOOT) == 0 then
		return
	end

	local currencies = {
		2148 = 1, 
		2152 = 100, 
		2160 = 10000
	}

	local player = Player(corpse:getCorpseOwner())
	local mType = self:getType()
	if not player or player:getStamina() > 840 then
		local currencyTransferAmount = 0
		
		local monsterLoot = mType:getLoot()
		for i = 1, #monsterLoot do
			local item = corpse:createLootItem(monsterLoot[i])
			if not item then
				print('[Warning] DropLoot:', 'Could not add loot item to corpse.')
			else
				if currencies[item:getType():getId()] ~= nil then
					if player and player:isPremium()...
Yes, that is the correct file. I'm guessing you want it something along the likes of this?

Lua:
function Monster:onDropLoot(corpse)
	if configManager.getNumber(configKeys.RATE_LOOT) == 0 then
		return
	end

	local currencies = {
		2148 = 1, 
		2152 = 100, 
		2160 = 10000
	}

	local player = Player(corpse:getCorpseOwner())
	local mType = self:getType()
	if not player or player:getStamina() > 840 then
		local currencyTransferAmount = 0
		
		local monsterLoot = mType:getLoot()
		for i = 1, #monsterLoot do
			local item = corpse:createLootItem(monsterLoot[i])
			if not item then
				print('[Warning] DropLoot:', 'Could not add loot item to corpse.')
			else
				if currencies[item:getType():getId()] ~= nil then
					if player and player:isPremium() then
						currencyTransferAmount = currencyTransferAmount + (item:getCount() * currencies[item:getType():getId()])
						item:remove()
					end
				end
			end
		end

		if player then
			if player:isPremium() and currencyTransferAmount > 0 then 
				player:setBankBalance(player:getBankBalance() + currencyTransferAmount)
				player:sendTextMessage(MESSAGE_LOOT, "Premium: " .. currencyTransferAmount .. " gp was automatically looted and transferred to your bank account.")
			end
			local text = ("Loot of %s: %s"):format(mType:getNameDescription(), corpse:getContentDescription())
			local party = player:getParty()
			if party then
				party:broadcastPartyLoot(text)
			else
				player:sendTextMessage(MESSAGE_LOOT, text)
			end
		end
	else
		local text = ("Loot of %s: nothing (due to low stamina)"):format(mType:getNameDescription())
		local party = player:getParty()
		if party then
			party:broadcastPartyLoot(text)
		else
			player:sendTextMessage(MESSAGE_LOOT, text)
		end
	end
end

Change revisions:
 
Last edited:
Solution
Yes, that is the correct file. I'm guessing you want it something along the likes of this?

Change revisions:

thanks! I only got my hands into testing it now 😁 had to change

Lua:
local currencies = {
        2148 = 1,
        2152 = 100,
        2160 = 10000
    }

to

Lua:
local currencies = {
        [2148] = 1,
        [2152] = 100,
        [2160] = 10000
    }

but it still give me an error when killing a monster:
2020-01-31 01_16_17-Window.png
 
Lua:
function Monster:onDropLoot(corpse)
    if configManager.getNumber(configKeys.RATE_LOOT) == 0 then
        return
    end

    local currencies = {
        [2148] = 1,
        [2152] = 100,
        [2160] = 10000
    }

    local player = Player(corpse:getCorpseOwner())
    local mType = self:getType()
    if not player or player:getStamina() > 840 then
        local currencyTransferAmount = 0
        
        local monsterLoot = mType:getLoot()
        for i = 1, #monsterLoot do
            local item = corpse:createLootItem(monsterLoot[i])
            if item then
                print(item.itemid)
                if currencies[item:getType():getId()] ~= nil then
                print("coins")
                    if player and player:isPremium() then
                        currencyTransferAmount = currencyTransferAmount + (item:getCount() * currencies[item:getType():getId()])
                        item:remove()
                    end
                end
            else
                print('[Warning] DropLoot:', 'Could not add loot item to corpse.')
            end
        end

        if player then
            if player:isPremium() and currencyTransferAmount > 0 then
                player:setBankBalance(player:getBankBalance() + currencyTransferAmount)
                player:sendTextMessage(MESSAGE_LOOT, "Premium: " .. currencyTransferAmount .. " gp was automatically looted and transferred to your bank account.")
            end
            local text = ("Loot of %s: %s"):format(mType:getNameDescription(), corpse:getContentDescription())
            local party = player:getParty()
            if party then
                party:broadcastPartyLoot(text)
            else
                player:sendTextMessage(MESSAGE_LOOT, text)
            end
        end
    else
        local text = ("Loot of %s: nothing (due to low stamina)"):format(mType:getNameDescription())
        local party = player:getParty()
        if party then
            party:broadcastPartyLoot(text)
        else
            player:sendTextMessage(MESSAGE_LOOT, text)
        end
    end
end
 
Last edited:
Try this, post the error/print messages:
Lua:
function Monster:onDropLoot(corpse)
    if configManager.getNumber(configKeys.RATE_LOOT) == 0 then
        return
    end

    local currencies = {
        [2148] = 1,
        [2152] = 100,
        [2160] = 10000
    }

    local player = Player(corpse:getCorpseOwner())
    local mType = self:getType()
    if not player or player:getStamina() > 840 then
        local currencyTransferAmount = 0
      
        local monsterLoot = mType:getLoot()
        for i = 1, #monsterLoot do
            local itemList = corpse:createLootItem(monsterLoot[i])
            print("itemList: " .. itemList)
            if not itemList then
                print('[Warning] DropLoot:', 'Could not add loot item to corpse.')
            else
                for _, item in ipairs(itemList) do
                    print("item: " ..item)
                    if currencies[item:getType():getId()] ~= nil then
                        print("Money detected: " .. item:getType():getId())
                        if player and player:isPremium() then
                            currencyTransferAmount = currencyTransferAmount + (item:getCount() * currencies[item:getType():getId()])
                            item:remove()
                        end
                    end
                end
            end
        end

        if player then
            if player:isPremium() and currencyTransferAmount > 0 then
                player:setBankBalance(player:getBankBalance() + currencyTransferAmount)
                player:sendTextMessage(MESSAGE_LOOT, "Premium: " .. currencyTransferAmount .. " gp was automatically looted and transferred to your bank account.")
            end
            local text = ("Loot of %s: %s"):format(mType:getNameDescription(), corpse:getContentDescription())
            local party = player:getParty()
            if party then
                party:broadcastPartyLoot(text)
            else
                player:sendTextMessage(MESSAGE_LOOT, text)
            end
        end
    else
        local text = ("Loot of %s: nothing (due to low stamina)"):format(mType:getNameDescription())
        local party = player:getParty()
        if party then
            party:broadcastPartyLoot(text)
        else
            player:sendTextMessage(MESSAGE_LOOT, text)
        end
    end
end
data/events/scripts/monster.lua:20: attempt to concatenate local 'itemList' (a boolean value)
 
data/events/scripts/monster.lua:20: attempt to concatenate local 'itemList' (a boolean value)

Edited.

Try that.
 
Edited.

Try that.
data/events/scripts/monster.lua:21: attempt to index local 'item' (a boolean value)

😭
 
@Evil Puncker Appears to actually be an issue with TFS 1.3 libs, Container.createLootItem doesn't actually return the item, which it should do in my opinion. (and does on the otbr/otx version).

Go into data/lib/core/container.lua and replace function Container.createLootItem(self, item) with this:
Lua:
function Container.createLootItem(self, item)
    if self:getEmptySlots() == 0 then
        return true, nil
    end

    local itemCount = 0
    local randvalue = getLootRandom()
    if randvalue < item.chance then
        if ItemType(item.itemId):isStackable() then
            itemCount = randvalue % item.maxCount + 1
        else
            itemCount = 1
        end
    end

    if itemCount == 0 then
        return false, nil
    end

    local tmpItem = self:addItem(item.itemId, math.min(itemCount, 100))
    if not tmpItem then
        return false, nil
    end

    if tmpItem:isContainer() then
        for i = 1, #item.childLoot do
            if not tmpItem:createLootItem(item.childLoot[i]) then
                tmpItem:remove()
                return false, nil
            end
        end
    end

    if item.subType ~= -1 then
        tmpItem:setAttribute(ITEM_ATTRIBUTE_CHARGES, item.subType)
    end

    if item.actionId ~= -1 then
        tmpItem:setActionId(item.actionId)
    end

    if item.text and item.text ~= "" then
        tmpItem:setText(item.text)
    end

    return true, tmpItem
end
It should hopefully retain default behavior of createLootItem in TFS 1.3 without breaking any other scripts, as well as return the item if it was added and created as a corpse item.

And in our code, replace:
Lua:
local item = corpse:createLootItem(monsterLoot[i])

With:
Lua:
local status, item = corpse:createLootItem(monsterLoot[i])

You might also need to replace item.itemid with item.itemId .
 
@Evil Puncker Appears to actually be an issue with TFS 1.3 libs, Container.createLootItem doesn't actually return the item, which it should do in my opinion. (and does on the otbr/otx version).

Go into data/lib/core/container.lua and replace function Container.createLootItem(self, item) with this:
Lua:
function Container.createLootItem(self, item)
    if self:getEmptySlots() == 0 then
        return true, nil
    end

    local itemCount = 0
    local randvalue = getLootRandom()
    if randvalue < item.chance then
        if ItemType(item.itemId):isStackable() then
            itemCount = randvalue % item.maxCount + 1
        else
            itemCount = 1
        end
    end

    if itemCount == 0 then
        return false, nil
    end

    local tmpItem = self:addItem(item.itemId, math.min(itemCount, 100))
    if not tmpItem then
        return false, nil
    end

    if tmpItem:isContainer() then
        for i = 1, #item.childLoot do
            if not tmpItem:createLootItem(item.childLoot[i]) then
                tmpItem:remove()
                return false, nil
            end
        end
    end

    if item.subType ~= -1 then
        tmpItem:setAttribute(ITEM_ATTRIBUTE_CHARGES, item.subType)
    end

    if item.actionId ~= -1 then
        tmpItem:setActionId(item.actionId)
    end

    if item.text and item.text ~= "" then
        tmpItem:setText(item.text)
    end

    return true, tmpItem
end
It should hopefully retain default behavior of createLootItem in TFS 1.3 without breaking any other scripts, as well as return the item if it was added and created as a corpse item.

And in our code, replace:
Lua:
local item = corpse:createLootItem(monsterLoot[i])

With:
Lua:
local status, item = corpse:createLootItem(monsterLoot[i])

You might also need to replace item.itemid with item.itemId .
thanks, working like a charm, and about the container file, what about a PR? :p I see no harm

@edit
it is now triggering the print:

[Warning] DropLoot: Could not add loot item to corpse.
 
Back
Top