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

[Module] - Loot Simulator - TFS 1.5

Rondel

Active Member
Joined
Feb 1, 2022
Messages
12
Reaction score
30
Hey there!
Balancing loot is quite a tedious task - it's easy to make mistakes and accidentally add an extra zero somewhere. It's always helpful to see how things actually look in-game, so to make life a bit easier for everyone, I've made this module. After following the installation steps, you'll need to populate the monsters array with all the monsters from your /monsters folder aswell as the items.lua file from game_lootsimulator folder with all the values.

Show-off
s1.png
s2.png
s3.png
s5.png

How to install
1. Server
1.1. Add to -> /lib/core/container.lua
Lua:
function Container.createSimulationLootItem(self, item, rateLoot)
    if self:getEmptySlots() == 0 then
        return true
    end

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

    while itemCount > 0 do
        local count = math.min(100, itemCount)
      
        local subType = count
        if itemType:isFluidContainer() then
            subType = math.max(0, item.subType)
        end
      
        local tmpItem = Game.createItem(item.itemId, subType)
        if not tmpItem then
            return false
        end

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

            if #item.childLoot > 0 and tmpItem:getSize() == 0 then
                tmpItem:remove()
                return true
            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

        local ret = self:addItemEx(tmpItem)
        if ret ~= RETURNVALUE_NOERROR then
            tmpItem:remove()
        end

        itemCount = itemCount - count
    end
    return true
end
1.2. Add to -> /global.lua
Code:
function getLootSimulationRandom(rateLoot)
    return math.random(0, MAX_LOOTCHANCE) / rateLoot
end
1.3. Add to -> /data/scripts -> lootSimulator.lua file from the folder.
2. Client
2.1. Add to -> /modules -> the game_lootsimulator folder.

To open the simulator window press 'CTRL + S'

I do believe that's all but I might have forgotten about something so if anything is missing, let me know. Enjoy ;3
 

Attachments

Last edited:
Neat. I modified it to send all monsters on the map for testing purposes because I didn't want to have to manually add all my monsters to an array ;)
I also modified it to send the value of the item because since I didn't want to do that manually either ;)
And with that it's a solid release. One thing that seems a bit interesting is how the "Chance" field is calculated.
For example comparing 30500 ancient scarabs to tibiawiki the avg, kills to get and count all seem to be within the margin of error but the chance is way off. For example the chance on tibiawiki is stated as 5% while the simulator calculates the chance to 15%
I didn't look into it but it's probably just related to the chance is calculated.
 
Cool module, will make configuring a lot easier, thanks for sharing!

Pro tip, if you have all monsters in one folder, just select them all, press shift and right mouse button, select "copy as path" and paste it into some text editor. Then just change (usually ctrl+h) the paths that you have.
Change it "C:\Users\user\ots\data\monster\monsters\dragon_lord.xml" like this:

"C:\Users\user\ots\data\monster\monsters\
to
"
then
.xml" (and possibly .lua" too if you have them)
to
",
and
_
to
(space)

Then paste it into the script.

Done in 3 minutes, instead of hours making it manually.
 
You can also just edit the script to get all monsterTypes and loop over those
 
Alright, I've slightly updated the script following @Nigtwisj suggestion - it now loads in all available monsters from your server. I've also converted the script to a non-revscript version and added a README file to each folder so you can install it without any issues. Cheers!

Important!
You need to add both functions from original post! (createSimulationLootItem, getLootSimulationRandom)

 

Attachments

Last edited:
if someone uses mehah and has this error.
Code:
/game_lootsimulator/lootsimulator.lua:375: attempt to call method 'getOutfit' (a nil value)

you should change
L375
Code:
widget:setOutfit(focusedChild.creature:getOutfit())
to
Lua:
widget:setOutfit(focusedChild.creature:getCreature():getOutfit())


1715375680143.png->1715375714038.png
 
Last edited:
Is there a max number how many monsters are loaded into the simulator because some of my monsters are not loading and I have no idea why there are no errors in server console or client termial
 
Is there a max number how many monsters are loaded into the simulator because some of my monsters are not loading and I have no idea why there are no errors in server console or client termial
Nope, there is no limit. However, I've excluded monsters which have no loot.
 
Hmm, thats strange this monster has loot and I have also changed the monster which is not loading to a complete other monster (which is loading) and its still not loading
 
Well, I don't know what could be the issue then. The only way to find out would be to debug it.
 
Its kinda strange but with the old version where you have to put in the monster names manually there this monster is working. So I think I will stick to that version
 
You iterate over monstertypes correct? If that's the case then it won't find the monstertype unless that Monster is at least spawned once on the map, xml monsters Work that way
 
Back
Top