====================================
====	Modder's resource: Inventory System	====
====================================
--		Version: 0.7b							--
--		By: N0X!C								--
------------------------------------------------------------------------------------------

Table of Contents:

I: Introduction
II: Basic How-To:
	IIa: Changing Settings
	IIb: Making New Items
	IIc: In the Map-editor

III: Advanced How-To:
	IIIa: Global Variables
	IIIb: Built-in Commands

IV: Known Bugs and Glitches
V: Questions and Answers
VI: Changelog
	VIa: 0.7b
VII: Credits

------------------------------------------------------------------------------------------
--	I: Introduction								--
------------------------------------------------------------------------------------------

This is a script module I've made for an inventory system I would use in a private mod I've worked on.
I'm not entirely happy with it at the same time as I figured people could use it in their own mods, so 
I decided to upload it as a (more or less) open-source modder's resource to get help developing it 
and help others develop their own mods. Basicly it allows players to pick, carry and drop items, use 
them, and combine them to gain new items. 

The items are made with variables, and each item carry their own functions that are written by the 
modder. To use an item, you say various commands that start with "!inv_". The existing commands are:
!inv_pickup	...	Picks up an item
!inv_drop		...	Drops an item
!inv_next		...	Selects the next item in the item list
!inv_prev		...	Selects the previous item in the item list
!inv_list		...	Gives a list of every currently held item and their total weight
!inv_desc		...	Gives a short description of the selected item
!inv_longdesc	...	Gives a long description of the selected item, or a short one if a long one doesn't exist
!inv_use		...	Uses the selected item
!inv_combine	...	First time: Selects an item to combine with something.
				Second time: Combines the item from the first time with the currently selected item.
!inv_hud		...	Toggles HUD on or off


------------------------------------------------------------------------------------------
--	II: Basic How-to							--
------------------------------------------------------------------------------------------

This section of the readme will contain information on how to change basic settings, how to make basic 
items, and how to place items in the map editor.

IIa: Changing Settings
------------------------------------------------------------------------------------------

A few settings exist in the inventory system for administrators that host servers with a mod using this 
system. They are stored as variables in "sys/lua/inv/globals.lua", and will be explained here.

Everything after the equal signs ("=") are options that can be added, and each options is separated 
by two pipes ("||"). Options that can be a number are represented by a number sign ("#"), unless they 
are a range of numbers. If they are between parenthesis ("()"), it means none of them may be used together, 
and if they are between brackets ("{}") it means they are multiple settings inside a table, in which case 
each variable inside that table is separated by a comma (","). An explanation for the setting can be found 
after two hyphens ("--") to the right of the variable.

They are all the top 3 variables in globals.lua, and the settings are the following:

inv_maxtype	= ("amount" || "weight")									-- Decides how to limit the amount of items a player can carry. (amount of items in item list, or total weight of items)
inv_max		= #													-- Depending on the previous setting, decides what the limit for the amount of items that can be carried, or the total weight that is allowed.
inv_loseitems	= { death = ("drop" || "delete"), endround = ("drop" || "delete") }	-- If the "death" variable exists, then its value decides what happens to the items a player has when he dies. Same thing goes for endround, where it decides what happens at the end of a round. "Drop" drops all items on the ground, "Delete" removes the items entirely.

IIb: Making New Items
------------------------------------------------------------------------------------------

To make new items you need some basic scripting knowledge. If you've made a script at all before, and it 
worked, then probably won't be a problem. To begin with, each item is built from a table of variables. 
Examples can be found in "inv/items.lua". Here is a template:

inv_items["Item Name"] = {}
inv_items["Item Name"]["use"] = name_of_item_function				-- The function for the item. Remember, THIS IS NOT A STRING. It's a link to the actual function.
inv_items["Item Name"]["name"] = "Item Name"					-- The name of the item.
inv_items["Item Name"]["desc"] = "Short description for the item."		-- A short description for the item.
inv_items["Item Name"]["longdesc"] = "Long description for the item."	-- Optional. A long description for the item. If it's really long, remember to put in newlines (rtfm to find out how).
inv_items["Item Name"]["amount"] = 1							-- I recommend not to change this, because I'm too lazy to find out if things get bugged when you do.
inv_items["Item Name"]["stacksize"] = 5							-- How many items of this type that can be in a stack.
inv_items["Item Name"]["weight"] = 1							-- The weight of the item.
inv_items["Item Name"]["icon"] = "gfx/weapons/molotovcocktail.bmp"	-- The image for the item when it's on the ground.
inv_items["Item Name"]["spec"] = nil							-- Optional. A special variable for the item. If you create unique items, or the items have some special properties, this variable can be used to identify things.

