• 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 Strange Errors :O

Adrenaline

Waiting for God
Joined
Jun 13, 2011
Messages
80
Reaction score
6
Location
Poland
Hi !

The Forgotten Server 0.3.6 - Debian6

At my server i have strange errors in console, who can say me what is it :O
Code:
[Error - CreatureScript Interface]
In a timer event called from:
buffer:onKill
Description:
[string "loadBuffer"]:120: attempt to perform arithmetic on global 'vocation_base_attackspeed' (a nil value)
stack traceback:
        [string "loadBuffer"]:120: in function 'createLoot'
        [string "loadBuffer"]:189: in function 'createChildLoot'
        [string "loadBuffer"]:228: in function <[string "loadBuffer"]:212>
 
Last edited:
How to repair it ;s

HTML:
[Error - CreatureScript Interface]
In a timer event called from:
buffer:onKill
Description:
[string "loadBuffer"]:83: bad argument #1 to 'pairs' (table expected, got nil)
stack traceback:
        [C]: in function 'pairs'
        [string "loadBuffer"]:83: in function 'createLoot'
        [string "loadBuffer"]:225: in function <[string "loadBuffer"]:212>
 
the first parameter ur giving to pairs at line 83 isn't a table

we can't help u fix it without the code, we can only say what's wrong with it
 
Code:
	for k, v in pairs(tiers) do
you're missing the config? :\
Code:
<?xml version="1.0" encoding="UTF-8"?>
<mod name="Random Item Stats" enabled="1">
[B][COLOR="#FF0000"]<config name="itemstats_conf"><![CDATA[
-- //
	extra_loot_key = 123 --: optional storage for higher loot rate
	vocation_base_attackspeed = getVocationInfo(1).attackSpeed --: used for attackSpeed stat
-- //

tiers, attr = {}, {}

tiers['rare'] = {
	color = 66, -- color of 'RARE' text
	extra = {0, 0},
	attrNames = true, -- show attribute names instead of rare
	chance = {
		[1] = 10000,
		[2] = 5000 -- chance for 2nd stat
	}
}
tiers['epic'] = {
	color = 35,
	extra = {7, 20}, -- additional percent bonus
	chance = {
		[1] = 3333,
		[2] = 25000
	}
}
tiers['legendary'] = {
	color = 149,
	extra = {20, 35},
	chance = {
		[1] = 1000,
		[2] = 100000 -- 2 bonuses always
	}
}

MELEE = 0
DISTANCE = 1
ARMOR = 2
SHIELD = 3
WAND = 4
DURATION_RING = 5
CHARGES = 6

--! attributes
attr['quick'] = {
	attr = 'attackSpeed',
	name = 'Attack Speed',
	percent = {6, 20},
	types = {MELEE, DISTANCE, WAND}
}
attr['fortified'] = {
	attr = 'extraDefense',
	base = 'defense',
	name = 'Defense',
	percent = {7, 25},
	types = {MELEE, SHIELD}
}
attr['deadly'] = {
	attr = 'extraAttack',
	base = 'attack',
	name = 'Attack',
	types = {MELEE},
	percent = {7, 25}
}
attr['strong'] = {
	attr = 'armor',
	name = 'Armor',
	percent = {7, 20},
	types = {ARMOR}
}
attr['hawkeye\'s'] = {
	attr = 'hitChance',
	name = 'Hit Chance',
	percent = {10, 25},
	types = {DISTANCE}
}
--[[ // not available without source edit
attr['farsight'] = {
	attr = 'shootRange',
	name = 'Shoot Range',
	percent = {17, 34},
	types = {DISTANCE, WAND}
}
]]
attr['charged'] = {
	attr = 'charges',
	name = 'Charges',
	percent = {30, 45},
	types = {CHARGES}
}
attr['divine'] = {
	attr = 'duration',
	name = 'Duration',
	percent = {35, 50},
	types = {DURATION_RING}
}
--/ attributes

rate = getConfigInfo('rateLoot')

if( getConfigInfo('monsterLootMessage') ~= 0 )then
	print('[Notice] Set monsterLootMessage = 0 to prevent duplicate loot messages')
end
]]></config>[/COLOR][/B]

