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

CreatureEvent [TFS 1.3 / 1.4] Upgrade System

Check your config, looks like you missed or misspelled something.
i have no messed any in the config file also got this

C++:
Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
data/upgrade_system_core.lua:1517: attempt to call a nil value (field 'pow')
stack traceback:
        [C]: in field 'pow'
        data/upgrade_system_core.lua:1517: in method 'calculateItemLevel'
        data/upgrade_system_core.lua:897: in function 'us_CheckCorpse'
 
i think when open monsters corpses
Post automatically merged:

when monster dies:

C++:
Lua Script Error: [Main Interface]
in a timer event called from:
(Unknown scriptfile)
data/upgrade_system_core.lua:1517: attempt to call a nil value (field 'pow')
stack traceback:
        [C]: in field 'pow'
        data/upgrade_system_core.lua:1517: in method 'calculateItemLevel'
        data/upgrade_system_core.lua:897: in function 'us_CheckCorpse'
upgrade_system_core.lua:1517:
Lua:
  level = math.ceil(math.pow(monsterValue, 0.478))

upgrade_system_core.lua:897:
Lua:
 local iLvl = monsterType:calculateItemLevel()
 
@oen432 and if i use look on myself got item level: 0
maybe something wrong on my player.lua?
Lua:
function Player:onBrowseField(position)
    return true
end

function Player:onLook(thing, position, distance)
    local description = "You see " .. thing:getDescription(distance) description = onItemUpgradeLook(self, thing, position, distance, description)
    
    if self:getGroup():getAccess() then
        if thing:isItem() then
            description = string.format("%s\nItem ID: %d", description, thing:getId())

            local actionId = thing:getActionId()
            if actionId ~= 0 then
                description = string.format("%s, Action ID: %d", description, actionId)
            end

            local uniqueId = thing:getAttribute(ITEM_ATTRIBUTE_UNIQUEID)
            if uniqueId > 0 and uniqueId < 65536 then
                description = string.format("%s, Unique ID: %d", description, uniqueId)
            end

            local itemType = thing:getType()

            local transformEquipId = itemType:getTransformEquipId()
            local transformDeEquipId = itemType:getTransformDeEquipId()
            if transformEquipId ~= 0 then
                description = string.format("%s\nTransforms to: %d (onEquip)", description, transformEquipId)
            elseif transformDeEquipId ~= 0 then
                description = string.format("%s\nTransforms to: %d (onDeEquip)", description, transformDeEquipId)
            end

            local decayId = itemType:getDecayId()
            if decayId ~= -1 then
                description = string.format("%s\nDecays to: %d", description, decayId)
            end
        elseif thing:isCreature() then
            local str = "%s\nHealth: %d / %d"
            if thing:isPlayer() and thing:getMaxMana() > 0 then
                str = string.format("%s, Mana: %d / %d", str, thing:getMana(), thing:getMaxMana())
            end
            description = string.format(str, description, thing:getHealth(), thing:getMaxHealth()) .. "."
        end

        local position = thing:getPosition()
        description = string.format(
            "%s\nPosition: %d, %d, %d",
            description, position.x, position.y, position.z
        )

        if thing:isCreature() then
            if thing:isPlayer() then
                description = string.format("%s\nIP: %s.", description, Game.convertIpToString(thing:getIp()))
            end
        end
    end
    self:sendTextMessage(MESSAGE_INFO_DESCR, description)
    if thing:isCreature() then
        if thing:isPlayer() then
            description = string.format("%s\nTask Rank: "..getRankTask(thing), description)
        end
    end
end

function Player:onLookInBattleList(creature, distance)
    local description = "You see " .. creature:getDescription(distance)
    if self:getGroup():getAccess() then
        local str = "%s\nHealth: %d / %d"
        if creature:isPlayer() and creature:getMaxMana() > 0 then
            str = string.format("%s, Mana: %d / %d", str, creature:getMana(), creature:getMaxMana())
        end
        description = string.format(str, description, creature:getHealth(), creature:getMaxHealth()) .. "."

        local position = creature:getPosition()
        description = string.format(
            "%s\nPosition: %d, %d, %d",
            description, position.x, position.y, position.z
        )

        if creature:isPlayer() then
            description = string.format("%s\nIP: %s", description, Game.convertIpToString(creature:getIp()))
        end
    end
    self:sendTextMessage(MESSAGE_INFO_DESCR, description)
end

