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

Lua [talkaction] Lootbag System param issue

LEDneotoxicity

New Member
Joined
Mar 3, 2017
Messages
27
Reaction score
3
Hi all, I'm attempting to create a lootbag system where the player can only have 1 bag in existence as a time, which can be created by saying "!lootbag create" and if the player ever loses the bag, they can say "!lootbag reset" to remove the existing flag.

I can't get either command to recognize, and the only thing that seems to work is the blank params check at the beginning of the script. Can someone tell me what I'm missing?

Lua:
local config = {
    backpackId = 2000,
    hasLootbag = 0
}

function onSay(player, words, param)
    local playerID = player:getGuid()
    local owner = (playerID + 100)
    local ownerName = player:getName()
  
    if param == "" then
        doPlayerSendTextMessage(player, MESSAGE_INFO_DESCR, "You must enter a proper command. '!lootbag create' creates a new lootbag, '!lootbag reset' disowns your previous lootbag and allows you to create a new one.")
        return TRUE
    end
  
    if param == "reset" then
        hasLootbag = 0,
        o:removeAttribute(ITEM_ATTRIBUTE_DESCRIPTION)
        o:setActionId(0)
        doPlayerSendTextMessage(player, MESSAGE_INFO_DESCR, "You have disowned your previous lootbag. You may now create a new one.")
        return TRUE
  
    elseif param == "create" then
        if hasLootbag == 1 then
            doPlayerSendTextMessage(player, MESSAGE_INFO_DESCR, "You cannot have more than 1 lootbag. If you have lost your lootbag, say '!lootbag reset'")
          
        elseif hasLootbag == 0 then
            local backpack = doPlayerAddItem(player:getId(), config.backpackId, 1)
            if (backpack ~= nil) then
                doSetItemSpecialDescription(backpack, ownerName..' owns this lootbag.')
                doSetItemActionId(backpack, owner)
                hasLootbag = 1,
                doPlayerSendTextMessage(player, MESSAGE_INFO_DESCR, "You have created a lootbag for "..config.cost.." gold.")
              
            end
        end
    end
    return TRUE
end
 
Yes, I do. It generates nothing when !lootbag create and said and an index error when !lootbag reset is said.

That index error is:
Code:
Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/lootbag.lua:onSay
data/talkactions/scripts/lootbag.lua:18: attempt to index global 'o' (a nil valu
e)
stack traceback:
        [C]: in function '__index'
        data/talkactions/scripts/lootbag.lua:18: in function <data/talkactions/s
cripts/lootbag.lua:6>

Talkaction line below:
XML:
    <!-- Lootbag System -->
    <talkaction words="!lootbag" separator=" " script="lootbag.lua" />
 
Well firstly that script is mixing 0.x functions with 1.x functions. You should probably try to keep it all 1.x style.

E.g. instead of
Lua:
local backpack = doPlayerAddItem(player:getId(), config.backpackId, 1)

You should be doing:
Lua:
local backpack = player:addItem(config.backpackId, 1)


Secondly, the variable "hasLootbag" makes no sense the way it's currently used. Currently it's acting as a global variable which means it will be the same each execution independent of which player uses the command (which means all players share the same hasLootbag variable). You'd have to use a storage value to store/read from individual players.

Now to your actual error, the variable "o" isn't even declared, so I don't see how the error isn't obvious to you. It would make sense if you would rename the variable "o" to "item" instead but that's not the solution, you still need a way to locate the item in his backpack (or wherever it is). Not sure how you'd do that and it depends very much where you intend to store this backpack. Is it pushed on the ground? It might be complicated.
 
As to the hasLootbag variable, I was unsure of how to declare a global integer variable in lua.

I'll resolve the "o:variable" issue as I forgot to update those when I removed the old function calls for them. I still however, cannot seem to get the reset or clean params to even register. I ran a test of removing all functions other than the doPlayerSendTextMessage and they do not appear on screen.

Thanks much for the assist thus far.
 
Well, if you actually received an error when writing !lootbag reset then it was in fact executed properly.

I do see now why you're not receiving any messages. You're using player which is a userdata in your doPlayerSendTextMessage. You probably meant to use playerId, although as I said before you are mixing old coding style (non-oop) with new. You should stick to the new, using only OOP. Which means the preferred way is to use player:sendTextMessage(...). Generally the rule for converting the old functions to new OOP functions is simple, just omit the "Player" part (and "do" if present) and remove first parameter.
 
