Jump to content

tabke expected, got boolean


kukimuki

Recommended Posts

local sx, sy = guiGetScreenSize();
local relX, relY = sx/1600, sy/900;

local isInventoryVisible = true;

local invWindow = {0.35, 0.325};
local windowMove = {false, false};

local dragNDrop = {}; -- slot, előzőSlot

function loadWindowPos()
	if (fileExists("@invPos.xml")) then
		local xmlNode = xmlLoadFile("@invPos.xml", true);
		local x = xmlNodeGetAttribute(xmlNode, "x");
		local y = xmlNodeGetAttribute(xmlNode, "y");
		invWindow = {x, y};
		xmlUnloadFile(xmlNode);
	end
end
loadWindowPos();

function saveWindowPos()
	local xmlNode;
	if (fileExists("@invPos.xml")) then
		xmlNode = xmlLoadFile("@invPos.xml");
	else
		xmlNode = xmlCreateFile("@invPos.xml", "root");
	end
	xmlNodeSetAttribute(xmlNode, "x", invWindow[1]);
	xmlNodeSetAttribute(xmlNode, "y", invWindow[2]);
	xmlSaveFile(xmlNode);
	xmlUnloadFile(xmlNode);
end

local slots = {};

function processSlots()
	local xGap = 0;
	local yGap = 0;
	local slotCount = 0;

	for i=1, 60, 1 do
		if not (slots[i]) then
			slots[i] = {};
		end
		slots[i][1] = (invWindow[1]+0.015)+xGap;
		slots[i][2] = (invWindow[2]+0.055)+yGap;
		slots[i][3] = (invWindow[1]+0.015+0.025)+xGap;
		slots[i][4] = (invWindow[2]+0.055+0.044)+yGap;
		if not (slots[i][5]) then
			slots[i][5] = {false};
		end
		xGap = xGap+0.027;
		slotCount = slotCount+1;
		if (slotCount >= 10) then
			yGap = yGap+0.048;
			xGap = 0;
			slotCount = 0;
		end
	end
end

processSlots();

function toggleCursor()
	showCursor(not isCursorShowing());
end
bindKey("m", "down", toggleCursor);

function toggleInventory()
	isInventoryVisible = not isInventoryVisible;
end
bindKey("i", "down", toggleInventory);

function dxDrawBox(x, y, sizeX, sizeY, color, width, postGUI)
	dxDrawLine(sx*(x), sy*(y), sx*(x+sizeX), sy*(y), color, width, postGUI);
	dxDrawLine(sx*(x+sizeX), sy*(y), sx*(x+sizeX), sy*(y+sizeY), color, width, postGUI);
	dxDrawLine(sx*(x), sy*(y+sizeY), sx*(x+sizeX), sy*(y+sizeY), color, width, postGUI);
	dxDrawLine(sx*(x), sy*(y), sx*(x), sy*(y+sizeY), color, width, postGUI);
end

function drawInventory()
	if (isInventoryVisible) then

		dxDrawRectangle(sx*(invWindow[1]), sy*(invWindow[2]), sx*0.3, sy*0.05, tocolor(50, 60, 70, 255), false);
		dxDrawText("Inventory", sx*(invWindow[1]), sy*(invWindow[2]), sx*(invWindow[1]+0.3), sy*(invWindow[2]+0.05), tocolor(255, 255, 255, 255), relX*2, relY*2, "default-bold", "center", "center", false, false, false, false);

		dxDrawRectangle(sx*(invWindow[1]), sy*(invWindow[2]+0.05), sx*0.3, sy*0.3, tocolor(0, 0, 0, 200), false);
		dxDrawBox(invWindow[1], invWindow[2], 0.3, 0.35, tocolor(255, 255, 255, 255), 1, false);

		for i, slot in ipairs(slots) do
			dxDrawRectangle(sx*slot[1], sy*slot[2], sx*0.025, sy*0.044, tocolor(255, 255, 255, 50), false);
			if (slot[5][1]) then
				-- dxDrawRectangle(sx*slot[1], sy*slot[2], sx*0.025, sy*0.044, tocolor(0, 175, 0, 255), false);
				dxDrawImage(sx*slot[1], sy*slot[2], sx*0.025, sy*0.044, "items/"..slot[5][1]..".png", 0, 0, 0, tocolor(255, 255, 255, 255), false);
				dxDrawText(slot[5][2], sx*slot[1], sy*(slot[2]), sx*(slot[3]), sy*(slot[4]), tocolor(255, 255, 255, 255), relX*1.5, relY*1.5, "default-bold", "center", "center", false, false, false, false);
			end
			-- dxDrawText(i, sx*(slot[1]), sy*(slot[2]), sx*(slot[3]), sy*(slot[4]), tocolor(255, 255, 255, 255), relX*1, relY*1, "sans", "center", "center", false, false, false, false);
		end

		if (windowMove[1]) then
			local cX, cY = getCursorPosition();
			invWindow[1] = cX-windowMove[1];
			invWindow[2] = cY-windowMove[2];
			processSlots();
		end

		if (dragNDrop[1]) then
			local cX, cY = getCursorPosition();
			dxDrawImage(sx*cX-20, sy*cY-20, 40, 40, "items/"..dragNDrop[1][1]..".png", 0, 0, 0, tocolor(255, 255, 255, 255), false);
		end

	end
