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

RevScripts Globalloot not active

n3crozzy

Member
Joined
Apr 23, 2021
Messages
48
Reaction score
14
Hi, I need help. I have a script that responds.
1. Activation of the shrine
2. Activates boost loot - for a specific period of time
3. Turn off boost
I don't understand what is wrong with this code:
data/scripts/action/global_loot.lua
LUA:
local emptyShrine = 8642 -- ID of the empty shrine
local fullShrine = 8641 -- ID of the full shrine
local shrineActionID = 51537 -- ActionID of the shrine
local platinumAmount = 10000 -- Equivalent of 100 platinum coins (1 crystal coin = 10000 gold coins)
local lootBonusMultiplier = 5.0 -- Loot bonus multiplier (e.g. 500%)
local bonusDuration = 30 -- Duration of the bonus in seconds
local basinPosition = Position(32376, 32239, 7) -- Coordinates of the shrine
local bonusActiveStorage = 12346 -- Global storage for bonus status

local worldBonusAction = Action()

-- Function triggered on server startup
local function onStartup()
    local bonusEndTime = tonumber(getGlobalStorageValue(bonusActiveStorage))
    if bonusEndTime and bonusEndTime > os.time() then
        local timeRemaining = bonusEndTime - os.time()
        addEvent(resetBonuses, timeRemaining * 1000)
        displayTimeLeft()
        broadcastTimeLeft()
    else
        setGlobalStorageValue(bonusActiveStorage, 0)
    end
end

-- Function to reset bonuses
local function resetBonuses()
    print("Resetting bonuses for all players.") -- Log for reset
    for _, player in ipairs(Game.getPlayers()) do
        player:setStorageValue(bonusActiveStorage, 0)
        print("Setting storage value for player " .. player:getName() .. " to 0") -- Debug log
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The global loot bonus has expired.")
    end

    local shrine = Tile(basinPosition):getItemById(fullShrine)
    if shrine then
        shrine:transform(emptyShrine)
        print("Shrine transformed to empty.") -- Log for shrine transformation
    end

    setGlobalStorageValue(bonusActiveStorage, 0)
    Game.broadcastMessage("The global loot bonus has expired.", MESSAGE_EVENT_ADVANCE)
    print("Global storage reset to 0 after bonus expiration.") -- Debug log
end

-- Function to calculate the total amount of money (gold, platinum, crystals) a player has
local function getTotalMoney(player)
    local goldCoins = player:getItemCount(2148) -- Gold coins
    local platinumCoins = player:getItemCount(2152) -- Platinum coins
    local crystalCoins = player:getItemCount(2160) -- Crystal coins

    -- Convert all coins to gold coin equivalent
    local totalGold = goldCoins + (platinumCoins * 100) + (crystalCoins * 10000)
    return totalGold
end

-- Function to remove the specified amount of money from the player
local function removeMoney(player, amount)
    local totalMoney = getTotalMoney(player)

    if totalMoney >= amount then
        local remainingAmount = amount

        -- First, remove crystal coins (highest value)
        local crystalCoinsToRemove = math.min(math.floor(remainingAmount / 10000), player:getItemCount(2160))
        if crystalCoinsToRemove > 0 then
            player:removeItem(2160, crystalCoinsToRemove)
            remainingAmount = remainingAmount - (crystalCoinsToRemove * 10000)
        end

        -- Then, remove platinum coins
        local platinumCoinsToRemove = math.min(math.floor(remainingAmount / 100), player:getItemCount(2152))
        if platinumCoinsToRemove > 0 then
            player:removeItem(2152, platinumCoinsToRemove)
            remainingAmount = remainingAmount - (platinumCoinsToRemove * 100)
        end

        -- Finally, remove gold coins
        if remainingAmount > 0 then
            player:removeItem(2148, remainingAmount)
        end

        return true
    else
        return false
    end
end

-- Function to display the remaining time on the shrine
local function displayTimeLeft()
    local shrine = Tile(basinPosition):getItemById(fullShrine)
    local timeSec = tonumber(getGlobalStorageValue(bonusActiveStorage)) - os.time()
    local timeMin = math.floor(timeSec / 60)
    local timeRemainingSec = timeSec % 60

    if shrine then
        local message
        if timeSec < 60 then
            message = "Loot Bonus:\n" .. timeSec .. " seconds"
        elseif timeSec < 120 then
            message = "Loot Bonus:\n" .. timeMin .. " minute " .. timeRemainingSec .. " seconds"
        else
            message = "Loot Bonus:\n" .. timeMin .. " minutes " .. timeRemainingSec .. " seconds"
        end

        shrine:getPosition():sendAnimatedText(message)
    end

    -- Recursively call this function every 3 seconds to update the timer
    addEvent(displayTimeLeft, 3000)
end

-- Function to send animated text to players near the shrine
function Position.sendAnimatedText(self, message)
    local specs = Game.getSpectators(self, false, true, 8, 8, 7, 7)
    for _, player in ipairs(specs) do
        player:say(message, TALKTYPE_MONSTER_SAY, false, player, self)
    end
end

-- Function to broadcast the remaining time every 10 seconds
local function broadcastTimeLeft()
    local timeSec = tonumber(getGlobalStorageValue(bonusActiveStorage)) - os.time()
    if timeSec > 0 then
        local timeMin = math.floor(timeSec / 60)
        local timeRemainingSec = timeSec % 60
        local message

        if timeSec < 60 then
            message = "Global loot bonus active for " .. timeSec .. " seconds."
        elseif timeSec < 120 then
            message = "Global loot bonus active for " .. timeMin .. " minute " .. timeRemainingSec .. " seconds."
        else
            message = "Global loot bonus active for " .. timeMin .. " minutes " .. timeRemainingSec .. " seconds."
        end

        Game.broadcastMessage(message, MESSAGE_STATUS_WARNING)

        -- Schedule the next announcement in 10 seconds
        addEvent(broadcastTimeLeft, 10000)
    end
