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

TFS 1.X+ Npc doesnt remove defined item

Tbol

Well-Known Member
Joined
Apr 7, 2019
Messages
592
Reaction score
64
Idk whats wrong with it but it doesnt remove defined item, because if they teleport to cave it shouldnt remove anything but if he choses second condition it should remove it, but it doesnt
LUA:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

function onCreatureAppear(cid)          npcHandler:onCreatureAppear(cid)            end
function onCreatureDisappear(cid)       npcHandler:onCreatureDisappear(cid)         end
function onCreatureSay(cid, type, msg)      npcHandler:onCreatureSay(cid, type, msg)        end
function onThink()              npcHandler:onThink()                    end

local function creatureSayCallback(cid, type, msg)
    local player = Player(cid)
    local prisonPos = {x = 1648, y = 119, z = 7}
    local penitentiaryPos = {x = 1700, y = 130, z = 7}

    if not npcHandler:isFocused(cid) then
        if msg == "hi" or msg == "hello" then
            npcHandler:addFocus(cid)
            npcHandler:say("Hello! If you want to teleport, just say {cave} or {testsecond}.", cid)
            npcHandler.topic[cid] = 1
        else
            return false
        end

    elseif msgcontains(msg, "test") then
        if player:getItemCount(15682) >= 5 then
            doTeleportThing(cid, prisonPos)
            npcHandler:say("Teleported to the cave.", cid)
        else
            npcHandler:say("You don't have enough crystals.", cid)
        end

    elseif msgcontains(msg, "testsecond") then
        npcHandler:say("Do you want to teleport to the testsecond?", cid)
        npcHandler.topic[cid] = 2

    elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 2 then
        if player:getItemCount(2160) >= 50 then
            player:removeItem(2160, 50) //this exact code doesnt work it doesnt remove them
            doTeleportThing(cid, penitentiaryPos)
            npcHandler:say("Teleported to the test.", cid)
        else
            npcHandler:say("You don't have enough crystal coins.", cid)
        end
        npcHandler.topic[cid] = 0

    elseif msgcontains(msg, "bye") then
        npcHandler:say("Bye.", cid)
        npcHandler:releaseFocus(cid)
    end

    return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
Your player here is defined as a cid, you cant use that function with a creature id like that.
Either you use correct function to cid or you define player correct to the function 'removeItem'
 
Your player here is defined as a cid, you cant use that function with a creature id like that.
Either you use correct function to cid or you define player correct to the function 'removeItem'
define player correct? what is correct way than
 
Your player here is defined as a cid, you cant use that function with a creature id like that.
Either you use correct function to cid or you define player correct to the function 'removeItem'
you sure? he has
LUA:
 local player = Player(cid)

if player is not nil it should work with player:removeItem aswell imo.
 
I have a feeling we are dealing with a backpack full of items issue.
It's probably removing them, but your gm's backpack is so full of items, you don't see the one's being removed.

Check with print, before and after you remove the item.
LUA:
    elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 2 then
        print(player:getItemCount(2160))
        if player:getItemCount(2160) >= 50 then
            player:removeItem(2160, 50)
            print(player:getItemCount(2160))
            doTeleportThing(cid, penitentiaryPos)
            npcHandler:say("Teleported to the test.", cid)
        else
            npcHandler:say("You don't have enough crystal coins.", cid)
        end
        npcHandler.topic[cid] = 0

or you're getting caught here, and teleporting to wrong location, and not realising.
LUA:
elseif msgcontains(msg, "test") then
It might never reach the testsecond if statement, because it's being redirected to this one, because your message contains test already.
 
I have a feeling we are dealing with a backpack full of items issue.
It's probably removing them, but your gm's backpack is so full of items, you don't see the one's being removed.

Check with print, before and after you remove the item.
LUA:
    elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 2 then
        print(player:getItemCount(2160))
        if player:getItemCount(2160) >= 50 then
            player:removeItem(2160, 50)
            print(player:getItemCount(2160))
            doTeleportThing(cid, penitentiaryPos)
            npcHandler:say("Teleported to the test.", cid)
        else
            npcHandler:say("You don't have enough crystal coins.", cid)
        end
        npcHandler.topic[cid] = 0

