ID:1436482
 
I've been working on an inventory system that allows me to easily choose between "Bag Slots" or "Bag Weight Capacity". It's something that will probably end up lost in a bunch of folders, but I like to use DM every now and then to keep me programming. I've worked out all the kinks cropped up during testing, but I'd like some feedback before I continue.

Right now it only handles adding items to a bag. There's quite a bit of commenting so I knew where I was at after not working on it for a couple of weeks at a time.

#ifndef CARRY_MODE
#define CARRY_MODE "SLOTS" //Alternative is "WEIGHT"
#endif

item
parent_type = /obj
var
stack = 1 // Current number of items in stack
maxStack // Number an item can be stacked to
weight = 0 // Weight of item

bag
var
name
slots = 0 // Number of slots bag has
weight = 0 // Current weight of bag
maxWeight = 0 // Maximum weight of bag
list
// Contents of bag
contents = list()
// List of bags acceptable item types
acceptable

proc
addItem(item/I, amount=1)
// Deny items that are not an acceptable type (if any)
if(acceptable && !I.type in acceptable) return

if(CARRY_MODE=="WEIGHT")
// Ensure Bag can carry at least one of the items weight
if((weight+I.weight) > maxWeight) return
// If item is stackable and there is a partial stack in the bag
if(I.maxStack && inBag(src,I))
// Get the stack of items in bag
var/item/stack = getStack(src,I)
// Set the number of spaces left in stack
var/num = stack.maxStack - stack.stack
// Set the weight of item(s)
var/wght = amount*I.weight
// Set the weight available in bag
var/wghtLeft = maxWeight - weight

//Ensure bag can handle the weight
if(CARRY_MODE=="WEIGHT")
// Reset amount and total weight if needed
if(wght >= wghtLeft)
amount = round(wghtLeft/wght)
wght = amount*I.weight

// If amount can fit into stack
if(num >= amount)
if(CARRY_MODE=="WEIGHT")
weight += wght
stack.stack += amount
I.stack -= amount
if(I.stack <=0)
I.loc = null

// If amount exceeds available stack spaces
else
stack.stack += num
I.stack -= num
amount -= num
if(CARRY_MODE=="WEIGHT")
weight += num*I.weight
addItem(I, amount)

// If item isn't stackable or in the bag
else
if(CARRY_MODE=="SLOTS" && contents.len >= slots) return
// If adding less that or equal to a full stack
if(!I.maxStack || amount <= I.maxStack)
I.stack = amount
src.contents.Add(I)
if(CARRY_MODE=="WEIGHT")
weight += I.weight*amount
// If amount exceeds items max stack
else
// Create and add a new item at max stack
var/item/N = new I.type
N.stack = N.maxStack
amount -= N.stack
src.contents.Add(N)
if(CARRY_MODE=="WEIGHT")
weight += N.weight*N.stack
// Then add the remainder
addItem(I, amount)

proc
// Check if item is in bag and has stackable spaces
inBag(bag/B,item/I)
for(var/item/i in B.contents)
if(i.type == I.type && i.stack < i.maxStack)
return 1
return 0

// Get an item in the bag for stacking
getStack(bag/B,item/I)
for(var/item/i in B.contents)
if(i.type==I.type && i.stack<i.maxStack)
return i
Stacking is fun!

From my quick glance I don't see anything really wrong with this code. It does seem a little weird that the bags themselves are limited by weight. I would probably just have a maximum carry weight for the player, and then only use slots to limit the capacity of individual bags. Because for example, you might have a small dense object that is really heavy but fits into a bag, or a big object that is not very heavy but wouldn't fit even if the bag is empty.
In addItem(),
if(acceptable && !I.type in acceptable) return

// should be
if(acceptable && !(I.type in acceptable)) return

It's funny you have this one big issue with order of operations, and yet, a few lines down, you put unnecessary parentheses around one side of a comparison operation.

You're also using src.contents.Add(I) instead of contents += I. The later has been proven to be better for adding one item to a list. It's not a big deal, though.
You see, I've been toying around with this and changed it so many times over the past few weeks that I figured I could benefit from a fresh set of eyes. I'll make the changes you pointed out, thanks for that Kaiochao.

I thought about giving the player a carry weight limit instead of the bags, but decided against it and decided upgrading bags to allow for more slots/carry weight would suit me better. I may end up having larger items take up more slots, but for now I'll just stick with one slot per item.