• 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 How to send all depot items from another city?

warriorfrog

Active Member
Joined
Jul 29, 2015
Messages
334
Reaction score
35
I made my oracle NPC, its work, but i want to... when player leave from rookgaard, all he items depot from town id 7 (rookgaard) send to main (town id 9)...

Should be possible? Anyone know how could do it?

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

local pos = {x=503, y=716, z=6}
local townid = 9

local talkState = {}               

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
function creatureSayCallback(cid, type, msg)
if(not npcHandler:isFocused(cid)) then
   return false   
end

local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid
   if msgcontains(msg:lower(), "sorcerer") then
       if(getPlayerLevel(cid) ~= 8) then
           selfSay("You need be level 8 to go to main!", cid)
           return true
       end
       if(getPlayerVocation(cid) ~= 0) then
           selfSay("You have a vocation!", cid)
           doPlayerSetTown(cid, townid)
           doTeleportThing(cid, pos)
           return true
       end
       doPlayerSetVocation(cid, 1)
       doPlayerSetTown(cid, townid)
       doTeleportThing(cid, pos)
   elseif msgcontains(msg:lower(), "druid") then
       if(getPlayerLevel(cid) ~= 8) then
           selfSay("You need be level 8 to go to main!", cid)
           return true
       end
       if(getPlayerVocation(cid) ~= 0) then
           selfSay("You have a vocation!", cid)
           doPlayerSetTown(cid, townid)
           doTeleportThing(cid, pos)
           return true
       end
       doPlayerSetVocation(cid, 2)
       doPlayerSetTown(cid, townid)
       doTeleportThing(cid, pos)
   elseif msgcontains(msg:lower(), "paladin") then
       if(getPlayerLevel(cid) ~= 8) then
           selfSay("You need be level 8 to go to main!", cid)
           return true
       end
       if(getPlayerVocation(cid) ~= 0) then
           selfSay("You have a vocation!", cid)
           doPlayerSetTown(cid, townid)
           doTeleportThing(cid, pos)
           return true
       end
       doPlayerSetVocation(cid, 3)
       doPlayerSetTown(cid, townid)
       doTeleportThing(cid, pos)
   elseif msgcontains(msg:lower(), "knight") then
       if(getPlayerLevel(cid) ~= 8) then
           selfSay("You need be level 8 to go to main!", cid)
           return true
       end
       if(getPlayerVocation(cid) ~= 0) then
           selfSay("You have a vocation!", cid)
           doPlayerSetTown(cid, townid)
           doTeleportThing(cid, pos)
           return true
       end
       doPlayerSetVocation(cid, 4)
       doPlayerSetTown(cid, townid)
       doTeleportThing(cid, pos)
   end
   -- remove all items from depot town id 7 and send everything to depot town id 9
end  -- fim function
         

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
Why not just simplify the entire process and make all depots available from all cities and rookguard? The player that is in rookguard can't access their depot in the main city because they aren't there yet and if they are in the main city then they can't access the one in rookguard because they are no longer in rookguard.

If the player ends up in rookguard again just delete all their items.
 
Why not just simplify the entire process and make all depots available from all cities and rookguard? The player that is in rookguard can't access their depot in the main city because they aren't there yet and if they are in the main city then they can't access the one in rookguard because they are no longer in rookguard.

If the player ends up in rookguard again just delete all their items.

simplifying everything:
Because i want use parcel system
 
It will send all items from rook depo via parcel to new town. If you had 50 items in rook depo, script will send 5 parcels etc. It may miss some UID etc, so be prepared for some bugs. But script's logic itself is ok.

After
Code:
  -- remove all items from depot town id 7 and send everything to depot town id 9
Add
Code:
local cfg = {
    rookTownId = 7,
    parcelId = 2595,
    labelId = 2599,
    mailBoxPos = {x = 1234, y = 1234, z = 7}
}