or you're getting caught here, and teleporting to wrong location, and not realising.
LUA:
elseif msgcontains(msg, "test") then
It might never reach the testsecond if statement, because it's being redirected to this one, because your message contains test already.
Backpack is empty just has 2160 items, and no im not geting caught with the wrong location it teleports to local penitentiaryPos = {x = 1700, y = 130, z = 7} which is perfectly fine. Also it doesnt print anything
 
Check out my automatic version of npc teleporter.
Just edit table variables and let me know if it's working as intended.
I also added "freezone" as an example of location option that doesn't require any source of payment.

LUA:
local DESTINATIONS = {
    ["cave"] = {
        position = Position(1648, 119, 7),
        itemCost = 15682,
        itemCount = 5
    },

    ["testsecond"] = {
        position = Position(1700, 130, 7),
        itemCost = 2160,
        itemCount = 50
    },

    ["freezone"] = {
        position = Position(1800, 140, 7),
        itemCost = nil,  -- No item cost for this destination
        itemCount = 0
    }
}

local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

function onCreatureAppear(cid) npcHandler:onCreatureAppear(cid) end
function onCreatureDisappear(cid) npcHandler:onCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg) npcHandler:onCreatureSay(cid, type, msg) end
function onThink() npcHandler:onThink() end

local function getDestinationsList()
    local list = {}
    for key in pairs(DESTINATIONS) do
        table.insert(list, "{" .. key .. "}")
    end
    return table.concat(list, " or ")
end

npcHandler:setMessage(MESSAGE_GREET, "Hello |PLAYERNAME|! If you want to teleport, just say: " .. getDestinationsList() .. ".")

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, function(cid, talkType, msg)
    if not npcHandler:isFocused(cid) then return false end

    local player = Player(cid)

    for key in pairs(DESTINATIONS) do  
        if msgcontains(msg, key) then
            local data = DESTINATIONS[key]
            local itemName = data.itemCost and ItemType(data.itemCost):getName() or nil
          
            local message = string.format("Do you want to teleport to {%s} %s?", key, itemName and string.format("for {%d}x {%s}", data.itemCount, itemName) or "for free")
            npcHandler:say(message, cid)
            npcHandler.topic[cid] = key
            return true
        end
    end

    if msgcontains(msg, "yes") and npcHandler.topic[cid] then
        local selectedDestination = DESTINATIONS[npcHandler.topic[cid]]
        if selectedDestination then
            -- Check if itemCost is not nil before proceeding with checks
            if selectedDestination.itemCost then
                -- Check if the player has enough items
                if player:getItemCount(selectedDestination.itemCost) < selectedDestination.itemCount then
                    npcHandler:say(string.format("You don't have {%i}x {%s} to travel to {%s}.", selectedDestination.itemCount, ItemType(selectedDestination.itemCost):getName(), npcHandler.topic[cid]), cid)
                    npcHandler.topic[cid] = nil
                    return true
                end
              
                -- Remove the required items
                player:removeItem(selectedDestination.itemCost, selectedDestination.itemCount)
            end
          
            -- Teleport the player to the selected position
            player:teleportTo(selectedDestination.position)
            npcHandler:say(string.format("Teleported to %s.", npcHandler.topic[cid]), cid)
            npcHandler.topic[cid] = nil
            return true
        end
    end

    return true
end)

npcHandler:addModule(FocusModule:new())
 
Last edited:
Also it doesnt print anything
This seems impossible.
Add more prints. lol

LUA:
    elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 2 then
        print("yes was called")
        print(player:getItemCount(2160))
        if player:getItemCount(2160) >= 50 then
            print("player has greater then 50 of the item")
            player:removeItem(2160, 50)
            print("items were removed.")
            print(player:getItemCount(2160))
            doTeleportThing(cid, penitentiaryPos)
            npcHandler:say("Teleported to the test.", cid)
        else
            npcHandler:say("You don't have enough crystal coins.", cid)
        end
        npcHandler.topic[cid] = 0
 
Check out my automatic version of npc teleporter.
Just edit table variables and let me know if it's working as intended.
I also added "freezone" as an example of location option that doesn't require any source of payment.