Sadly when I try to use player:sendTextMessage the script doesn't send any messages. I am running the TFS 1.2 SVN.
For the issue of the command not working it seems now that they only work sequentially, IE: you have to say !lootbag, then lootbag reset, etc. I'm not sure why the script isn't understand the elseif logic, maybe it's me. Below is what I have now, and it seems to work well other than the command issue. I'm still going to replace the broken hasLootbag with a proper storage value as soon as I get this working.

Lua:
local config = {
    backpackId = 2000,
    hasLootbag = 0
}

function onSay(player, words, param)
    local playerID = player:getGuid()
    local owner = (playerID + 100)
    local ownerName = player:getName()

    if param == "" then
        doPlayerSendTextMessage(player, MESSAGE_INFO_DESCR, "You must enter a proper command. '!lootbag create' creates a new lootbag, '!lootbag reset' disowns your previous lootbag and allows you to create a new one.")

    elseif param == "reset" then
        hasLootbag = 0,
        --readd the bag ownership removal --
        doPlayerSendTextMessage(player, MESSAGE_INFO_DESCR, "You have disowned your previous lootbag. You may now create a new one.")

    elseif param == "create" then
        if hasLootbag == 1 then
            doPlayerSendTextMessage(player, MESSAGE_INFO_DESCR, "You cannot have more than 1 lootbag. If you have lost your lootbag, say '!lootbag reset'")
        end
        if hasLootbag == 0 then
            local backpack = player:addItem(config.backpackId, 1)
                doSetItemSpecialDescription(backpack, ownerName..' owns this lootbag.')
                doSetItemActionId(backpack, owner)
                hasLootbag = 1,
                doPlayerSendTextMessage(player, MESSAGE_INFO_DESCR, "You have created a new lootbag.")
        end
    end
    return TRUE
end
 
The reason it only works "sequentially" is because you're checking if hasLootbag is 0 in the "create" param and in "reset" param you're setting it to 0, which means after that it will work. hasLootbag is initially nil though, which is why it won't work in the first execution.

I fixed your code a bit. Dunno why you were doing playerID + 100 on the owner.
Lua:
local config = {
    backpackId = 2000,
    hasLootbagStorage = 65432
}

function onSay(player, words, param)
    if param == "" then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "You must enter a proper command. \"!lootbag create\" creates a new lootbag, \"!lootbag reset\" disowns your previous lootbag and allows you to create a new one.")
        return true
    end

    if param == "reset" then
        --readd the bag ownership removal --
        player:sendTextMessage(MESSAGE_INFO_DESCR, "You have disowned your previous lootbag. You may now create a new one.")
        player:setStorageValue(config.hasLootbagStorage, 0)
    elseif param == "create" then
        local hasLootbag = player:getStorageValue(config.hasLootbagStorage)
        if hasLootbag == 1 then
            player:sendTextMessage(MESSAGE_INFO_DESCR, "You cannot have more than 1 lootbag. If you have lost your lootbag, say \"!lootbag reset\"")
            return true
        end

        local backpack = player:addItem(config.backpackId, 1)
        if not backpack then
            player:sendTextMessage(MESSAGE_INFO_DESCR, "Failed to create lootbag.")
            return true
        end

        local playerID = player:getGuid()
        local ownerName = player:getName()
        backpack:setAttribute(ITEM_ATTRIBUTE_DESCRIPTION, ownerName.." owns this lootbag.")
        backpack:setActionId(backpack, playerID) -- im not sure if this works (player id is probably too large number to use as actionid)
        player:sendTextMessage(MESSAGE_INFO_DESCR, "You have created a new lootbag.")
        player:setStorageValue(config.hasLootbagStorage, 1)
    end
    return true
end

Now my question is still how are you going to make it recognize the lootbag? For one I believe your current way of storing the player id won't work because it's too long for action id. Also the player id is not unique but will reset upon relog. You probably want to use player:getGuid() rather, which is unique to the player (the id stored in database). Although using them as actionids might result in unexpected behavior if any action script is currently bound to that action id.
 
Back
Top