end

-- Function to activate the loot bonus using the shrine
function worldBonusAction.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    print("Attempting to use shrine...") -- Log debug

    -- Check the shrine position
    if item:getPosition() ~= basinPosition then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "This shrine cannot be used in this location.")
        return true
    end

    -- Check if the bonus is active
    if tonumber(getGlobalStorageValue(bonusActiveStorage)) <= 0 then
        -- Check if the player has enough money
        if getTotalMoney(player) >= platinumAmount then
            print("Player has enough money.") -- Log debug
            -- Remove the required amount of money
            if removeMoney(player, platinumAmount) then
                item:transform(fullShrine)

                -- Activate bonuses for all online players
                for _, onlinePlayer in ipairs(Game.getPlayers()) do
                    local newBonusEndTime = os.time() + bonusDuration
                    onlinePlayer:setStorageValue(bonusActiveStorage, newBonusEndTime)
                    print("Activated loot bonus for player " .. onlinePlayer:getName() .. " until " .. newBonusEndTime) -- Debug log
                    onlinePlayer:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The global loot bonus has been activated!")
                end

                -- Set the active bonus status and display the remaining time
                setGlobalStorageValue(bonusActiveStorage, os.time() + bonusDuration)
                print("Global loot bonus activated until " .. os.time() + bonusDuration) -- Debug log
                displayTimeLeft()
                broadcastTimeLeft()

                -- Schedule the reset function after the bonus duration
                addEvent(resetBonuses, bonusDuration * 1000)

                -- Broadcast the activation message
                Game.broadcastMessage("The global loot bonus has been activated for " .. bonusDuration .. " seconds!", MESSAGE_EVENT_ADVANCE)
                print("Loot bonus activated!") -- Log debug
            else
                player:sendTextMessage(MESSAGE_INFO_DESCR, "You don't have enough money.")
            end
        else
            player:sendTextMessage(MESSAGE_INFO_DESCR, "You don't have enough money.")
        end
    else
        player:sendTextMessage(MESSAGE_INFO_DESCR, "The bonus is already active.")
    end

    return true
end

-- Register the action and trigger functions
worldBonusAction:aid(shrineActionID)
worldBonusAction:register()
onStartup() -- Ensure the startup function is called after its definition

data/lib/core/container.lua
Code:
function Container.createLootItem(self, item, creatureName)
    if self:getEmptySlots() == 0 then
        return true
    end

    local itemCount = 0
    local randvalue = getLootRandom()
    local itemType = ItemType(item.itemId)
    local chance = item.chance

    -- Check if loot bonus is active
    if tonumber(getGlobalStorageValue(bonusActiveStorage)) > os.time() then
        chance = chance * lootBonusMultiplier -- Apply loot bonus multiplier
        print("Loot bonus active. Original chance: " .. item.chance .. ", New chance: " .. chance)
    else
        print("Loot bonus not active. Chance: " .. chance)
    end

    -- Calculate if item should be created based on chance
    if randvalue < 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:createLootItem(item.childLoot[i]) 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

Introductory video

Currently after changes, debug print. In the right places.

Code:
Necrozzy has logged in.
Loot bonus not active. Chance: 30050
Loot bonus not active. Chance: 210
Loot bonus not active. Chance: 390
Loot bonus not active. Chance: 100
Loot bonus not active. Chance: 15000
Loot bonus not active. Chance: 500
Loot bonus not active. Chance: 1470
Loot bonus not active. Chance: 10
Loot bonus not active. Chance: 300
Loot bonus not active. Chance: 130
Loot bonus not active. Chance: 10130
Loot bonus not active. Chance: 1001
Attempting to use shrine...
Player has enough money.
Activated loot bonus for player Necrozzy until 1728224725
Global loot bonus activated until 1728224725
Loot bonus activated!
Loot bonus not active. Chance: 30050
Loot bonus not active. Chance: 210
Loot bonus not active. Chance: 390
Loot bonus not active. Chance: 100
Loot bonus not active. Chance: 15000
Loot bonus not active. Chance: 500
Loot bonus not active. Chance: 1470
Loot bonus not active. Chance: 10
Loot bonus not active. Chance: 300
Loot bonus not active. Chance: 130
Loot bonus not active. Chance: 10130
Loot bonus not active. Chance: 1001
Resetting bonuses for all players.
Setting storage value for player Necrozzy to 0
Shrine transformed to empty.
Global storage reset to 0 after bonus expiration.

Is there anyone who could help me?
 
bonusActiveStorage is set as local in your first script, so in createLootItem function, you're basically getting the storage value of nil, because it has no idea what bonusActiveStorage is.

You need to use 12346 directly, or place a local bonusActiveStorage in the container script, or make the bonusActiveStorage a global variable in the first script.
 
bonusActiveStorage is set as local in your first script, so in createLootItem function, you're basically getting the storage value of nil, because it has no idea what bonusActiveStorage is.

You need to use 12346 directly, or place a local bonusActiveStorage in the container script, or make the bonusActiveStorage a global variable in the first script.
Why core/container.lua not onDropLoot.lua in eventcallbacks?
 
Back
Top