function Player:onLookInTrade(partner, item, distance)
    self:sendTextMessage(MESSAGE_INFO_DESCR, "You see " .. item:getDescription(distance))
end

function Player:onLookInShop(itemType, count)
    return true
end

function Player:onMoveItem(item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    if item:getAttribute("wrapid") ~= 0 then
        local tile = Tile(toPosition)
        if (fromPosition.x ~= CONTAINER_POSITION and toPosition.x ~= CONTAINER_POSITION) or tile and not tile:getHouse() then
            if tile and not tile:getHouse() then
                self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
                return false
            end
        end
    end

    if toPosition.x ~= CONTAINER_POSITION then
        return true
    end

    if item:getTopParent() == self and bit.band(toPosition.y, 0x40) == 0 then
        local itemType, moveItem = ItemType(item:getId())
        if bit.band(itemType:getSlotPosition(), SLOTP_TWO_HAND) ~= 0 and toPosition.y == CONST_SLOT_LEFT then
            moveItem = self:getSlotItem(CONST_SLOT_RIGHT)
        elseif itemType:getWeaponType() == WEAPON_SHIELD and toPosition.y == CONST_SLOT_RIGHT then
            moveItem = self:getSlotItem(CONST_SLOT_LEFT)
            if moveItem and bit.band(ItemType(moveItem:getId()):getSlotPosition(), SLOTP_TWO_HAND) == 0 then
                return us_onMoveItem(self, item, fromPosition, toPosition)
            end
        end

        if moveItem then
            local parent = item:getParent()
            if parent:isContainer() and parent:getSize() == parent:getCapacity() then
                self:sendTextMessage(MESSAGE_STATUS_SMALL, Game.getReturnMessage(RETURNVALUE_CONTAINERNOTENOUGHROOM))
                return false
            else
                return moveItem:moveTo(parent)
            end
        end
    end

    return us_onMoveItem(self, item, fromPosition, toPosition)
end

function Player:onItemMoved(item, count, fromPosition, toPosition, fromCylinder, toCylinder)
onUpgradeMoved(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder)
end

function Player:onMoveCreature(creature, fromPosition, toPosition)
    return true
end

local function hasPendingReport(name, targetName, reportType)
    local f = io.open(string.format("data/reports/players/%s-%s-%d.txt", name, targetName, reportType), "r")
    if f then
        io.close(f)
        return true
    else
        return false
    end
end

function Player:onReportRuleViolation(targetName, reportType, reportReason, comment, translation)
    local name = self:getName()
    if hasPendingReport(name, targetName, reportType) then
        self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your report is being processed.")
        return
    end

    local file = io.open(string.format("data/reports/players/%s-%s-%d.txt", name, targetName, reportType), "a")
    if not file then
        self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "There was an error when processing your report, please contact a gamemaster.")
        return
    end

    io.output(file)
    io.write("------------------------------\n")
    io.write("Reported by: " .. name .. "\n")
    io.write("Target: " .. targetName .. "\n")
    io.write("Type: " .. reportType .. "\n")
    io.write("Reason: " .. reportReason .. "\n")
    io.write("Comment: " .. comment .. "\n")
    if reportType ~= REPORT_TYPE_BOT then
        io.write("Translation: " .. translation .. "\n")
    end
    io.write("------------------------------\n")
    io.close(file)
    self:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("Thank you for reporting %s. Your report will be processed by %s team as soon as possible.", targetName, configManager.getString(configKeys.SERVER_NAME)))
    return
end

function Player:onReportBug(message, position, category)
    if self:getAccountType() == ACCOUNT_TYPE_NORMAL then
        return false
    end

    local name = self:getName()
    local file = io.open("data/reports/bugs/" .. name .. " report.txt", "a")

    if not file then
        self:sendTextMessage(MESSAGE_EVENT_DEFAULT, "There was an error when processing your report, please contact a gamemaster.")
        return true
    end

    io.output(file)
    io.write("------------------------------\n")
    io.write("Name: " .. name)
    if category == BUG_CATEGORY_MAP then
        io.write(" [Map position: " .. position.x .. ", " .. position.y .. ", " .. position.z .. "]")
    end
    local playerPosition = self:getPosition()
    io.write(" [Player Position: " .. playerPosition.x .. ", " .. playerPosition.y .. ", " .. playerPosition.z .. "]\n")
    io.write("Comment: " .. message .. "\n")
    io.close(file)

    self:sendTextMessage(MESSAGE_EVENT_DEFAULT, "Your report has been sent to " .. configManager.getString(configKeys.SERVER_NAME) .. ".")
    return true
