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

Solved Player not geting exp from stages

Esbuma

New Member
Joined
Apr 19, 2017
Messages
21
Reaction score
1
Today i got these error on my server


Screenshot_2.png

my player.lua is ok i think

the error is in line 438

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

anyone know how to fix it?

my config.lua

Lua:
-- Rates
-- NOTE: rateExp is not used if you have enabled stages in data/XML/stages.xml
rateExp = 5
rateSkill = 50
rateLoot = 3
rateMagic = 10
rateSpawn = 1

and my stages.xml

Lua:
<?xml version="1.0" encoding="UTF-8"?>
    <stages>
        <config enabled="1" />
        <stage minlevel="8" maxlevel="50" multiplier="300" />   
        <stage minlevel="51" maxlevel="80" multiplier="250" />
        <stage minlevel="81" maxlevel="100" multiplier="200" />
        <stage minlevel="101" maxlevel="120" multiplier="150" />
        <stage minlevel="121" maxlevel="140" multiplier="100" />
        <stage minlevel="141" maxlevel="160" multiplier="80" />
        <stage minlevel="161" maxlevel="180" multiplier="60" />
        <stage minlevel="181" maxlevel="200" multiplier="40" />
        <stage minlevel="201" maxlevel="220" multiplier="20" />
        <stage minlevel="221" maxlevel="260" multiplier="10" />
        <stage minlevel="261" maxlevel="280" multiplier="8" />
        <stage minlevel="281" maxlevel="300" multiplier="6" />
        <stage minlevel="301" maxlevel="350" multiplier="4" />
        <stage minlevel="351" maxlevel="400" multiplier="2" />
        <stage minlevel="401" multiplier="1" />
    </stages>
 

Attachments

Last edited:
Solution
Lua:
-- No move items with actionID 8000
-- Players cannot throw items on teleports if set to true
local blockTeleportTrashing = true

-- Internal Use
ITEM_STORE_INBOX = 26052

function Player:onBrowseField(position)
    return true
end

function Player:onLook(thing, position, distance)
    local description = "You see " .. thing:getDescription(distance)
    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
   
    -- KD look 
    if...
Lua:
-- No move items with actionID 8000
-- Players cannot throw items on teleports if set to true
local blockTeleportTrashing = true

-- Internal Use
ITEM_STORE_INBOX = 26052

function Player:onBrowseField(position)
    return true
end

function Player:onLook(thing, position, distance)
    local description = "You see " .. thing:getDescription(distance)
    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
   
    -- KD look 
    if thing:isCreature() and thing:isPlayer() then
        description = string.format("%s\n [PVP Kills: %d] \n [PVP Deaths: %d] \n",
            description, math.max(0, thing:getStorageValue(167912)), math.max(0, thing:getStorageValue(167913)))
    end
   
    -- MARRY 
    if LOOK_MARRIAGE_DESCR and thing:isCreature() then
    if thing:isPlayer() then
    description = description .. self:getMarriageDescription(thing)
    end
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: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)
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: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
    -- KD look 
    if creature:isPlayer() and creature:isCreature() then
        description = string.format("%s\n [PVP Kills: %d] \n [PVP Deaths: %d] \n",
            description, math.max(0, creature:getStorageValue(167912)), math.max(0, creature:getStorageValue(167913)))
    end
   
    -- MARRY  
    if LOOK_MARRIAGE_DESCR and creature:isCreature() then
if creature:isPlayer() then
description = description .. self:getMarriageDescription(creature)
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)

--- LIONS ROCK START 