local rookitem = getPlayerDepotItems(cid, cfg.rookTownId)
local parcel = {} -- leave it
local label = doCreateItemEx(cfg.labelId, 1)
doSetItemText(label, getCreatureName(cid).. "\n" ..getTownName(townid))
if rookitem ~= nil then
    local check = 1
    for p = 1, math.ceil(#rookitem / 10) do
        parcel[p] = doCreateItemEx(cfg.parcelId, 1)
        doAddContainerItemEx(parcel[p], label)
    end
    for i = 1, #rookitem do
        local parcelNumber = 1
        if i > check * 10 then
            parcelNumber = parcelNumber + 1
            check = check + 1
        end
        doAddContainerItemEx(parcel[parcelNumber], rookitem[i])
        doTeleportThing(parcel[parcelNumber], cfg.mailBoxPos)
        -- doTileAddItemEx(cfg.mailBoxPos, parcel[parcelNumber]) -- for older TFS
    end
end
 
Last edited:
It will send all items from rook depo via parcel to new town. If you had 50 items in rook depo, script will send 5 parcels etc. It may miss some UID etc, so be prepared for some bugs. But script's logic itself is ok.

After
Code:
  -- remove all items from depot town id 7 and send everything to depot town id 9
Add
Code:
local cfg = {
    rookTownId = 7,
    parcelId = 2595,
    labelId = 2599,
    mailBoxPos = {x = 1234, y = 1234, z = 7}
}

local rookitem = getPlayerDepotItems(cid, cfg.rookTownId)
local parcel = {} -- leave it
local label = doCreateItemEx(cfg.labelId, 1)
doSetItemText(label, getCreatureName(cid).. "\n" ..getTownName(townid))
if rookitem ~= nil then
    local check = 1
    for p = 1, math.ceil(#rookitem / 10) do
        parcel[p] = doCreateItemEx(cfg.parcelId, 1)
        doAddContainerItemEx(parcel[p], label)
    end
    for i = 1, #rookitem do
        local parcelNumber = 1
        if i > check * 10 then
            parcelNumber = parcelNumber + 1
            check = check + 1
        end
        doAddContainerItemEx(parcel[parcelNumber], rookitem[i])
        doTeleportThing(parcel[parcelNumber], cfg.mailBoxPos)
        -- doTileAddItemEx(cfg.mailBoxPos, parcel[parcelNumber]) -- for older TFS
    end
end


Oh god you helping here again!!!
"It may miss some UID etc, so be prepared for some bugs. But script's logic itself is ok."
Srry, i don't understand... What are u mean?
 
Last edited:
It will send all items from rook depo via parcel to new town. If you had 50 items in rook depo, script will send 5 parcels etc. It may miss some UID etc, so be prepared for some bugs. But script's logic itself is ok.

After
Code:
  -- remove all items from depot town id 7 and send everything to depot town id 9
Add
Code:
local cfg = {
    rookTownId = 7,
    parcelId = 2595,
    labelId = 2599,
    mailBoxPos = {x = 1234, y = 1234, z = 7}
}

local rookitem = getPlayerDepotItems(cid, cfg.rookTownId)
local parcel = {} -- leave it
local label = doCreateItemEx(cfg.labelId, 1)
doSetItemText(label, getCreatureName(cid).. "\n" ..getTownName(townid))
if rookitem ~= nil then
    local check = 1
    for p = 1, math.ceil(#rookitem / 10) do
        parcel[p] = doCreateItemEx(cfg.parcelId, 1)
        doAddContainerItemEx(parcel[p], label)
    end
    for i = 1, #rookitem do
        local parcelNumber = 1
        if i > check * 10 then
            parcelNumber = parcelNumber + 1
            check = check + 1
        end
        doAddContainerItemEx(parcel[parcelNumber], rookitem[i])
        doTeleportThing(parcel[parcelNumber], cfg.mailBoxPos)
        -- doTileAddItemEx(cfg.mailBoxPos, parcel[parcelNumber]) -- for older TFS
    end
end

THANK YOU!
but got some errors:
Code:
[13:25:20.775] [Error - NpcScript Interface]
[13:25:20.775] data/npc/scripts/oracle.lua:onCreatureSay
[13:25:20.775] Description:
[13:25:20.775] data/npc/scripts/oracle.lua:143: attempt to get length of local 'rookitem' (a number value)
[13:25:20.775] stack traceback:
[13:25:20.775]    data/npc/scripts/oracle.lua:143: in function 'callback'
[13:25:20.775]    data/npc/lib/npcsystem/npchandler.lua:423: in function 'onCreatureSay'
[13:25:20.775]    data/npc/scripts/oracle.lua:12: in function <data/npc/scripts/oracle.lua:12>

line 143 is
Code:
for p = 1, math.ceil(#rookitem / 10) do
 
THANK YOU!
but got some errors:
Code:
[13:25:20.775] [Error - NpcScript Interface]
[13:25:20.775] data/npc/scripts/oracle.lua:onCreatureSay
[13:25:20.775] Description:
[13:25:20.775] data/npc/scripts/oracle.lua:143: attempt to get length of local 'rookitem' (a number value)
[13:25:20.775] stack traceback:
[13:25:20.775]    data/npc/scripts/oracle.lua:143: in function 'callback'
[13:25:20.775]    data/npc/lib/npcsystem/npchandler.lua:423: in function 'onCreatureSay'
[13:25:20.775]    data/npc/scripts/oracle.lua:12: in function <data/npc/scripts/oracle.lua:12>

line 143 is
Code:
for p = 1, math.ceil(#rookitem / 10) do
getPlayerDepotItems doesn't return a table of every item from that depot id, it returns the number of items in that depot
unless there's a way to make it a container and get items from that i don't think you can do this
 
I know how to transfer all items from one depot to another. But it works ONLY for offline players. It is IMPOSSIBLE to make it work for online players in TFS 0.4 and earlier (there was no such function in sources yet).

For offline ver. you have to ONLY change 1 thing. Find in database player_depotitems then search for pid equal to your rook temple id and player_id equal to player which you want transfer items to. Then change pid from rook temple id to new town id.

This simple thing will transfer ALL items from previous depo to another. It wont work properly if player already have some items in new depot.

Why it wont work for online players?
Whenever a player logins, server is taking all information from db file into server's memory. At this point in memory there are such infos: player have items in rook dp and new town dp is empty. Whenever you executes this script right now, it will override infos in db file, not memory. Then, when a player logouts, server is saving all infos from memory into db file (overriding all changes made by your script.)


You can add doKickPlayer after player choses a new town. Then script will continue and it will transfer all items to new town.

Like i said, it is IMPOSSIBLE to make it work for online players, old TFS doesn't have such functions. The only alternative is doKickPlayer before script starts item transfer.
 
Last edited:
I know how to transfer all items from one depot to another. But it works ONLY for offline players. It is IMPOSSIBLE to make it work for online players in TFS 0.4 and earlier (there was no such function in sources yet).

For offline ver. you have to ONLY change 1 thing. Find in database player_depotitems then search for pid equal to your rook temple id and player_id equal to player which you want transfer items to. Then change pid from rook temple id to new town id.

This simple thing will transfer ALL items from previous depo to another. It wont work properly if player already have some items in new depot.

Why it wont work for online players?
Whenever a player logins, server is taking all information from db file into server's memory. At this point in memory there are such infos: player have items in rook dp and new town dp is empty. Whenever you executes this script right now, it will override infos in db file, not memory. Then, when a player logouts, server is saving all infos from memory into db file (overriding all changes made by your script.)


You can add doKickPlayer after player choses a new town. Then script will continue and it will transfer all items to new town.

Like i said, it is IMPOSSIBLE to make it work for online players, old TFS doesn't have such functions. The only alternative is doKickPlayer before script starts item transfer.

Oh fuck, so is better don't do it, thanks...
I was think to send items to main, because:

- Items in rook dp is saved in DB for nothing, players will never use it...
Then there is a way to when player go to main delete all items from rookgaard DP?
just to get a DB more clean, in oracle, on login idk...
You are more experienced... What u think about it?
 
In main, have a depot chest with a mailbox beside it, allow the player to access this depot only a set number of times, set it to the rook dp id. this way, they cannot continue to use this depot but they have the chance to move their items out of it.
Make a movement script and paste this into it, name it rookdp.lua
Code:
local storage = 1000 -- storage to store the access count
local limit = 5 -- number of times player is allowed to access this depot
function onStepIn(cid, item, position, fromPosition)
    if getCreatureStorage(cid, storage) >= limit then
        doTeleportThing(cid, fromPosition)
        doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You have already accessed this depot " .. limit .. " times and cannot access it again.")
        if getCreatureStorage(cid, storage + 1) < 0 then
            doCreatureSetStorage(cid, storage + 1, 1)
registerCreatureEvent(cid, "rookdp")
        end
    else
        doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You have now accessed this depot " .. getCreatureStorage(cid, storage) .. " times. You may access it " .. limit - getCreatureStorage(cid, storage) .. " more times.")
        doCreatureSetStorage(cid, storage, getCreatureStorage(cid, storage) + 1)
        if getCreatureStorage(cid, storage) >= limit then
            if getCreatureStorage(cid, storage + 1) < 0 then
                doCreatureSetStorage(cid, storage + 1, 1)
registerCreatureEvent(cid, "rookdp")
            end
        end
    end
   
    return true
end
in movements.xml put
Code:
<movevent type="StepIn" actionid="1000" event="script" value="rookdp.lua"/>
set actionid to whatever actionid you want


in creaturescripts/scripts add a script called rookdp.lua and paste this into it:
Code:
local storage = 1001
function onLogout(cid)
    local guid = getPlayerGUID(cid)
    if getCreatureStorage(cid, storage) > 0 then
        db.executeQuery("DELETE FROM `player_depotitems` WHERE `pid`=7 AND `player_id`="..guid)
        doCreatureSetStorage(cid, storage, 0)
    end
    return true
end

in creaturescripts.xml put
Code:
<event type="logout" name="rookdp" event="script" value="rookdp.lua" />

This should limit the player from accessing more than 5 times, and on the fifth time it will prevent them from accessing. if their rook depot has not been cleared but they are unable to access it anymore (checked by storage to avoid unnecessary database queries) it will register the onLogout event and when they next logout, it will clear their rook depot

let me know if you have any issues with that. Best way to do this sort of thing in that version.
 
I would prefer to do it Andu's way, but with a little finesse while online, to let the player know what is happening.

Oracle teleports + give vocation.
Player is sent to boat/temple, movement restricted + battlesign.
Message displayed in chat + on-screen advising they will be kicked in 15-30 seconds to finish their transition to main in the mythical back-end system.
Kick player, do database changes for their items.

Done.

Alternative to above,

Movement script outside of boat/temple area that doesn't allow them to leave until they relog, for the same reason as above.

This let's the player logout on their own, but may be worse in some ways. (database unable to complete all items before player can ctrl+g)
 
I would prefer to do it Andu's way, but with a little finesse while online, to let the player know what is happening.

Oracle teleports + give vocation.
Player is sent to boat/temple, movement restricted + battlesign.
Message displayed in chat + on-screen advising they will be kicked in 15-30 seconds to finish their transition to main in the mythical back-end system.
Kick player, do database changes for their items.

Done.

Alternative to above,

Movement script outside of boat/temple area that doesn't allow them to leave until they relog, for the same reason as above.

This let's the player logout on their own, but may be worse in some ways. (database unable to complete all items before player can ctrl+g)
you would have to create multiple queries for each item to change sids
that shit sounds horrible if you have a bunch of items in your depot lol
 
Don't use @RazorBlade script. Cuz it's only a trash. It will leave all useless entires in DB. Exactly like @Xeraphus said.

j6o3eg.jpg
 
Don't use @RazorBlade script. Cuz it's only a trash. It will leave all useless entires in DB. Exactly like @Xeraphus said.

j6o3eg.jpg
not all are trash cause you can create a function in sources to return depot of given id
use that cylinder and iterate through the cylinder and moving each item into new depot cylinder for the new town
database will update new contents of depot as the first depot should not have any more items since they have been transferred over
 
In my post's pic, changing 1021 entire's pid from 2 to 7, will transfer all items from 2 depo to 7. Like I wrote here. But it may cause issues if player already have items in transfer's destination town.

If using this script:
Code:
local storage = 1001
function onLogout(cid)
    local guid = getPlayerGUID(cid)
    if getCreatureStorage(cid, storage) > 0 then
        db.executeQuery("DELETE FROM `player_depotitems` WHERE `pid`=7 AND `player_id`="..guid)
        doCreatureSetStorage(cid, storage, 0)
    end
    return true
end
Will only delete 1021 entire. Leaving all other this in database. If you already did that for LARGE amount of players you may have lots of useless entires in database. To keep db clean, is good to remove all useless things from it. To do it, you can make an function like @Xeraphus said.
 
Don't use @RazorBlade script. Cuz it's only a trash. It will leave all useless entires in DB. Exactly like @Xeraphus said.

j6o3eg.jpg
I tested my script and it removed all items from the player's depot. However I'm also using a later version and there's no such thing as space outside the depot chest because of the inbox and market dealio. I literally actually used the information from YOUR comment to write it, so I guess you're the one who is trash.
For offline ver. you have to ONLY change 1 thing. Find in database player_depotitems then search for pid equal to your rook temple id and player_id equal to player which you want transfer items to. Then change pid from rook temple id to new town id.

This simple thing will transfer ALL items from previous depo to another. It wont work properly if player already have some items in new depot.



Edit:
Code:
local storage = 1001
function onLogout(cid)
    local guid = getPlayerGUID(cid)
    local townid = 7
    if getCreatureStorage(cid, storage) > 0 then
        local sids = {}
        local resultId = db.storeQuery('SELECT * FROM player_depotitems WHERE player_id=' guid)
        if resultId ~= false then
            repeat
                local pid = result.getDataInt(resultId, "pid")
                if pid == townid then
                    table.insert(sids, result.getDataInt(resultId, "sid"))
                end
            until not result.next(resultId)
            result.free(resultId)
        end

        db.executeQuery("DELETE FROM `player_depotitems` WHERE `pid`=7 AND `player_id`="..guid)
        for i = 1, #sids do
            db.executeQuery("DELETE FROM `player_depotitems` WHERE `pid`="..sids[i].." AND `player_id`="..guid)
        end
        doCreatureSetStorage(cid, storage, 0)
    end
    return true
end
this should delete all items and items within containers, since it checks for any sids involved with the town and deletes any items that have that sid as their pid. Happy now?
 
Last edited:
I tested my script and it removed all items from the player's depot. However I'm also using a later version and there's no such thing as space outside the depot chest because of the inbox and market dealio. I literally actually used the information from YOUR comment to write it, so I guess you're the one who is trash.

You hit own goal. You have to study all posts again. Trash.
 
Back
Top