end

function Player:onTurn(direction)
    return true
end

function Player:onTradeRequest(target, item)
    return true
end

function Player:onTradeAccept(target, item, targetItem)
    return true
end

function Player:onTradeCompleted(target, item, targetItem, isSuccess)
    return
end

local soulCondition = Condition(CONDITION_SOUL, CONDITIONID_DEFAULT)
soulCondition:setTicks(4 * 60 * 1000)
soulCondition:setParameter(CONDITION_PARAM_SOULGAIN, 1)

local function useStamina(player)
    local staminaMinutes = player:getStamina()
    if staminaMinutes == 0 then
        return
    end

    local playerId = player:getId()
    local currentTime = os.time()
    local timePassed = currentTime - nextUseStaminaTime[playerId]
    if timePassed <= 0 then
        return
    end

    if timePassed > 60 then
        if staminaMinutes > 2 then
            staminaMinutes = staminaMinutes - 2
        else
            staminaMinutes = 0
        end
        nextUseStaminaTime[playerId] = currentTime + 120
    else
        staminaMinutes = staminaMinutes - 1
        nextUseStaminaTime[playerId] = currentTime + 60
    end
    player:setStamina(staminaMinutes)
end

function Player:onGainExperience(source, exp, rawExp)
    if not source or source:isPlayer() then
    exp = us_onGainExperience(self, source, exp, rawExp)
        return exp
    end

    -- Soul regeneration
    local vocation = self:getVocation()
    if self:getSoul() < vocation:getMaxSoul() and exp >= self:getLevel() then
        soulCondition:setParameter(CONDITION_PARAM_SOULTICKS, vocation:getSoulGainTicks() * 1000)
        self:addCondition(soulCondition)
    end

    -- Apply experience stage multiplier
    exp = exp * Game.getExperienceStage(self:getLevel())

    -- Stamina modifier
    if configManager.getBoolean(configKeys.STAMINA_SYSTEM) then
        useStamina(self)

        local staminaMinutes = self:getStamina()
        if staminaMinutes > 2400 and self:isPremium() then
            exp = exp * 1.5
        elseif staminaMinutes <= 840 then
            exp = exp * 0.5
        end
    end

    return exp
end

function Player:onLoseExperience(exp)
    return exp
end

function Player:onGainSkillTries(skill, tries)
    if APPLY_SKILL_MULTIPLIER == false then
        return tries
    end

    if skill == SKILL_MAGLEVEL then
        return tries * configManager.getNumber(configKeys.RATE_MAGIC)
    end
    return tries * configManager.getNumber(configKeys.RATE_SKILL)
end

function Player:onWrapItem(item, position)
    local topCylinder = item:getTopParent()
    if not topCylinder then
        return
    end

    local tile = Tile(topCylinder:getPosition())
    if not tile then
        return
    end

    local house = tile:getHouse()
    if not house then
        self:sendCancelMessage("You can only wrap and unwrap this item inside a house.")
        return
    end

    if house ~= self:getHouse() and not string.find(house:getAccessList(SUBOWNER_LIST):lower(), "%f[%a]" .. self:getName():lower() .. "%f[%A]") then
        self:sendCancelMessage("You cannot wrap or unwrap items from a house, which you are only guest to.")
        return
    end

    local wrapId = item:getAttribute("wrapid")
    if wrapId == 0 then
        return
    end

    local oldId = item:getId()
    item:remove(1)
    local item = tile:addItem(wrapId)
    if item then
        item:setAttribute("wrapid", oldId)
    end
end
 
Just follow installation steps again, you did mess up something, somewhere.
 
@oen432 this is correct?

