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

Error install [OTClient Mod] Loot stats in mehah otclient

Michcol94

Member
Joined
Sep 2, 2021
Messages
105
Reaction score
18
This is a link to the topic with the module:
MOD


Trying to add the [OTClient Mod] Loot stats module to my otclient mehah version, downloaded from here and compiled from GitHub - mehah/otclient: An alternative tibia client for otserv written in C++20 and Lua, made with a modular system that uses lua scripts for ingame interface and functionality, making otclient flexible and easy to customize (https://github.com/mehah/otclient)
Unfortunately, I have a problem, the first one I think I solved was the wrong path to the icons, here are the screenshots:

Zrzut ekranu 2023-12-13 173148.png
Zrzut ekranu 2023-12-13 173050.png
I copied the /img folder with its contents to the /-OTClient-Mod-loot_stats folder as shown in the screenshot:
Zrzut ekranu 2023-12-13 173616.png
Now when I turn on the client and log in, I have a second problem that I cannot solve, this is a screenshot of errors in otclient:
Zrzut ekranu 2023-12-13 174431.png
This is what the contents of the folder and the path to the files look like:





Zrzut ekranu 2023-12-13 173735.png


content of createStats.lua link file:
Create Stats.lua
Lines 1 to 65 that cause the error:
Lua:
function CreateStats()
    local createStats = {
        loadedVersionItems = 0;
        ownParser = false;

        _loadClientVersionItems = nil;
        _checkLootTextMessage = nil;

        init = function(self)
            self._loadClientVersionItems = function() self:loadClientVersionItems() end
            self._checkLootTextMessage = function(messageMode, message) self:checkLootTextMessage(messageMode, message) end

            connect(g_game, { onClientVersionChange = self._loadClientVersionItems })
            connect(g_game, { onTextMessage = self._checkLootTextMessage })

            if (self.loadedVersionItems == 0 and g_game.getClientVersion() ~= 0) or (g_game.getClientVersion() ~= 0 and self.loadedVersionItems ~= g_game.getClientVersion()) then
                self:loadClientVersionItems()
            end
        end;

        terminate = function(self)
            disconnect(g_game, { onClientVersionChange = self._loadClientVersionItems })
            disconnect(g_game, { onTextMessage = self._checkLootTextMessage })
        end;

        -- Load items

        loadClientVersionItems = function(self)
            local version = g_game.getClientVersion()

            if version ~= self.loadedVersionItems then
                if not directoryExists('items_versions/' .. version) then
                    pwarning("Directory: items_versions/" .. version .. "/ doesn't exist!")
                    pwarning("Add " .. version .. " directory to items_versions/ with correct version items.otb and items.xml!")
                    self.loadedVersionItems = 0
                    g_modules.getModule('loot_stats'):unload()
                    modules.client_modulemanager.refreshLoadedModules()
                    return
                end

                if not fileExists('items_versions/' .. version .. '/items.otb') then
                    pwarning("File: items_versions/" .. version .. "/ doesn't exist!")
                    pwarning("Add correct version items.otb to items_versions/" .. version .. "/!")
                    self.loadedVersionItems = 0
                    g_modules.getModule('loot_stats'):unload()
                    modules.client_modulemanager.refreshLoadedModules()
                    return
                end

                if not fileExists('items_versions/' .. version .. '/items.xml') then
                    pwarning("File: items_versions/" .. version .. " doesn't exist!")
                    pwarning("Add correct version items.xml to items_versions/" .. version .. "/!")
                    self.loadedVersionItems = 0
                    g_modules.getModule('loot_stats'):unload()
                    modules.client_modulemanager.refreshLoadedModules()
                    return
                end

                loadOtb('items_versions/' .. version .. '/items.otb')
                loadXml('items_versions/' .. version .. '/items.xml')
                self:checkParserType()

                self.loadedVersionItems = version
            end
        end;

Finally, I will add that no part of the module appears and it does not work at all. I am using TFS Engine 1.5 by nekiro Downgrade 8.6 with the latest release on github mehah otclient. And I have custom items.otb items.xml files, which means that I edited them by adding new items, but they work normally with the client, so it shouldn't pose a problem, I think.
 
Last edited:
Well, I got to the point after a few changes to this point. Namely, I edited file paths and created folders such as in createStats.lua, for example, and now I have a problem that everything loads but a crash message appears when I run the client:
fileotb loaded
ERROR: invalid thing type, server id: 1
It's probably about paraserXML
Below is the edited createStats.lua file
Lua:
function CreateStats()
    local createStats = {
        loadedVersionItems = 0;
        ownParser = false;

        _loadClientVersionItems = nil;
        _checkLootTextMessage = nil;

        init = function(self)
            self._loadClientVersionItems = function() self:loadClientVersionItems() end
            self._checkLootTextMessage = function(messageMode, message) self:checkLootTextMessage(messageMode, message) end

            connect(g_game, { onClientVersionChange = self._loadClientVersionItems })
            connect(g_game, { onTextMessage = self._checkLootTextMessage })

            if (self.loadedVersionItems == 0 and g_game.getClientVersion() ~= 0) or (g_game.getClientVersion() ~= 0 and self.loadedVersionItems ~= g_game.getClientVersion()) then
                self:loadClientVersionItems()
            end
        end;

        terminate = function(self)
            disconnect(g_game, { onClientVersionChange = self._loadClientVersionItems })
            disconnect(g_game, { onTextMessage = self._checkLootTextMessage })
        end;

        -- Load items

        loadClientVersionItems = function(self)
            local version = g_game.getClientVersion()

            if version ~= self.loadedVersionItems then
                if not directoryExists('/mods/loot_stats/items_versions/' .. version) then
                    pwarning("Directory: items_versions/" .. version .. "/ doesn't exist!")
                    pwarning("Add " .. version .. " directory to items_versions/ with correct version items.otb and items.xml!")
                    self.loadedVersionItems = 0
                    g_modules.getModule('loot_stats'):unload()
                    modules.client_modulemanager.refreshLoadedModules()
                    return
                end

                if not fileExists('/mods/loot_stats/items_versions/' .. version .. '/items.otb') then
                    pwarning("File: items_versions/" .. version .. "/ doesn't exist!")
                    pwarning("Add correct version items.otb to items_versions/" .. version .. "/!")
                    self.loadedVersionItems = 0
                    g_modules.getModule('loot_stats'):unload()
                    modules.client_modulemanager.refreshLoadedModules()
                    return
                end

                if not fileExists('/mods/loot_stats/items_versions/' .. version .. '/items.xml') then
                    pwarning("File: items_versions/" .. version .. " doesn't exist!")
                    pwarning("Add correct version items.xml to items_versions/" .. version .. "/!")
                    self.loadedVersionItems = 0
                    g_modules.getModule('loot_stats'):unload()
                    modules.client_modulemanager.refreshLoadedModules()
                    return
                end

                loadOtb('/mods/loot_stats/items_versions/' .. version .. '/items.otb')
                print("plikotb zaladowany")
                loadXml('mods/loot_stats/systems/items_versions/' .. version .. '/items.xml')
                print("pliki xml zaladowane")
                self:checkParserType()

                self.loadedVersionItems = version
            end
        end;

        checkParserType = function(self)
            if g_things.findItemTypeByPluralName then
                self.ownParser = false
            else
                self.ownParser = ItemsXML()
                self.ownParser:parseItemsXML('items_versions/' .. g_game.getClientVersion() .. '/items.xml')
            end
        end;

        -- Convert plural to singular

        convertPluralToSingular = function(self, searchWord)
            if not self.ownParser then
                local item = g_things.findItemTypeByPluralName(searchWord)
                if not item:isNull() then
                    return item:getName()
                else
                    return false
                end
            else
                return self.ownParser:convertPluralToSingular(searchWord)
            end
        end;

        -- Parse message logs

        returnPluralNameFromLoot = function(lootMonsterName, itemWord)
            for a,b in pairs(store.lootStatsTable[lootMonsterName].loot) do
                if b.plural == itemWord then
                    return a
                end
            end

            return false
        end;

        checkLootTextMessage = function(self, messageMode, message)
            if self.loadedVersionItems == 0 then
                return
            end

            local fromLootValue, toLootValue = string.find(message, 'Loot of ')
            if toLootValue then
                -- Return monster
                local lootMonsterName = string.sub(message, toLootValue + 1, string.find(message, ':') - 1)
                local isAFromLootValue, isAToLootValue = string.find(lootMonsterName, 'a ')
                if isAToLootValue then
                    lootMonsterName = string.sub(lootMonsterName, isAToLootValue + 1, string.len(lootMonsterName))
                end

                local isANFromLootValue, isANToLootValue = string.find(lootMonsterName, 'an ')
                if isANToLootValue then
                    lootMonsterName = string.sub(lootMonsterName, isANToLootValue + 1, string.len(lootMonsterName))
                end

                -- If no monster then add monster to table
                if not store.lootStatsTable[lootMonsterName] then
                    store.lootStatsTable[lootMonsterName] = { loot = {}, count = 0 }
                end

                -- Update monster kill count information
                store.lootStatsTable[lootMonsterName].count = store.lootStatsTable[lootMonsterName].count + 1

                -- Return Loot
                local lootString = string.sub(message, string.find(message, ': ') + 2, string.len(message))

                -- If dot at the ned of sentence (OTS only), delete it
                if not store:getIgnoreLastSignWhenDot() then
                    if string.sub(lootString, string.len(lootString)) == '.' then
                        lootString = string.sub(lootString, 0, string.len(lootString) - 1)
                    end
                end

                local lootToScreen = {}
                for word in string.gmatch(lootString, '([^,]+)') do
                    -- Delete first space
                    if string.sub(word, 0, 1) == ' ' then
                        word = string.sub(word, 2, string.len(word))
                    end

                    -- Delete 'a ' / 'an '
                    local isAToLootValue, isAFromLootValue = string.find(word, 'a ')
                    if isAFromLootValue then
                        word = string.sub(word, isAFromLootValue + 1, string.len(word))
                    end

                    local isANToLootValue, isANFromLootValue = string.find(word, 'an ')
                    if isANFromLootValue then
                        word = string.sub(word, isANFromLootValue + 1, string.len(word))
                    end

                    -- Check is first sign is number
                    if type(tonumber(string.sub(word, 0, 1))) == 'number' then
                        local itemCount = tonumber(string.match(word, "%d+"))
                        local delFN, delLN = string.find(word, itemCount)
                        local itemWord = string.sub(word, delLN + 2)
                        local isPluralNameInLoot = self.returnPluralNameFromLoot(lootMonsterName, itemWord)

                        if isPluralNameInLoot then
                            if not store.lootStatsTable[lootMonsterName].loot[isPluralNameInLoot] then
                                store.lootStatsTable[lootMonsterName].loot[isPluralNameInLoot] = {}
                                store.lootStatsTable[lootMonsterName].loot[isPluralNameInLoot].count = 0
                            end

                            if not lootToScreen[isPluralNameInLoot] then
                                lootToScreen[isPluralNameInLoot] = {}
                                lootToScreen[isPluralNameInLoot].count = 0
                            end

                            store.lootStatsTable[lootMonsterName].loot[isPluralNameInLoot].count = store.lootStatsTable[lootMonsterName].loot[isPluralNameInLoot].count + itemCount
                            lootToScreen[isPluralNameInLoot].count = lootToScreen[isPluralNameInLoot].count + itemCount
                        else
                            local pluralNameToSingular = self:convertPluralToSingular(itemWord)
                            if pluralNameToSingular then
                                if not store.lootStatsTable[lootMonsterName].loot[pluralNameToSingular] then
                                    store.lootStatsTable[lootMonsterName].loot[pluralNameToSingular] = {}
                                    store.lootStatsTable[lootMonsterName].loot[pluralNameToSingular].count = 0
                                end

                                if not store.lootStatsTable[lootMonsterName].loot[pluralNameToSingular].plural then
                                    store.lootStatsTable[lootMonsterName].loot[pluralNameToSingular].plural = itemWord
                                end

                                if not lootToScreen[pluralNameToSingular] then
                                    lootToScreen[pluralNameToSingular] = {}
                                    lootToScreen[pluralNameToSingular].count = 0
                                end

                                store.lootStatsTable[lootMonsterName].loot[pluralNameToSingular].count = store.lootStatsTable[lootMonsterName].loot[pluralNameToSingular].count + itemCount
                                lootToScreen[pluralNameToSingular].count = lootToScreen[pluralNameToSingular].count + itemCount
                            else
                                if not store.lootStatsTable[lootMonsterName].loot[word] then
                                    store.lootStatsTable[lootMonsterName].loot[word] = {}
                                    store.lootStatsTable[lootMonsterName].loot[word].count = 0
                                end

                                if not lootToScreen[word] then
                                    lootToScreen[word] = {}
                                    lootToScreen[word].count = 0
                                end

                                store.lootStatsTable[lootMonsterName].loot[word].count = store.lootStatsTable[lootMonsterName].loot[word].count + 1
                                lootToScreen[word].count = lootToScreen[word].count + 1
                            end
                        end
                    else
                        if not store.lootStatsTable[lootMonsterName].loot[word] then
                            store.lootStatsTable[lootMonsterName].loot[word] = {}
                            store.lootStatsTable[lootMonsterName].loot[word].count = 0
                        end

                        if not lootToScreen[word] then
                            lootToScreen[word] = {}
                            lootToScreen[word].count = 0
                        end

                        store.lootStatsTable[lootMonsterName].loot[word].count = store.lootStatsTable[lootMonsterName].loot[word].count + 1
                        lootToScreen[word].count = lootToScreen[word].count + 1
                    end
                end

                store:addLootLog(lootToScreen)
                lootToScreen = {}
            end

            store:refreshLootStatsTable()
        end;
    }

    return createStats
end
Post automatically merged:

Reloading loot_stats
fileotb loaded
xml files loaded
Lua:
function CreateStats()
    local createStats = {
        loadedVersionItems = 0;
        ownParser = false;
        _loadClientVersionItems = nil;
        _checkLootTextMessage = nil;
        init = function(self)
            self._loadClientVersionItems = function() self:loadClientVersionItems() end
            self._checkLootTextMessage = function(messageMode, message) self:checkLootTextMessage(messageMode, message) end
            connect(g_game, { onClientVersionChange = self._loadClientVersionItems })
            connect(g_game, { onTextMessage = self._checkLootTextMessage })
            if (self.loadedVersionItems == 0 and g_game.getClientVersion() ~= 0) or (g_game.getClientVersion() ~= 0 and self.loadedVersionItems ~= g_game.getClientVersion()) then
                self:loadClientVersionItems()
            end
        end;
        terminate = function(self)
            disconnect(g_game, { onClientVersionChange = self._loadClientVersionItems })
            disconnect(g_game, { onTextMessage = self._checkLootTextMessage })
        end;
        -- Load items
        loadClientVersionItems = function(self)
            local version = g_game.getClientVersion()
            if version ~= self.loadedVersionItems then
                if not directoryExists('/mods/loot_stats/items_versions/' .. version) then
                    pwarning("Directory: items_versions/" .. version .. "/ doesn't exist!")
                    pwarning("Add " .. version .. " directory to items_versions/ with correct version items.otb and items.xml!")
                    self.loadedVersionItems = 0
                    g_modules.getModule('loot_stats'):unload()
                    modules.client_modulemanager.refreshLoadedModules()
                    return
                end
                if not fileExists('/mods/loot_stats/items_versions/' .. version .. '/items.otb') then
                    pwarning("File: items_versions/" .. version .. "/ doesn't exist!")
                    pwarning("Add correct version items.otb to items_versions/" .. version .. "/!")
                    self.loadedVersionItems = 0
                    g_modules.getModule('loot_stats'):unload()
                    modules.client_modulemanager.refreshLoadedModules()
                    return
                end
                if not fileExists('/mods/loot_stats/items_versions/' .. version .. '/items.xml') then
                    pwarning("File: items_versions/" .. version .. " doesn't exist!")
                    pwarning("Add correct version items.xml to items_versions/" .. version .. "/!")
                    self.loadedVersionItems = 0
                    g_modules.getModule('loot_stats'):unload()
                    modules.client_modulemanager.refreshLoadedModules()
                    return
                end
                loadOtb('/mods/loot_stats/items_versions/' .. version .. '/items.otb')
                print("fileotb loaded")
                loadXml('mods/loot_stats/systems/items_versions/' .. version .. '/items.xml')
                print("xml files loaded")
                self:checkParserType()
                self.loadedVersionItems = version
            end
        end;
        checkParserType = function(self)
            if g_things.findItemTypeByPluralName then
                self.ownParser = false
            else
                self.ownParser = ItemsXML()
                self.ownParser:parseItemsXML('items_versions/' .. g_game.getClientVersion() .. '/items.xml')
            end
        end;
        -- Convert plural to singular
        convertPluralToSingular = function(self, searchWord)
            if not self.ownParser then
                local item = g_things.findItemTypeByPluralName(searchWord)
                if not item:isNull() then
                    return item:getName()
                else
                    return false
                end
            else
                return self.ownParser:convertPluralToSingular(searchWord)
            end
        end;
        -- Parse message logs
        returnPluralNameFromLoot = function(lootMonsterName, itemWord)
            for a,b in pairs(store.lootStatsTable[lootMonsterName].loot) do
                if b.plural == itemWord then
                    return a
                end
            end
            return false
        end;
        checkLootTextMessage = function(self, messageMode, message)
            if self.loadedVersionItems == 0 then
                return
            end
            local fromLootValue, toLootValue = string.find(message, 'Loot of ')
            if toLootValue then
                -- Return monster
                local lootMonsterName = string.sub(message, toLootValue + 1, string.find(message, ':') - 1)
                local isAFromLootValue, isAToLootValue = string.find(lootMonsterName, 'a ')
                if isAToLootValue then
                    lootMonsterName = string.sub(lootMonsterName, isAToLootValue + 1, string.len(lootMonsterName))
                end
                local isANFromLootValue, isANToLootValue = string.find(lootMonsterName, 'an ')
                if isANToLootValue then
                    lootMonsterName = string.sub(lootMonsterName, isANToLootValue + 1, string.len(lootMonsterName))
                end
                -- If no monster then add monster to table
                if not store.lootStatsTable[lootMonsterName] then
                    store.lootStatsTable[lootMonsterName] = { loot = {}, count = 0 }
                end
                -- Update monster kill count information
                store.lootStatsTable[lootMonsterName].count = store.lootStatsTable[lootMonsterName].count + 1
                -- Return Loot
                local lootString = string.sub(message, string.find(message, ': ') + 2, string.len(message))
                -- If dot at the ned of sentence (OTS only), delete it
                if not store:getIgnoreLastSignWhenDot() then
                    if string.sub(lootString, string.len(lootString)) == '.' then
                        lootString = string.sub(lootString, 0, string.len(lootString) - 1)
                    end
                end
                local lootToScreen = {}
                for word in string.gmatch(lootString, '([^,]+)') do
                    -- Delete first space
                    if string.sub(word, 0, 1) == ' ' then
                        word = string.sub(word, 2, string.len(word))
                    end
                    -- Delete 'a ' / 'an '
                    local isAToLootValue, isAFromLootValue = string.find(word, 'a ')
                    if isAFromLootValue then
                        word = string.sub(word, isAFromLootValue + 1, string.len(word))
                    end
                    local isANToLootValue, isANFromLootValue = string.find(word, 'an ')
                    if isANFromLootValue then
                        word = string.sub(word, isANFromLootValue + 1, string.len(word))
                    end
                    -- Check is first sign is number
                    if type(tonumber(string.sub(word, 0, 1))) == 'number' then
                        local itemCount = tonumber(string.match(word, "%d+"))
                        local delFN, delLN = string.find(word, itemCount)
                        local itemWord = string.sub(word, delLN + 2)
                        local isPluralNameInLoot = self.returnPluralNameFromLoot(lootMonsterName, itemWord)
                        if isPluralNameInLoot then
                            if not store.lootStatsTable[lootMonsterName].loot[isPluralNameInLoot] then
                                store.lootStatsTable[lootMonsterName].loot[isPluralNameInLoot] = {}
                                store.lootStatsTable[lootMonsterName].loot[isPluralNameInLoot].count = 0
                            end
                            if not lootToScreen[isPluralNameInLoot] then
                                lootToScreen[isPluralNameInLoot] = {}
                                lootToScreen[isPluralNameInLoot].count = 0
                            end
                            store.lootStatsTable[lootMonsterName].loot[isPluralNameInLoot].count = store.lootStatsTable[lootMonsterName].loot[isPluralNameInLoot].count + itemCount
                            lootToScreen[isPluralNameInLoot].count = lootToScreen[isPluralNameInLoot].count + itemCount
                        else
                            local pluralNameToSingular = self:convertPluralToSingular(itemWord)
                            if pluralNameToSingular then
                                if not store.lootStatsTable[lootMonsterName].loot[pluralNameToSingular] then
                                    store.lootStatsTable[lootMonsterName].loot[pluralNameToSingular] = {}
                                    store.lootStatsTable[lootMonsterName].loot[pluralNameToSingular].count = 0
                                end
                                if not store.lootStatsTable[lootMonsterName].loot[pluralNameToSingular].plural then
                                    store.lootStatsTable[lootMonsterName].loot[pluralNameToSingular].plural = itemWord
                                end
                                if not lootToScreen[pluralNameToSingular] then
                                    lootToScreen[pluralNameToSingular] = {}
                                    lootToScreen[pluralNameToSingular].count = 0
                                end
                                store.lootStatsTable[lootMonsterName].loot[pluralNameToSingular].count = store.lootStatsTable[lootMonsterName].loot[pluralNameToSingular].count + itemCount
                                lootToScreen[pluralNameToSingular].count = lootToScreen[pluralNameToSingular].count + itemCount
                            else
                                if not store.lootStatsTable[lootMonsterName].loot[word] then
                                    store.lootStatsTable[lootMonsterName].loot[word] = {}
                                    store.lootStatsTable[lootMonsterName].loot[word].count = 0
                                end
                                if not lootToScreen[word] then
                                    lootToScreen[word] = {}
                                    lootToScreen[word].count = 0
                                end
                                store.lootStatsTable[lootMonsterName].loot[word].count = store.lootStatsTable[lootMonsterName].loot[word].count + 1
                                lootToScreen[word].count = lootToScreen[word].count + 1
                            end
                        end
                    else
                        if not store.lootStatsTable[lootMonsterName].loot[word] then
                            store.lootStatsTable[lootMonsterName].loot[word] = {}
                            store.lootStatsTable[lootMonsterName].loot[word].count = 0
                        end
                        if not lootToScreen[word] then
                            lootToScreen[word] = {}
                            lootToScreen[word].count = 0
                        end
                        store.lootStatsTable[lootMonsterName].loot[word].count = store.lootStatsTable[lootMonsterName].loot[word].count + 1
                        lootToScreen[word].count = lootToScreen[word].count + 1
                    end
                end
                store:addLootLog(lootToScreen)
                lootToScreen = {}
            end
            store:refreshLootStatsTable()
        end;
    }
    return createStats
end
Post automatically merged:

Zrzut ekranu 2023-12-18 135051.png
I LOG IN AND MARKED THE MONSTER AND I GOT THE MESSAGE
THE CLIENT IS HANGING
Post automatically merged:

plikotb LOADED
ERROR: invalid thing type, server id: 1
AFTER RESTARTING THE CLIENT, IT CRASHES AND THESE LOGS

change createStats.lua fix problem
]dofile('itemsXML.lua')function CreateStats() local createStats = { - Pastebin.com (https://pastebin.com/Wqq5K5d9)
The next problem displays only an image of a red x in flight, probably related to the ui.lua and showLootOnScreen.lua files, there are conditional instructions there
Post automatically merged:

Zrzut ekranu 2023-12-18 162227.png
 
Last edited:
After many hours of trying to analyze the code, I managed to come to something and finally make some progress. I'm a bit embarrassed by the lack of support from any side, I say otland and discord, let's get to the point of what I managed to do and what conclusions I reached. I managed to display the loot graphics on the screen and in the module statistics in the panel intended for this purpose, apart from the graphics whose loot was in the plural, it shouldn't be very difficult to do it anymore, I have a few solutions to this problem in my head, I don't even know what the results would be, but after analyzing this code and writing it by trial and error using various functions and methods of using them, writing my own, modifying the code, adding a new one, I tried everything and until I analyzed the code thoroughly, I did not find any solution and the effect was still the same and I stood still and wasted time, then this is an advice for others, sometimes it's better to spend some time on code analysis, if you don't fully understand programming, but you are still learning and the knowledge is really basic, you will definitely get a positive result, you will solve the problem faster and you can also learn something else only at the very end I realized and came to the conclusion that such a statistics system based on tables may be burdensome for the client, unless there is a large number of players and no resetting of the statistics data will store larger and larger tables unless it only adds the quantity to the name of the item because if each loot[ expands the tables indefinitely, it will grow to a large size, which can be troublesome, attack I really think that such a statistics system could be good for some rare items, after obtaining certain statistics we gain achievement, it would make some sense and what is such a system really for?
the loot stat system adds nothing and just wastes memory in my opinion. later, I will add changes to the code and the solution for someone who would also face the same problem as me, although I do not know whether my solution is consistent with the assumptions of the project and the logic in which the module was supposed to work, but it almost works.
Zrzut ekranu 2023-12-20 104247.pngZrzut ekranu 2023-12-20 104236.png
  1. I think that when I'm finished, I will simply add a publicly ready module to github for installation in otclient mehah
 
Do you solve it bro, i follow your instructions but got this:

Lua:
ERROR: protected lua call failed: C++ call failed: unable to open file '/mods/loot_stats/systems/items_versions/1098/items.xml': not found
stack traceback:
    [builtin#146]: at 0x0046e0b0
    [C]: in function 'readFileContents'
    /mods/loot_stats/systems/itemsXML.lua:9: in function 'parseItemsXML'
    /mods/loot_stats/systems/createStats.lua:85: in function 'loadClientVersionItems'
    /mods/loot_stats/systems/createStats.lua:21: in function </mods/loot_stats/systems/createStats.lua:21>
    [C]: in function 'setClientVersion'
    /modules/client_entergame/entergame.lua:538: in function 'doLogin'
    /modules/client_entergame/entergame.otui:167: [@onClick]:2: in function </modules/client_entergame/entergame.otui:167: [@onClick]:1>
 
Back
Top