end
addEventHandler("onClientRender", root, drawInventory);

function isInBox(x, y, x2, y2)
	if (isCursorShowing()) then
		local cX, cY = getCursorPosition();
		if ( (cX >= x) and (cY >= y) and (cX <= x2) and (cY <= y2) ) then
			return true;
		else
			return false;
		end
	else
		return false;
	end
end

function onItemClick(slot, slotId)
	if (items[slot[1]][4] == "Food") then
		outputChatBox("Ettél!");
		slot[2] = slot[2]-1;
		if (slot[2] == 0) then
			deleteLocalItemBySlot(slotId);
		end
	elseif (items[slot[1]][4] == "Weapon") then
		triggerServerEvent("weaponSelected", resourceRoot, weapons[slot[1]]);
	end
	if (items[slot[1]][4] ~= "Weapon") then
		refreshElementData();
	end
end

function onDropEnd()
	for i, slot in ipairs(slots) do
		if (isInBox(slot[1], slot[2], slot[3], slot[4])) then -- Sloton engedtük bal-egeret
			if (slot[5]) then -- Ha ezen a sloton van valami
				if (slot[5][1] == dragNDrop[1][1]) then -- Ha ez a valami ugyan az mint a kezünkben lévő valami
					if (slot[5][2] < items[slot[5][1]][3]) then -- Ha a sloton lévő item mennyisége kisebb mint a stackLimit
						if (slot[5][2]+dragNDrop[1][2] > items[slot[5][1]][3]) then -- Ha sloton lévő item mennyiség + kezünkben lévő item mennyiség az nagyobb mint a stackLimit
							local prevAmount = slot[5][2];
							slot[5][2] = items[slot[5][1]][3]; -- A sloton lévő valami mennyisége legyen stackLimit
							dragNDrop[1][2] = dragNDrop[1][2]-prevAmount;
							slots[dragNDrop[2]][5] = dragNDrop[1]; -- A dragNDrop-ból vissza rakjuk az itemet a helyére
						else
							slot[5][2] = slot[5][2]+dragNDrop[1][2]; -- A sloton lévő item mennyiségéhez hozzáadjuk a kezünkben lévő item mennyiséget
						end
					else
						slots[dragNDrop[2]][5] = slot[5]; -- A kezünkben lévő item előző slotjába berakjuk a jelenlegi slot itemjét.
						slot[5] = dragNDrop[1]; -- A slotba beleküldjük a kezünkben lévő itemet
					end
				else
					slots[dragNDrop[2]][5] = slot[5]; -- A kezünkben lévő item előző slotjába berakjuk a jelenlegi slot itemjét.
					slot[5] = dragNDrop[1]; -- A slotba beleküldjük a kezünkben lévő itemet
				end
			else -- Ha ez a slot üres
				slot[5] = dragNDrop[1]; -- Ide rakjuk a dragNDrop itemjét
			end
			dragNDrop = {false, false};
		end
	end

	if (dragNDrop[1]) then -- Ha a játékos egy sloton kívűl engedte fel a bal egeret
		slots[dragNDrop[2]][5] = dragNDrop[1]; -- A dragNDrop-ból vissza rakjuk az itemet a helyére
		dragNDrop = {false, false}; -- Töröljük a dragNDrop-ot
	end
	refreshElementData();