LUA:
local DESTINATIONS = {
    ["cave"] = {
        position = Position(1648, 119, 7),
        itemCost = 15682,
        itemCount = 5
    },

    ["testsecond"] = {
        position = Position(1700, 130, 7),
        itemCost = 2160,
        itemCount = 50
    },

    ["freezone"] = {
        position = Position(1800, 140, 7),
        itemCost = nil,
        itemCount = 0
    }
}

local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)

function onCreatureAppear(cid) npcHandler:onCreatureAppear(cid) end
function onCreatureDisappear(cid) npcHandler:onCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg) npcHandler:onCreatureSay(cid, type, msg) end
function onThink() npcHandler:onThink() end

local function getDestinationsList()
    local list = {}
    for key in pairs(DESTINATIONS) do
        table.insert(list, "{" .. key .. "}")
    end
    return table.concat(list, " or ")
end

npcHandler:setMessage(MESSAGE_GREET, "Hello |PLAYERNAME|! If you want to teleport, just say: " .. getDestinationsList() .. ".")

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, function(cid, talkType, msg)
    if not npcHandler:isFocused(cid) then return false end

    local player = Player(cid)

    for key in pairs(DESTINATIONS) do
        if msgcontains(msg, key) then
            local data = DESTINATIONS[key]
            local itemName = data.itemCost and ItemType(data.itemCost):getName() or nil
       
            local message = string.format("Do you want to teleport to {%s} %s?", key, itemName and string.format("for %dx {%s}", data.itemCount, itemName) or "for free")
            npcHandler:say(message, cid)
            npcHandler.topic[cid] = key
            return true
        end
    end

    if msgcontains(msg, "yes") and npcHandler.topic[cid] then
        local selectedDestination = DESTINATIONS[npcHandler.topic[cid]]
        if selectedDestination then
            if selectedDestination.itemCost then
                if player:getItemCount(selectedDestination.itemCost) < selectedDestination.itemCount then
                    npcHandler:say(string.format("You don't have {%i}x {%s} for travel to %s.", selectedDestination.itemCount, ItemType(selectedDestination.itemCost):getName(), npcHandler.topic[cid]), cid)
                    npcHandler.topic[cid] = nil
                    return true
                end
           
                player:removeItem(selectedDestination.itemCost, selectedDestination.itemCount)
            end
       
            player:teleportTo(selectedDestination.position)
            npcHandler:say(string.format("Teleported to %s.", npcHandler.topic[cid]), cid)
            npcHandler.topic[cid] = nil
            return true
        end
    end

    return true
end)

npcHandler:addModule(FocusModule:new())
It does work but it misses function to check if he has required item and not remove it, because right now it removes all the time, and using itemCost = nil, is not an option sometimes
 
It does work but it misses function to check if he has required item and not remove it, because right now it removes all the time, and using itemCost = nil, is not an option sometimes

Try change Line 60, which is:
LUA:
if selectedDestination.itemCost then
to
LUA:
if selectedDestination.itemCost and selectedDestination.itemCost > 0 then

Anyway, strangely, if NIL is in the table in itemCost element it should not take this condition into account and not pass further to removing the item.


The other option is to remove completely itemCost and itemCount line from table element when you want to have free travel (without costs), just remove it, like this for example, for tests, leave like that:
LUA:
    ["testsecond"] = {
        position = Position(1700, 130, 7),
    },
 
Last edited:
LUA:
    elseif msgcontains(msg, "test") then
        if player:getItemCount(15682) >= 5 then
            doTeleportThing(cid, prisonPos)
            npcHandler:say("Teleported to the cave.", cid)
        else
            npcHandler:say("You don't have enough crystals.", cid)
        end

    elseif msgcontains(msg, "testsecond") then
        npcHandler:say("Do you want to teleport to the testsecond?", cid)
        npcHandler.topic[cid] = 2

okay, so it check if message contains "test", so even if u type "testsecond" it will execute first condition, since msgcontains its nothing else than string.find

so i think it never goess to this part
LUA:
elseif msgcontains(msg, "testsecond") then

try change "testsecond" to smth else than will not be found with first condition like idk "abc123"


nvm @Xikini found this issue already.
 

Similar threads

Back
Top