Once you've made an item with this template, you need to make an item function. Examples can be found in 
"inv/itemfuncs.lua". Remember that the variable 'inv_items["Item Name"]["use"]' has to link to this function.
As you might have noticed, item functions only get one variable passed to them, which is the ID of the player
that used them. This is why I've added the "spec" variable. You can put any amount of additional, custom 
item variables in it if you need those variables to do something special. Only use it if you have to, though, 
because items with different "spec" values can't be stacked.

You'll need to remember two things when making new item functions though.
1. Usually you'll want to show a message to the player when he/she uses an item, like "You bandage yourself, making the bleeding stop.".
2. If the item is removed after being used, you have to remove it using a function that will be shown in the list of commands, further down this readme.

IIc: In the Map-editor
------------------------------------------------------------------------------------------

Putting items on maps is simple; You can either do it through a map script (using commands that will be listed
later), or you can just place an item entity in the map editor, and give it the name of the item you want to spawn 
there.
At the start of each round, every item on the map will be checked, and if their name matches any of the item 
names, the item entity is removed and a "lua" item is spawned in its stead.


------------------------------------------------------------------------------------------
--	III: Advanced How-to							--
------------------------------------------------------------------------------------------

This section will deal with the more advanced aspects of this script, such as global variables that normally aren't 
changed, and built-in commands that are related to the inventory system.

IIIa: Global Variables
------------------------------------------------------------------------------------------

There are more variables inside globals.lua, other than the settings ones. They are the following:

inv			-- The table that contains each player's variables, such as their inventory and currently selected item.
inv_items		-- The table that contains the stats for each item.
inv_dropped	-- The table that contains every dropped item, their image ID and their coordinates (in tiles).
inv_hud		-- The table that contains the HUD ID to use for HUD, and the coordinates for the HUD.

It may be necessary to use some of these variables at times, so I will explain how they work.

inv:
It's best if I give the default values for this table and explain them.