end

addEventHandler("onClientClick", root,
	function(button, state)
		if (isInventoryVisible) then
			local cX, cY = getCursorPosition();
			if (button == "left") then
				if (state == "up") then -- Játékos felengedi a bal klikket
					if (dragNDrop[1]) then
						onDropEnd();
					end

					if (windowMove[1]) then
						windowMove = {false, false};
					end
				else
					local isSlotClick = false;
					local clickedSlot = false;
					for i, slot in ipairs(slots) do
						if (isInBox(slot[1], slot[2], slot[3], slot[4])) then
							clickedSlot = i;
							isSlotClick = slot;
							break;
						end
					end
					if not (isSlotClick) then
						windowMove = { cX-invWindow[1], cY-invWindow[2] };
					else -- Ha slotba kattintottunk
						if (isSlotClick[5][1]) then
							dragNDrop = {isSlotClick[5], clickedSlot}; -- Elrakjuk az Item-et arról a slotról és a slot ID-jét.
							slots[clickedSlot][5] = {false};
						end
					end
				end
			elseif (button == "right") then
				if (state == "up") then
					local isSlotClick = false;
					for i, slot in ipairs(slots) do
						if (isInBox(slot[1], slot[2], slot[3], slot[4])) then
							if (slot[5][1]) then
								onItemClick(slot[5], i);
								break;
							end
							isSlotClick = slot;
							break;
						end
					end
				end
			end
		end
	end
);

function refreshElementData()
	local inv = {};
	for i, slot in ipairs(slots) do -- Végpörgetjük a slotokat
		if (slot[5][1]) then
			table.insert(inv, {i, slot[5][1], slot[5][2], slot[5][3]});
		end
	end
	setElementData(localPlayer, "char:items", inv);
end

function deleteLocalItemBySlot(slot)
	local inv = getElementData(localPlayer, "char:items");
	for i, v in ipairs(inv) do
		if (v[1] == slot) then
			table.remove(inv, i);
			break;
		end
	end
	setElementData(localPlayer, "char:items", inv);
end
addCommandHandler('delitem', function(cmd, slot)
	if (not slot) then
		return outputChatBox('#23FF00[Használat] #FFFFFF /delitem [slot]', 35, 255, 0, true);
	end
	deleteLocalItemBySlot(tonumber(slot))
end)

addEventHandler("onClientElementDataChange", localPlayer,
	function(key, oldValue, newValue)
		if (key == "char:items") then
			for i, v in ipairs(slots) do
				slots[i][5] = {false};
			end
			for i, item in ipairs(newValue) do
				slots[item[1]][5] = {item[2], item[3], item[4]};
			end
		end
	end
);

function addItem(cmd, id, amount)
	if (not id or not amount) then
		return outputChatBox('#23FF00[Használat] #FFFFFF /additem [id] [mennyiség]', 35, 255, 0, true);
	end

	id = tonumber(id);
	amount = tonumber(amount)
	if (items[id]) then
		local inv = getElementData(localPlayer, 'char:items');
		for i, item in pairs(inv) do
			if (item[2] == id) then
				inv[i][3] = item[3] + amount;
				outputChatBox(items[id][1].. ' sikeresen hozzáadva az inventoryhoz ('..amount..' darab)')
				setElementData(localPlayer, 'char:items', inv);
				return true
			end
		end
		for i, slot in pairs(slots) do
			if (not slot[5][1]) then
				table.insert(inv, { i, id, amount })
				outputChatBox(items[id][1].. ' sikeresen hozzáadva az inventoryhoz ('..amount..' darab)')
				setElementData(localPlayer, 'char:items', inv);
				return true;
			end
		end
	end
	outputChatBox('#FF0000[HIBA] #FFFFFF Nem sikerült hozzáadni az itemet!', 255, 0, 0)
	return false
end
addCommandHandler('additem', addItem)

addEventHandler("onClientResourceStop", resourceRoot, saveWindowPos);

When I use /additem it says: ERROR: inventory\client.lua:281:bad argument #1 to 'pairs' {table expected, got boolean}

I inserted the client file. 

Link to comment
  • Moderators