if self:getStorageValue(lionrock.storages.playerCanDoTasks) - os.time() < 0 then
        local p, i = lionrock.positions, lionrock.items
        local checkPr = false
        if item:getId() == lionrock.items.ruby and toPosition.x == p.ruby.x
                and toPosition.y == p.ruby.y  and toPosition.z == p.ruby.z then
            -- Ruby
            self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You place the ruby on the small socket. A red flame begins to burn.")
            checkPr = true
            if lionrock.taskactive.ruby ~= true then
                lionrock.taskactive.ruby = true
            end
           
            local tile = Tile(p.ruby)
            if tile:getItemCountById(i.redflame) < 1 then
                Game.createItem(i.redflame, 1, p.ruby)
            end
        end
       
        if item:getId() == lionrock.items.sapphire and toPosition.x == p.sapphire.x
                and toPosition.y == p.sapphire.y  and toPosition.z == p.sapphire.z then
            -- Sapphire
            self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You place the sapphire on the small socket. A blue flame begins to burn.")
            checkPr = true
            if lionrock.taskactive.sapphire ~= true then
                lionrock.taskactive.sapphire = true
            end
           
            local tile = Tile(p.sapphire)
            if tile:getItemCountById(i.blueflame) < 1 then
                Game.createItem(i.blueflame, 1, p.sapphire)
            end
        end
       
        if item:getId() == lionrock.items.amethyst and toPosition.x == p.amethyst.x
                and toPosition.y == p.amethyst.y  and toPosition.z == p.amethyst.z then
            -- Amethyst
            self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You place the topaz on the small socket. A yellow flame begins to burn.")
            checkPr = true
            if lionrock.taskactive.amethyst ~= true then
                lionrock.taskactive.amethyst = true
            end
           
            local tile = Tile(p.amethyst)
            if tile:getItemCountById(i.yellowflame) < 1 then
                Game.createItem(i.yellowflame, 1, p.amethyst)
            end
        end
       
        if item:getId() == lionrock.items.topaz and toPosition.x == p.topaz.x
                and toPosition.y == p.topaz.y  and toPosition.z == p.topaz.z then
            -- Topaz
            self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You place the amethyst on the small socket. A violet flame begins to burn.")
            checkPr = true
            if lionrock.taskactive.topaz ~= true then
                lionrock.taskactive.topaz = true
            end
           
            local tile = Tile(p.topaz)
            if tile:getItemCountById(i.violetflame) < 1 then
                Game.createItem(i.violetflame, 1, p.topaz)
            end
        end
       
        if checkPr == true then
            -- Adding the Fountain which gives present
            if lionrock.taskactive.ruby == true and lionrock.taskactive.sapphire == true
                and lionrock.taskactive.amethyst == true and lionrock.taskactive.topaz == true then
               
                local fountain = Game.createItem(i.rewardfountain, 1, { x=33073, y=32300, z=9})
                fountain:setActionId(41357)
               local stone = Tile({ x=33073, y=32300, z=9}):getItemById(3608)
            if stone ~= nil then
            stone:remove()
            end
                self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Something happens at the centre of the room ...");
            end
           
            -- Removing Item
            item:remove(1)
        end
    end
   
    ---- LIONS ROCK END 

    local exhaust = { } -- SSA exhaust
    if toPosition.x == CONTAINER_POSITION and toPosition.y == CONST_SLOT_NECKLACE and item:getId() == 2197 then
        local pid = self:getId()
        if exhaust[pid] then  
            self:sendCancelMessage(RETURNVALUE_YOUAREEXHAUSTED)    
            return false
        else
            exhaust[pid] = true
            addEvent(function() exhaust[pid] = false end, 2000, pid)
            return true
        end
    end

    -- Store Inbox
    local containerIdFrom = fromPosition.y - 64
    local containerFrom = self:getContainerById(containerIdFrom)
    if (containerFrom) then
        if (containerFrom:getId() == ITEM_STORE_INBOX and toPosition.y >= 1 and toPosition.y <= 11 and toPosition.y ~= 3) then
            self:sendCancelMessage(RETURNVALUE_CONTAINERNOTENOUGHROOM)
            return false
        end
    end

    local containerTo = self:getContainerById(toPosition.y-64)
    if (containerTo) then
        if (containerTo:getId() == ITEM_STORE_INBOX) then
            self:sendCancelMessage(RETURNVALUE_CONTAINERNOTENOUGHROOM)
            return false
        end
    end

    -- No move items with actionID 8000
    if item:getActionId() == NOT_MOVEABLE_ACTION then
        self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
        return false
    end

    -- Check two-handed weapons 
    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 true
            end
        end

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

    -- Reward System
    if toPosition.x == CONTAINER_POSITION then
        local containerId = toPosition.y - 64
        local container = self:getContainerById(containerId)
        if not container then
            return true
        end

        -- Do not let the player insert items into either the Reward Container or the Reward Chest
        local itemId = container:getId()
        if itemId == ITEM_REWARD_CONTAINER or itemId == ITEM_REWARD_CHEST then
            self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
            return false
        end

        -- The player also shouldn't be able to insert items into the boss corpse
        local tile = Tile(container:getPosition())
        for _, item in ipairs(tile:getItems() or { }) do
            if item:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == 2^31 - 1 and item:getName() == container:getName() then
                self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
                return false
            end
        end
    end

    -- Do not let the player move the boss corpse.
    if item:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == 2^31 - 1 then
        self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
        return false
    end

    -- Players cannot throw items on reward chest
    local tile = Tile(toPosition)
    if tile and tile:getItemById(ITEM_REWARD_CHEST) then
        self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
        self:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end

    -- Players cannot throw items on teleports
    if blockTeleportTrashing and toPosition.x ~= CONTAINER_POSITION then
        local thing = Tile(toPosition):getItemByType(ITEM_TYPE_TELEPORT)
        if thing then
            self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
            self:getPosition():sendMagicEffect(CONST_ME_POFF)
            return false
        end
    end

    -- No move parcel very heavy
    if item:getWeight() > 90000 and item:getId() == ITEM_PARCEL then 
        self:sendCancelMessage('YOU CANNOT MOVE PARCELS TOO HEAVY.')
        return false 
    end

    -- No move if item count > 26 items
    if tile and tile:getItemCount() > 26 then
        self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
        return false
    end

    if tile and tile:getItemById(370) then -- Trapdoor
        self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
        self:getPosition():sendMagicEffect(CONST_ME_POFF)
        return false
    end 
    return true
end

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

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

    local name = self:getName()
    local file = io.open("data/reports/" .. 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:onWrapItem(item)
    local pos = item:getPosition()
    local house = Tile(pos):getHouse()
   
    if not house then
        self:sendTextMessage(MESSAGE_STATUS_SMALL, "You can only wrap and unwrap this item inside a house.")
        return
    end
   
    local wrapId = item:getType():getWrapId()
    if wrapId ~= 0 then
        item:transform(wrapId)
    end
end

function Player:onTurn(direction)
    if self:getGroup():getAccess() and self:getDirection() == direction then
        local nextPosition = self:getPosition()
        nextPosition:getNextPosition(direction)

        self:teleportTo(nextPosition, true)
    end

    return true
end

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

function Player:onTradeAccept(target, item, targetItem)
    return true
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

local config = {
    rate = 2,
    storage = 200011,
}

function Player:onGainExperience(source, exp, rawExp)
    if not source or source:isPlayer() then
        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

    -- Apply Extra Experience
    if self:getStorageValue(config.storage) >= os.time() then
        exp = exp * config.rate
    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

The error "was" at line 466, you didn't add the config table (rate and storage)
 
Solution
Back
Top