inv[id] = {}			-- The player's table.
inv_hud[id] = true		-- Whether the player wants to use HUD to show its current item, or the chat. (default: HUD)
inv[id]["cur"] = 1		-- The currently selected item in the item list (inv[id]["items"]).
inv[id]["combine"] = {}	-- The table of items to combine.
inv[id]["combine"][1] = 0	-- The first selected item to combine. When it is 0, no item has been selected. Otherwise, it is that item's item table.
inv[id]["combine"][2] = 0	-- The item to combine the first selected item with. It will first try to combine 1 with 2. If that fails, it tries to combine 2 with 1.
inv[id]["weight"] = 0		-- The total weight of every item. It's more convenient to keep this here than to calculate the total weight of an inventory each time it needs to be checked.
inv[id]["items"] = {}	-- The inventory. Each index (inv[id]["items"][#]) is an item, and the first index (1) is a special item called "None", which doesn't actually exist and does nothing.

inv_items:
This variable is never changed EVER, because it contains the default stats for every newly spawned item. So unless 
you want items that are spawned after a certain point to be different from what they were earlier, you shouldn't touch this.

inv_dropped:
This table has a similiar structure to inv_items and inv[id]["items"]. It contains item tables, and item IDs. When an item is 
picked up or removed from the map, every ID shifts to fill its spot, so use a special variable for each item if you want to 
keep track of it, and then use the command 'finddropped' to find its ID.

inv_hud:
This is a simple table. It contains 3 variables: id, x and y.
id is the HUD ID to use for the HUD inventory "interface". x and y are the coordinates to put them at.

IIIb: Built-in Commands
------------------------------------------------------------------------------------------

There are some built-in commands for handling the inventory structure, and some of them are necessary to know to
create new items properly. They are the following:

giveitem(id, item, spec)					-- Adds an item to a player's inventory.
									-- id = the player's ID
									-- item = the name of the item to add
									-- spec = the special variable to add (Default: nil)
									-- Returns the inventory ID of the item

spawnitem(item, x, y, rot)				-- Spawns an item on the map.
									-- item = the name of the item to add
									-- x = the X coordinate to spawn the item at (in tiles).
									-- y = the Y coordinate to spawn the item at (in tiles).
									-- rot = the rotation of the item (Default: -179 ~ 180).
									-- Returns the dropped ID of the item

pick(id, itemid)							-- Makes the player pick an item (even if they are nowhere close to each the item)
									-- id = the player's ID
									-- itemid = the ID of the item to pick OR a table identical to the item to pick
									-- Returns the inventory ID of the item

removeitem(id, itemtable, amount)			-- Removes an amount of items from a player's inventory. 
									-- id = the player's ID
									-- itemtable = a table identical to the one to remove OR the item name
									-- amount = the amount of items to remove (Default: 1).
									-- Returns true if the item stack was removed, otherwise the size of the stack.
									
removedropped(itemid, amount)			-- Removes an item that is lying on the ground. 
									-- itemid = The ID of the item to remove OR a table identical to the item to remove
									-- amount = the amount of items to remove (Default: 1).
									-- Returns true if the item stack was removed, otherwise the size of the stack.

finditem(id, itemtable)					-- Finds an item in a player's inventory.
									-- id = the player's ID
									-- itemtable = a table identical to the one to find OR the item name
									-- Returns the inventory ID of the first matching item found.

finddropped(itemtable)					-- Find an item on the map.
									-- itemtable = a table identical to the one to find
									-- Returns the dropped ID of the first matching item found.

loop_table(table)						-- Recursively loop through and copy a table. 
									-- table = the table to loop through.
									-- Returns a copy of the table that was looped.

convert_items(mode)					-- Convert the item entities on a map into Lua items.
									-- mode = start/end mode id, whatever that is. (Not needed)
									-- Returns a table with the dropped IDs of the items that were created

check_weight(id, itemtable)				-- Check if a player can carry an item. (Note: Works even if inv_maxtype is "amount".)
									-- itemtable = the item table to see if the character can carry.
									-- id = the player's ID
									-- Returns false if the player couldn't pick up the item. Otherwise, returns the amount of items the character could pick up.

update_hud(id)						-- Update the HUD for a player. If the player isn't using HUD, then it sends them a chat message saying what item they have selected.
									-- id = the player's ID


------------------------------------------------------------------------------------------
--	IV: Known Bugs and Glitches					--
------------------------------------------------------------------------------------------

The "First Glitch":
The first item that is spawned in a round doesn't have its picture shown. This might be a 
conflict with another mod I have that simulates film grain by randomly changing the rotation 
of a picture each frame. Either way, it definitely doesn't work the way it should. 

The "Coffee Glitch":
While testing this mod, sometimes this would happen:
I would mix coffee powder with water, thereby making coffee. When I dropped the new coffee, 
I would be able to pick it up several times. Note that it didn't drop several coffees, since then 
they would stack and I would pick them all up at the same time. Instead, they simply didn't 
disappear when I picked them up. No clue why this might happen, but I seem to have gotten 
rid of it. 


------------------------------------------------------------------------------------------
--	V: Questions and Answers					--
------------------------------------------------------------------------------------------

Q: Your items look weird!
A: They're only for examples. I used graphics from the original game, but the 'image' and 
imageblend' functions don't seem to use the same colors to make items transparent as 
the actual game engine does. 

Q: What is the difference between a dropped ID and an inventory ID?
A: A dropped ID is the ID of an item stack that is lying on the ground, while an inventory ID 
is the ID of an item stack in someone's inventory. More specifically, the inventory ID of an item 
is the item slot it is taking up. 

Q: When I added this to my mod, my chat/chat commands started acting up. What do I do?
A: Open core.lua. Find the chat command part, and put everything inside it in your own 
chat command script. If it complains after this, it's probably because of the load order of 
your mods. Loading your chat commands last should fix it. 

Q: I found a bug/glitch! What do I do?
A: Fix it if you can, and then post about it on the forum thread for this mod. If you can't fix it, 
post how you found it and how to recreate it. 

Q: Wow, your coding sucks.
A: So fix it if you can, re-upload your fixed version, and post about it on the forum thread for 
this mod. I'm not a good coder, I admit, and that is partly why I'm making this open-source 
style. 

Q: If I want to update this mod, how do I go about it?
A: Don't include any other items than the example ones. Upload the changed files with a 
fitting title (i.e "Modder's Resource: Inventory System patch v0.8b"), and post about it on 
the forum thread for this mod. And (this is important) remember to update the readme. 
When it seems fit, anyone may put each approved patch together into a full version.

Q: What should I do if I want to use this module in my mod?
A: Apart from actually using the scripts, simply say somewhere that your mod is using 
Inventory System <version>.

------------------------------------------------------------------------------------------
--	VI: Changelog								--
------------------------------------------------------------------------------------------

Remember to update this if you've made any additions to the mod!!!

VIa: v0.7b
------------------------------------------------------------------------------------------
--	Released. Everything (except graphics) by N0X!C.


------------------------------------------------------------------------------------------
--	VII: Credits								--
------------------------------------------------------------------------------------------

--------- Developers ---------
N0X!C - Entirely made v0.7b, the first publicly released version of this mod.

--------- Testers ---------
None

--------- Thanks ---------
Evildeeds
Archien
Verian
Pandan
Dereliction
Searif