diff options
| author | Alexander Pickering <alexandermpickering@gmail.com> | 2017-11-26 21:07:54 -0500 |
|---|---|---|
| committer | Alexander Pickering <alexandermpickering@gmail.com> | 2017-11-26 21:07:54 -0500 |
| commit | 83af51534bf16bf048aea1cd3b74a0308ed9dd71 (patch) | |
| tree | ff82f3e6dd841633b1355b73181bcae607ee1138 /tutorials/tut030_inventories.md | |
| parent | 25e4d04a331a6a0b9d897d4f721757730771ff97 (diff) | |
| download | artery-83af51534bf16bf048aea1cd3b74a0308ed9dd71.tar.gz artery-83af51534bf16bf048aea1cd3b74a0308ed9dd71.tar.bz2 artery-83af51534bf16bf048aea1cd3b74a0308ed9dd71.zip | |
Started work on writing tutorials
Wrote tutorials for
* Setup
* Addon structure
* Inventories
* Items
Diffstat (limited to 'tutorials/tut030_inventories.md')
| -rw-r--r-- | tutorials/tut030_inventories.md | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/tutorials/tut030_inventories.md b/tutorials/tut030_inventories.md new file mode 100644 index 0000000..fbf654d --- /dev/null +++ b/tutorials/tut030_inventories.md @@ -0,0 +1,144 @@ +# Tut 0x030 + +## Inventories + +Many gamemode bases try to build an inventory system into the gamemode, leaving the developer with few ways to actually use the system more than "put item in, take item out". Artery somewhat forces you to build your own inventories to use. + +In this tutorial, we'll build a simple rougelike inventory, where we expect items to have a "weight", and we can carry as many items as we want, as long as we don't exceed our "max weight". + +Inventories and items in Artery are just tables, as per usual in lua. They have a few required fields each. On the left, under "Classes", open invtbl and itemtbl in new tabs. + +## A simple inventory + +You can see all the fields needed for an inventory, so let's get started. Recall that + + function tbl:func_name(one) + ... + end + +is the same as + + function tbl.func_name(self,one) + ... + end + +lua will automatically create the variable "self" in the first example + +garrysmod/addons/artery_rougelite/data/artery/global/rougeinv.lua + + local inventory_registry = nrequire("inventory.lua") + local item_registry = nrequire("item.lua") + local inv = {} + + inv.items = {} --A table of all the items we have + inv.maxweight = 100 --The maximum weight of all our items + inv.weight = 0 --The current weight of all our items. + --Technically we could calculate the weight based on the "items" table, + -- but that might start taking a long time if we have a lot of low-weight items. + + --Returns a position for an item, or nil if we don't have room + function inv:FindPlaceFor(item) + --Make sure we won't be over weight when we add the item + if self.weight + item.weight > self.maxweight then + return nil + end + --[[ + ALWAYS return a table position, even if you only need a number. + This is the same as + return { + [1] = #self.items + 1 + } + ]] + return {#self.items + 1} + end + + function inv:CanFitIn(position,item) + --Check that we won't be over weight + if self.weight + item.weight > self.maxweight then + return false + end + + --And make sure we don't already have an item in that position + if self.items[position[1]] ~= nil then + return false + end + + --If we won't go over weight, and the position isn't already used, we can fit it! + return true + end + + --Put something into our inventory + function inv:Put(position,item) + self.items[position[1]] = item + self.weight = self.weight + item.weight + end + + --This one is a bit complicated + --ptr can be either a string, or a function that takes 1 argument, + -- and returns true when given an object we should return. + --this function returns a POSITION that can be given back to get, remove, ect. + -- the object. + function inv:Has(ptr) + --Look for an item with the given name + if type(ptr) == "string" then + for k,v in pairs(self.items) do + if v.Name == ptr then + return {k} + end + end + elseif type(ptr) == "function" then + for k,v in pairs(self.items) do + if ptr(v) then + return {k} + end + end + end + return nil + end + + --Removes an item from our inventory, returns the item we removed + function inv:Remove(position) + local item = self.items[position[1]] + self.weight = self.weight - item.weight + self.items[position[1]] = nil + return item + end + + --Gets the item in a given position + function inv:Get(position) + return self.items[position[1]] + end + + --Creates a string that this inventory can be re-created with + function inv:Serialize() + local ser = {} + for k,v in pairs(self.items) do + ser[k] = { + v.Name, + v:Serialize() + } + end + return util.TableToJSON(ser) + end + + --Re-creates this inventory from the data created by Serialize() + function inv:DeSerialize(data) + local self_copy = table.Copy(self) + local json = util.JSONToTable(data) + for k,v in pairs(json) do + local item_name = v[1] + local item_data = v[2] + local item = item_registry.GetItemFromData(item_name,item_data) + self_copy.items[k] = item + end + for k,v in pair(self_copy.items) do + self_copy.weight = self_copy.weight + v.weight + end + return self_copy + end + + --Don't forget to register it with the gamemode! + inventory_registry.RegisterInventory(inv) + + +That was a bit long, but we're done! This is the absolute minimum needed to create an Artery inventory. Now you can go in-game and use the console command `artery_printinventories`, and in that list, you will see your newly made inventory! |
