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

Action [TFS 1.x] open world style chests

zbizu

Legendary OT User
Joined
Nov 22, 2010
Messages
3,323
Solutions
26
Reaction score
2,690
Location
Poland
Remember all those RPG games where you used to find chests with random loot in areas filled with enemies?
Well, this is what this script does adapted to multiplayer style of ot servers.

Warning! Set an unique id to the chest so no one will be able to move or take it!

So what this script does?
- a player opens a chest, it generates items inside, works as normal chest until certain time passes (1h in script, can be changed)
- if you or any player open that chest within that 1h - it behaves like a normal chest.
- if you or any other player open that chest after 1h passes, all items inside will be removed and new loot will be generated

What you can do with it?
- Generated items may depend on skills, quests done, level, storage-based luck stat, buffs etc.
- A chest can do other actions such as summoning something, inflicting damage, etc.

Warning!
Script may conflict with some questsystems.
Make sure to test this script with your questsystems before adding it to your server.

actions.xml
Code:
<action actionid="7895" script="openworldchest.lua"/>

openworldchest.lua
Code:
if not worldchests then
	worldchests = {}
end

if not table.find then
	table.find = function(table, value)
		for i, v in pairs(table) do
			if v == value then
				return i
			end
		end
		return nil
	end
end

function Container:clear()
	for i = 0, self:getItemHoldingCount() - 1 do
		self:getItem(0):remove()
	end
	return true
end

local interval = 3600 -- time to generate new loot (in seconds)
local actionid = 7895 -- actionid to assign in RME
local allowDuplicates = false -- for default setting

-- uid will serve as chest identificator. It will prevent moving the chest and will allow to make every chest script unique.

local defaultrewards = {
-- id, chance(100000 = 100.000%), countmax(default 1)
{2148, 45000, 50}, -- gold coin
{2152, 10000, 10}, -- platinum coin
{2398, 60000}, -- mace
{2187, 450}, -- wand of inferno
{2197, 3000} -- stone skin amulet
}
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
	if item.actionid ~= actionid then
		return false
	end
	
	if not worldchests[item.uid] then
		worldchests[item.uid] = 0
	end

	if os.time() < worldchests[item.uid] then
		return false
	end
	
	worldchests[item.uid] = os.time() + interval
	local c = Container(item.uid)
	
	local clear = true -- put "clear = false" in your unique chest "if" statement if you plan to not use "return false"
	
	-- unique chest action example
	if item.uid == 27500 then
		c:clear()
		-- chest with gold in random amounts only
		local newitem = defaultrewards[1]
		for i = 1, math.random(1, 10) do
			if math.random(1, 100000) < newitem[2] then
				local count = 1
				if newitem[3] then
					count = math.random(1, newitem[3])
				end
				c:addItem(newitem[1], count)
			end
		end
		
		-- clear = false -- see local clear
		return false -- if you put return here, default action below won't be executed
	end
	
	-- you can put other unique chests here
	-- if you forget return false, default action will also be executed
	
	-- default action
	local items = 0
	local maxItems = math.random(0, 5)
	local attempts = 0
	local dupcheck = {}
	
	if clear then
		c:clear()
	end
	
	while (items <= maxItems) and (items <= #defaultrewards) and (attempts < 1000) do
		local nid = math.random(1, #defaultrewards)
		local newitem = defaultrewards[nid]
		if allowDuplicates or not table.find(dupcheck, nid) then
			if math.random(1, 100000) < newitem[2] then
				local count = 1
				if newitem[3] then
					count = math.random(1, newitem[3])
				end
				
				c:addItem(newitem[1], count)
				
				if not allowduplicates then
					table.insert(dupcheck, nid)
				end
				
				items = items + 1
			end
			
		end
		
		attempts = attempts + 1	
	end
	
	return false
end
 
Oh man this is awesome, I missed daily quests!

Just tested it out and it works perfect. How would I go about adding different daily chests with different rewards? Do I just create another action.lua with different actionid/items and call it again in actions.xml?
 
you add if statement checking uid in same script and then entry in actions.xml
 
Okay so I successfully added a second globalchest -yay- , now I'm just a bit confused on the function to add items..I set a local reward
Code:
local ccrewards = {
{2160, 45000, 50}
}
and I called it with uid using your example:
Code:
if item.uid == 51001 then
        c:clear()
        -- chest with gold in random amounts only
        local newitem = ccrewards[1]
        for i = 1, math.random(1, 10) do
            if math.random(1, 100000) < newitem[2] then
                local count = 1
                if newitem[3] then
                    count = math.random(1, newitem[3])
                end
                c:addItem(newitem[1], count)
            end
        end
       
        return false 
    end
I'm not sure on what to change in order for it to just call math.random (maxcount)...I set it to 50 but I got 125 and 113.

Also, do I need to create a new local actionid for some reason? I ask because I didn't and it still seems to work with actionid 7896 as the second chest so I was wondering what the purpose of it actually is?
 
Idea: Broadcast player name and what he got for items with 10% chance or lower
Edit: Not working properly, players can open the chest infinite amount of times and get items, pluse even if I have a chance of 1 I get the item almost every time :(
And I am using TFS 1.2

Edit 2: Ok I'm stupid I was missing the UID :facepalm:
 
Last edited:
I can open the chest indefinitely with new rewards generating every time. No errors in console.
 
Can someone help me with this error?

ERROR:

...openworldchest.lua: onUse
Description:
...openworldchest.lua:45: attempt to call global 'Container' (a nil value)

I dont know if someone still helping but I hope yes!
 
The idea is amazing but wouldn't it be better to add it to every chest (without action id) with the specific item id?
This will be so hard to add action & unique id to all chests 🤔
 
Is it possible to remove unique identifier from this script and make the chest unmovable with code instead?
Just like tejdi commented 3 years ago.
 
Back
Top