<event type="kill" name="itemstats" event="script"><![CDATA[
domodlib('itemstats_conf')

function round(n, s)
	return tonumber(('%.' .. (s or 0) .. 'f'):format(n))
end

function getContentDescription(uid, sep)
	local ret, i, containers = '', 0, {}
	while( i < getContainerSize(uid) )do
		local v, s = getContainerItem(uid, i), ''
		local k = getItemInfo(v.itemid)
		k.name = getItemAttribute(v.uid, 'name') or k.name
		if( k.name ~= '' )then
			if( v.type > 1 and k.stackable and k.showCount )then
				s = v.type .. ' ' .. k.plural
			else
				local article = getItemAttribute(v.uid, 'article') or k.article
				s = (article == '' and '' or article .. ' ') .. k.name
			end
			ret = ret .. (i == 0 and not sep and '' or ', ') .. s
			if( isContainer(v.uid) and getContainerSize(v.uid) ~= 0 )then
				table.insert(containers, v.uid)
			end
		else
			ret = ret .. (i == 0 and not sep and '' or ', ') .. 'an item of type ' .. v.itemid .. ', please report it to gamemaster'
		end
		i = i + 1
	end
	for i = 1, #containers do
		ret = ret .. getContentDescription(containers[i], true)
	end
	return ret
end

local function send(cid, corpse, monster)
	if( isPlayer(cid) )then
		local ret = isContainer(corpse) and getContentDescription(corpse)
		doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'Loot of ' .. monster .. ': ' .. (ret ~= '' and ret or 'nothing'))
		local party = getPlayerParty(cid)
		if( party )then
			for _, pid in ipairs(getPartyMembers(party)) do
				doPlayerSendChannelMessage(pid, '', 'Loot of ' .. monster .. ': ' .. (ret ~= '' and ret or 'nothing'), TALKTYPE_CHANNEL_W, CHANNEL_PARTY)
			end
		end
	end
end

local function createLoot(i, ext)
	local item = type(i.id) == 'table' and i.id[math.random(#i.id)] or i.id
	local random = math.ceil(math.random(100000) / ext)
	local tmpItem, f

	if( random < i.chance )then
		if i.subType == -1 then
			f = getItemInfo(item)
		end
		tmpItem = doCreateItemEx(item,
			i.subType ~= -1 and i.subType or
			f.stackable and random % i.count + 1 or
			f.charges ~= 0 and f.charges or
			1
		)
	end

	if( not tmpItem )then
		return
	end

	if( i.actionId ~= -1 )then
		doItemSetAttribute(tmpItem, 'aid', i.actionId)
	end

	if( i.uniqueId ~= -1 )then
		doItemSetAttribute(tmpItem, 'uid', i.uniqueId)
	end

	if( i.text ~= '' )then
		doItemSetAttribute(tmpItem, 'text', i.text)
	end

	local ret, done

	for k, v in pairs(tiers) do
		local cur, used = {}, {}
		for i = 1, #v.chance do
			if( math.random(100000) <= v.chance[i] )then
				if( f )then
					f = getItemInfo(item)
				end
				if( not f.stackable )then
					for m, n in pairs(attr) do
						if( not table.find(used, m) and
						(
							( table.find(n.types, MELEE) and table.find({WEAPON_SWORD, WEAPON_CLUB, WEAPON_AXE}, f.weaponType) ) or
							( table.find(n.types, DISTANCE) and f.weaponType == WEAPON_DIST and f.ammoType ~= 0 ) or
							( table.find(n.types, ARMOR) and f.armor ~= 0 and f.wieldPosition ~= CONST_SLOT_NECKLACE ) or
							( table.find(n.types, SHIELD) and f.defense ~= 0 and f.weaponType == WEAPON_SHIELD ) or
							( table.find(n.types, WAND) and f.weaponType == WEAPON_WAND ) or
							( table.find(n.types, DURATION_RING) and f.wieldPosition == CONST_SLOT_RING and f.transformEquipTo ~= 0 ) or
							( table.find(n.types, CHARGES) and table.find({CONST_SLOT_RING, CONST_SLOT_NECKLACE}, f.wieldPosition) and f.charges ~= 0 )
						) )then
							table.insert(cur, m)
						end
					end

					if( #cur ~= 0 )then
						local n = cur[math.random(#cur)]
						table.insert(used, n)

						n = attr[n]
						local percent, new, tmp = math.random(n.percent[1] + (v.extra[1] or 0), n.percent[2] + (v.extra[2] or 0))
						-- hacks
						if( n.attr == 'duration' )then
							tmp = getItemInfo(f.transformEquipTo)
							if tmp.transformDeEquipTo ~= item then
								break
							end
							new = round( tmp.decayTime * (1 + percent / 100) * 1000 )
						elseif( n.attr == 'attackSpeed' )then
							new = round( vocation_base_attackspeed / (1 + percent / 100) )
						elseif( n.attr == 'hitChance' ) then
							new = round(
								f.hitChance == -1 and
									percent
								or 
									f.hitChance * (1 + percent / 100)
							)
						else
							new = round(
								n.base and
									f[n['attr']] + f[n['base']] * (percent / 100)
								or
									f[n['attr']] * (1 + percent / 100)
							)

							if( new == f[n[n.base and 'base' or 'attr']] )then -- no improvement
								break
							end
						end

						doItemSetAttribute(tmpItem, n.attr:lower(), new)

						local name = getItemAttribute(tmpItem, 'name')
						if( v.attrNames or not name )then
							local name = (v.attrNames and used[#used] or k) .. ' ' .. (name or f.name)
							doItemSetAttribute(tmpItem, 'name', name)

							if( f.article ~= '' )then
								local article = getArticle(name)
								if( article ~= f.article )then
									doItemSetAttribute(tmpItem, 'article', article)
								end
							end
						end

						local desc = getItemAttribute(tmpItem, 'description') or f.description
						doItemSetAttribute(tmpItem, 'description', '[' .. n.name .. ': +' .. percent .. '%]' .. (desc == '' and '' or '\n' .. desc))

						ret = k
					end
					cur = {}
					if( #v.chance == i )then
						done = true
					end
				end
			else
				done = i ~= 1
				break
			end
		end
		if( done )then
			break
		end
	end

	return tmpItem, ret
end

local function createChildLoot(parent, i, ext, pos)
	if( not i or #i == 0 )then
		return true
	end

	local size, cap = 0, getContainerCap(parent)
	for k = 1, #i do
		if( size == cap )then
			break
		end
		local tmp, ret = createLoot(i[k], ext)
		if( tmp )then
			if( isContainer(tmp) )then
				if( createChildLoot(tmp, i[k].child, ext, pos) )then
					doAddContainerItemEx(parent, tmp)
					size = size + 1
				else
					doRemoveItem(tmp)
				end
			else
				if( ret )then
					doSendMagicEffect(pos, CONST_ME_MAGIC_GREEN)
					doSendAnimatedText(pos, ret:upper(), tiers[ret].color)
				end
				doAddContainerItemEx(parent, tmp)
				size = size + 1
			end
		end
	end

	return size > 0
end

local function dropLoot(pos, v, ext, master, cid, target)
	local corpse
	if( not master or master == target )then -- 0.3/4
		corpse = getTileItemById(pos, v.lookCorpse).uid
		if( isContainer(corpse) )then
			for i = 1, getContainerSize(corpse) do
				doRemoveItem(getContainerItem(corpse, 0).uid)
			end
			local size, cap = 0, getContainerCap(corpse)
			for i = 1, #v.loot do
				if( size == cap )then
					break
				end
				local tmp, ret = createLoot(v.loot[i], ext)
				if( tmp )then
					if( isContainer(tmp) )then
						if( createChildLoot(tmp, v.loot[i].child, ext, pos) )then
							doAddContainerItemEx(corpse, tmp)
							size = size + 1
						else
							doRemoveItem(tmp)
						end
					else
						if( ret )then
							doSendMagicEffect(pos, CONST_ME_MAGIC_GREEN)
							doSendAnimatedText(pos, ret:upper(), tiers[ret].color)
						end
						doAddContainerItemEx(corpse, tmp)
						size = size + 1
					end
				end
			end
		end
	end
	send(cid, corpse, v.description)
end

function onKill(cid, target, damage, flags)
	if( (damage == true or bit.band(flags, 1) == 1) and isMonster(target) )then -- 0.3/4
		local v = getMonsterInfo(getCreatureName(target))
		if( v and v.lookCorpse ~= 0 )then
			local s = getCreatureStorage(cid, extra_loot_key)
			addEvent(dropLoot, 0, getThingPos(target), v, s == -1 and rate or s, getCreatureMaster(target), cid, target)
		end
	end
	return true
end
]]></event>

<event type="login" name="itemstats_login" event="buffer"><![CDATA[
	registerCreatureEvent(cid, 'itemstats')
]]></event>

</mod>
 
Code:
	for k, v in pairs(tiers) do
you're missing the config? :\

yyy dont know what missing.. i only delete all comments (--)

This is my file:
PHP:
<?xml version="1.0" encoding="UTF-8"?>
<mod name="Random Item Stats" enabled="1">
<config name="itemstats_conf"><![CDATA[

-- //
	extra_loot_key = 123 --: optional storage for higher loot rate
	vocation_base_attackspeed = getVocationInfo(1).attackSpeed --: used for attackSpeed stat
-- //

tiers, attr = {}, {}
 
tiers['rare'] = {
	color = 66,
	extra = {0, 0},
	attrNames = true,
	chance = {
		[1] = 10000,
		[2] = 5000
	}
}
tiers['epic'] = {
	color = 35,
	extra = {7, 20},
	chance = {
		[1] = 3333,
		[2] = 25000
	}
}
tiers['legendary'] = {
	color = 149,
	extra = {20, 35},
	chance = {
		[1] = 1000,
		[2] = 100000
	}
}
 
MELEE = 0
DISTANCE = 1
ARMOR = 2
SHIELD = 3
WAND = 4
DURATION_RING = 5
CHARGES = 6
 

attr['quick'] = {
	attr = 'attackSpeed',
	name = 'Attack Speed',
	percent = {6, 20},
	types = {MELEE, DISTANCE, WAND}
}
attr['fortified'] = {
	attr = 'extraDefense',
	base = 'defense',
	name = 'Defense',
	percent = {7, 25},
	types = {MELEE, SHIELD}
}
attr['deadly'] = {
	attr = 'extraAttack',
	base = 'attack',
	name = 'Attack',
	types = {MELEE},
	percent = {7, 25}
}
attr['strong'] = {
	attr = 'armor',
	name = 'Armor',
	percent = {7, 20},
	types = {ARMOR}
}
attr['hawkeye\'s'] = {
	attr = 'hitChance',
	name = 'Hit Chance',
	percent = {10, 25},
	types = {DISTANCE}
}

attr['farsight'] = {
	attr = 'shootRange',
	name = 'Shoot Range',
	percent = {17, 34},
	types = {DISTANCE, WAND}
}
]]
attr['charged'] = {
	attr = 'charges',
	name = 'Charges',
	percent = {30, 45},
	types = {CHARGES}
}
attr['divine'] = {
	attr = 'duration',
	name = 'Duration',
	percent = {35, 50},
	types = {DURATION_RING}
}

 
rate = getConfigInfo('rateLoot')
 
if( getConfigInfo('monsterLootMessage') ~= 0 )then
	print('[Notice] Set monsterLootMessage = 0 to prevent duplicate loot messages')
end
]]></config>
 
<event type="kill" name="itemstats" event="script"><![CDATA[
domodlib('itemstats_conf')
 
function round(n, s)
	return tonumber(('%.' .. (s or 0) .. 'f'):format(n))
end
 
function getContentDescription(uid, sep)
	local ret, i, containers = '', 0, {}
	while( i < getContainerSize(uid) )do
		local v, s = getContainerItem(uid, i), ''
		local k = getItemInfo(v.itemid)
		k.name = getItemAttribute(v.uid, 'name') or k.name
		if( k.name ~= '' )then
			if( v.type > 1 and k.stackable and k.showCount )then
				s = v.type .. ' ' .. k.plural
			else
				local article = getItemAttribute(v.uid, 'article') or k.article
				s = (article == '' and '' or article .. ' ') .. k.name
			end
			ret = ret .. (i == 0 and not sep and '' or ', ') .. s
			if( isContainer(v.uid) and getContainerSize(v.uid) ~= 0 )then
				table.insert(containers, v.uid)
			end
		else
			ret = ret .. (i == 0 and not sep and '' or ', ') .. 'an item of type ' .. v.itemid .. ', please report it to gamemaster'
		end
		i = i + 1
	end
	for i = 1, #containers do
		ret = ret .. getContentDescription(containers[i], true)
	end
	return ret
end
 
local function send(cid, corpse, monster)
	if( isPlayer(cid) )then
		local ret = isContainer(corpse) and getContentDescription(corpse)
		doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'Loot of ' .. monster .. ': ' .. (ret ~= '' and ret or 'nothing'))
		local party = getPlayerParty(cid)
		if( party )then
			for _, pid in ipairs(getPartyMembers(party)) do
				doPlayerSendChannelMessage(pid, '', 'Loot of ' .. monster .. ': ' .. (ret ~= '' and ret or 'nothing'), TALKTYPE_CHANNEL_W, CHANNEL_PARTY)
			end
		end
	end
end
 
local function createLoot(i, ext)
	local item = type(i.id) == 'table' and i.id[math.random(#i.id)] or i.id
	local random = math.ceil(math.random(100000) / ext)
	local tmpItem, f
 
	if( random < i.chance )then
		if i.subType == -1 then
			f = getItemInfo(item)
		end
		tmpItem = doCreateItemEx(item,
			i.subType ~= -1 and i.subType or
			f.stackable and random % i.count + 1 or
			f.charges ~= 0 and f.charges or
			1
		)
	end
 
	if( not tmpItem )then
		return
	end
 
	if( i.actionId ~= -1 )then
		doItemSetAttribute(tmpItem, 'aid', i.actionId)
	end
 
	if( i.uniqueId ~= -1 )then
		doItemSetAttribute(tmpItem, 'uid', i.uniqueId)
	end
 
	if( i.text ~= '' )then
		doItemSetAttribute(tmpItem, 'text', i.text)
	end
 
	local ret, done
 
	for k, v in pairs(tiers) do
		local cur, used = {}, {}
		for i = 1, #v.chance do
			if( math.random(100000) <= v.chance[i] )then
				if( f )then
					f = getItemInfo(item)
				end
				if( not f.stackable )then
					for m, n in pairs(attr) do
						if( not table.find(used, m) and
						(
							( table.find(n.types, MELEE) and table.find({WEAPON_SWORD, WEAPON_CLUB, WEAPON_AXE}, f.weaponType) ) or
							( table.find(n.types, DISTANCE) and f.weaponType == WEAPON_DIST and f.ammoType ~= 0 ) or
							( table.find(n.types, ARMOR) and f.armor ~= 0 and f.wieldPosition ~= CONST_SLOT_NECKLACE ) or
							( table.find(n.types, SHIELD) and f.defense ~= 0 and f.weaponType == WEAPON_SHIELD ) or
							( table.find(n.types, WAND) and f.weaponType == WEAPON_WAND ) or
							( table.find(n.types, DURATION_RING) and f.wieldPosition == CONST_SLOT_RING and f.transformEquipTo ~= 0 ) or
							( table.find(n.types, CHARGES) and table.find({CONST_SLOT_RING, CONST_SLOT_NECKLACE}, f.wieldPosition) and f.charges ~= 0 )
						) )then
							table.insert(cur, m)
						end
					end
 
					if( #cur ~= 0 )then
						local n = cur[math.random(#cur)]
						table.insert(used, n)
 
						n = attr[n]
						local percent, new, tmp = math.random(n.percent[1] + (v.extra[1] or 0), n.percent[2] + (v.extra[2] or 0))

						if( n.attr == 'duration' )then
							tmp = getItemInfo(f.transformEquipTo)
							if tmp.transformDeEquipTo ~= item then
								break
							end
							new = round( tmp.decayTime * (1 + percent / 100) * 1000 )
						elseif( n.attr == 'attackSpeed' )then
							new = round( vocation_base_attackspeed / (1 + percent / 100) )
						elseif( n.attr == 'hitChance' ) then
							new = round(
								f.hitChance == -1 and
									percent
								or 
									f.hitChance * (1 + percent / 100)
							)
						else
							new = round(
								n.base and
									f[n['attr']] + f[n['base']] * (percent / 100)
								or
									f[n['attr']] * (1 + percent / 100)
							)
 
							if( new == f[n[n.base and 'base' or 'attr']] )then
								break
							end
						end
 
						doItemSetAttribute(tmpItem, n.attr:lower(), new)
 
						local name = getItemAttribute(tmpItem, 'name')
						if( v.attrNames or not name )then
							local name = (v.attrNames and used[#used] or k) .. ' ' .. (name or f.name)
							doItemSetAttribute(tmpItem, 'name', name)
 
							if( f.article ~= '' )then
								local article = getArticle(name)
								if( article ~= f.article )then
									doItemSetAttribute(tmpItem, 'article', article)
								end
							end
						end
 
						local desc = getItemAttribute(tmpItem, 'description') or f.description
						doItemSetAttribute(tmpItem, 'description', '[' .. n.name .. ': +' .. percent .. '%]' .. (desc == '' and '' or '\n' .. desc))
 
						ret = k
					end
					cur = {}
					if( #v.chance == i )then
						done = true
					end
				end
			else
				done = i ~= 1
				break
			end
		end
		if( done )then
			break
		end
	end
 
	return tmpItem, ret
end
 
local function createChildLoot(parent, i, ext, pos)
	if( not i or #i == 0 )then
		return true
	end
 
	local size, cap = 0, getContainerCap(parent)
	for k = 1, #i do
		if( size == cap )then
			break
		end
		local tmp, ret = createLoot(i[k], ext)
		if( tmp )then
			if( isContainer(tmp) )then
				if( createChildLoot(tmp, i[k].child, ext, pos) )then
					doAddContainerItemEx(parent, tmp)
					size = size + 1
				else
					doRemoveItem(tmp)
				end
			else
				if( ret )then
					doSendMagicEffect(pos, CONST_ME_MAGIC_GREEN)
					doSendAnimatedText(pos, ret:upper(), tiers[ret].color)
				end
				doAddContainerItemEx(parent, tmp)
				size = size + 1
			end
		end
	end
 
	return size > 0
end
 
local function dropLoot(pos, v, ext, master, cid, target)
	local corpse
	if( not master or master == target )then
		corpse = getTileItemById(pos, v.lookCorpse).uid
		if( isContainer(corpse) )then
			for i = 1, getContainerSize(corpse) do
				doRemoveItem(getContainerItem(corpse, 0).uid)
			end
			local size, cap = 0, getContainerCap(corpse)
			for i = 1, #v.loot do
				if( size == cap )then
					break
				end
				local tmp, ret = createLoot(v.loot[i], ext)
				if( tmp )then
					if( isContainer(tmp) )then
						if( createChildLoot(tmp, v.loot[i].child, ext, pos) )then
							doAddContainerItemEx(corpse, tmp)
							size = size + 1
						else
							doRemoveItem(tmp)
						end
					else
						if( ret )then
							doSendMagicEffect(pos, CONST_ME_MAGIC_GREEN)
							doSendAnimatedText(pos, ret:upper(), tiers[ret].color)
						end
						doAddContainerItemEx(corpse, tmp)
						size = size + 1
					end
				end
			end
		end
	end
	send(cid, corpse, v.description)
end
 
function onKill(cid, target, damage, flags)
	if( (damage == true or bit.band(flags, 1) == 1) and isMonster(target) )then
		local v = getMonsterInfo(getCreatureName(target))
		if( v and v.lookCorpse ~= 0 )then
			local s = getCreatureStorage(cid, extra_loot_key)
			addEvent(dropLoot, 0, getThingPos(target), v, s == -1 and rate or s, getCreatureMaster(target), cid, target)
		end
	end
	return true
end
]]></event>
 
<event type="login" name="itemstats_login" event="buffer"><![CDATA[
	registerCreatureEvent(cid, 'itemstats')
]]></event>
 
</mod>
 
Back
Top