2 hours ago, kukimuki said:

I inserted the client file. 

 

Always validate your element-data before you are going to do something with it:

local inv = getElementData(localPlayer, "char:items");

-----------------------------------------------

assert(type(inv) == "table", "inv must be a table") -- hard error

-- or

if type(inv) != "table" then 
	-- outputChatBox("OH NO, I need a table to put my head on...")
	return
end

 

If element data is not set, the variable inv does not contain a table, but false instead.

 

 

Link to comment
  • Moderators
25 minutes ago, kukimuki said:

can you explain me how is it works?

How validation works?

When data comes from an external source, in this case element-data, there is no way of knowing that it is valid. Therefore checking if the data is OK is essential.

For example if the script tries to get the element-data under the key "char:items" before it has an value assigned to it, the script without data validation will most likely end up with an warning or error at a certain point.

 

25 minutes ago, kukimuki said:

and what you written me code is good for me?

Are you suggesting that it is not good for you? Well this is more or less the format in which you receive help in this forum section🤷‍♂️ If I misunderstand you, please let me know.

Link to comment
  • Moderators

 

21 hours ago, kukimuki said:

nono, I just want to know that where I need to write this code? 

Directly after getting the element data:

On 12/07/2023 at 16:49, kukimuki said:
local inv = getElementData(localPlayer, "char:items");
Link to comment
	id = tonumber(id);
	amount = tonumber(amount)
	if (items[id]) then
	local inv = getElementData(localPlayer, 'char:items');
	if type(inv) != "table" then 
		-- outputChatBox("asdasdasdasdasdasdasdasdasdasdasdasd")
	return
	end
		for i, item in pairs(inv) do
			if (item[2] == id) then
				inv[i][3] = item[3] + amount;
				outputChatBox(items[id][1].. ' sikeresen hozzáadva az inventoryhoz ('..amount..' darab)')
				setElementData(localPlayer, 'char:items', inv);
				return true
			end
		end
		for i, slot in pairs(slots) do
			if (not slot[5][1]) then
				table.insert(inv, { i, id, amount })
				outputChatBox(items[id][1].. ' sikeresen hozzáadva az inventoryhoz ('..amount..' darab)')
				setElementData(localPlayer, 'char:items', inv);
				return true;
			end
		end
	end
	outputChatBox('#FF0000[HIBA] #FFFFFF Nem sikerült hozzáadni az itemet!', 255, 0, 0)
	return false
end
addCommandHandler('additem', addItem)

addEventHandler("onClientResourceStop", resourceRoot, saveWindowPos);

i think i did something wrong, can you help me? it says again again the same.

Link to comment
  • Moderators
17 hours ago, kukimuki said:

it says again again the same.

Is the error it still at this line? Or a different line? (note the resource has to be restarted)

for i, item in pairs(inv) do

 

Link to comment

Its says : ERROR: inventory\client.lua:281: 'then' expected near '!'

function addItem(cmd, id, amount)
	if (not id or not amount) then
		return outputChatBox('#23FF00[Használat] #FFFFFF /additem [id] [mennyiség]', 35, 255, 0, true);
	end

	id = tonumber(id);
	amount = tonumber(amount)
	if (items[id]) then
		local inv = getElementData(localPlayer, 'char:items');
		if type(inv) != "table" then 
			-- outputChatBox("asdasdasdasdasdasdasdasdasdasdasdasd")
		return
		for i, item in pairs(inv) do
			if (item[2] == id) then
				inv[i][3] = item[3] + amount;
				outputChatBox(items[id][1].. ' sikeresen hozzáadva az inventoryhoz ('..amount..' darab)')
				setElementData(localPlayer, 'char:items', inv);
				return true
			end
		end
		for i, slot in pairs(slots) do
			if (not slot[5][1]) then
				table.insert(inv, { i, id, amount })
				outputChatBox(items[id][1].. ' sikeresen hozzáadva az inventoryhoz ('..amount..' darab)')
				setElementData(localPlayer, 'char:items', inv);
				return true;
			end
		end
	end
	outputChatBox('#FF0000[HIBA] #FFFFFF Nem sikerült hozzáadni az itemet!', 255, 0, 0)
	return false
end
addCommandHandler('additem', addItem)

 

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...