Lua:
function Player:onMoveItem(item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    if item:getAttribute("wrapid") ~= 0 then
        local tile = Tile(toPosition)
        if (fromPosition.x ~= CONTAINER_POSITION and toPosition.x ~= CONTAINER_POSITION) or tile and not tile:getHouse() then
            if tile and not tile:getHouse() then
                self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
                return false
            end
        end
    end

    if toPosition.x ~= CONTAINER_POSITION then
        return true
    end

    if item:getTopParent() == self and bit.band(toPosition.y, 0x40) == 0 then
        local itemType, moveItem = ItemType(item:getId())
        if bit.band(itemType:getSlotPosition(), SLOTP_TWO_HAND) ~= 0 and toPosition.y == CONST_SLOT_LEFT then
            moveItem = self:getSlotItem(CONST_SLOT_RIGHT)
        elseif itemType:getWeaponType() == WEAPON_SHIELD and toPosition.y == CONST_SLOT_RIGHT then
            moveItem = self:getSlotItem(CONST_SLOT_LEFT)
            if moveItem and bit.band(ItemType(moveItem:getId()):getSlotPosition(), SLOTP_TWO_HAND) == 0 then
                return us_onMoveItem(self, item, fromPosition, toPosition)
            end
        end

        if moveItem then
            local parent = item:getParent()
            if parent:isContainer() and parent:getSize() == parent:getCapacity() then
                self:sendTextMessage(MESSAGE_STATUS_SMALL, Game.getReturnMessage(RETURNVALUE_CONTAINERNOTENOUGHROOM))
                return false
            else
                return moveItem:moveTo(parent)
            end
        end
    end

    return us_onMoveItem(self, item, fromPosition, toPosition)
end
 
@oen432 this is correct?

Lua:
function Player:onMoveItem(item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    if item:getAttribute("wrapid") ~= 0 then
        local tile = Tile(toPosition)
        if (fromPosition.x ~= CONTAINER_POSITION and toPosition.x ~= CONTAINER_POSITION) or tile and not tile:getHouse() then
            if tile and not tile:getHouse() then
                self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
                return false
            end
        end
    end

    if toPosition.x ~= CONTAINER_POSITION then
        return true
    end

    if item:getTopParent() == self and bit.band(toPosition.y, 0x40) == 0 then
        local itemType, moveItem = ItemType(item:getId())
        if bit.band(itemType:getSlotPosition(), SLOTP_TWO_HAND) ~= 0 and toPosition.y == CONST_SLOT_LEFT then
            moveItem = self:getSlotItem(CONST_SLOT_RIGHT)
        elseif itemType:getWeaponType() == WEAPON_SHIELD and toPosition.y == CONST_SLOT_RIGHT then
            moveItem = self:getSlotItem(CONST_SLOT_LEFT)
            if moveItem and bit.band(ItemType(moveItem:getId()):getSlotPosition(), SLOTP_TWO_HAND) == 0 then
                return us_onMoveItem(self, item, fromPosition, toPosition)
            end
        end

        if moveItem then
            local parent = item:getParent()
            if parent:isContainer() and parent:getSize() == parent:getCapacity() then
                self:sendTextMessage(MESSAGE_STATUS_SMALL, Game.getReturnMessage(RETURNVALUE_CONTAINERNOTENOUGHROOM))
                return false
            else
                return moveItem:moveTo(parent)
            end
        end
    end

    return us_onMoveItem(self, item, fromPosition, toPosition)
end
Yup
 
@oen432 i think the entire error is for something named "POW"
i got this console error too when blightwalker attacks some player and in the line 1587 of upgrade..system..core have something like math.Pow
Lua:
attempt to call a nil value (field 'pow')
 
@oen432 i think the entire error is for something named "POW"
i got this console error too when blightwalker attacks some player and in the line 1587 of upgrade..system..core have something like math.Pow
Lua:
attempt to call a nil value (field 'pow')
Which version of Lua are you using :eek: math.pow is depracated in 5.3+, but because TFS is using LuaJIT, you should have version 5.1 which contains standard pow function from math library.
 
Which version of Lua are you using :eek: math.pow is depracated in 5.3+, but because TFS is using LuaJIT, you should have version 5.1 which contains standard pow function from math library.
C++:
The Forgotten Server - Version 1.3

Compiled with Microsoft Visual C++ version 14.2
Compiled on Aug 30 2020 01:01:39 for platform x64
Linked with Lua 5.3.5 for Lua support
 
yeah i have compiled with that
Code:
vcpkg install --triplet x64-windows boost-iostreams boost-asio boost-system boost-filesystem boost-variant boost-lockfree luajit libmariadb pugixml cryptopp
Post automatically merged:

@oen432 i dont know how to download the sources with luajit enabled :/
 
Last edited:
well it is working now, but how i can make work with webstore items, quest items and "/i" items? any tutorial for this?
Items from Quests, NPCs or any source other than monster loot won't have Item Level set. There are functions to help you overcome this issue.
 
Back
Top