ID:1802525
 
(See the best response by Ter13.)
Code:

mob
verb
UpdateBag()
var/items = 0
for(var/atom/O in src.contents) items++
winset(src,"Bag.Items", "cells=1x[items]")
items = 0

if(contents.len)
var/countList_[0]

for( var/atom/x in contents )
if( countList_[x.type] )
countList_[x.type][1] ++
else
countList_[x.type] = list( 1, x )

for( var/x in countList_)
//im stuck here


Problem description:
Hello. I would like to know how to make group atom together when i pick them up and view in the Bag. The bag is based on grid.
mob
verb
UpdateBag()
var/x = 1
src << output ("Bag.Items","InvGrid:1,[x]")
for(var/obj/i in contents)
src << output(i,"Items:1,[++x]")
src << output(i.Amount,"Items:2,[++x]")


You will have to make Amount var for objects, too.
Also edit the drop/wear/buy verbs for amount
Synpax wrote:
Code:

> mob
> verb
> UpdateBag()
> var/items = 0
> for(var/atom/O in src.contents) items++
> winset(src,"Bag.Items", "cells=1x[items]")
> items = 0
>
> if(contents.len)
> var/countList_[0]
>
> for( var/atom/x in contents )
> if( countList_[x.type] )
> countList_[x.type][1] ++
> else
> countList_[x.type] = list( 1, x )
>
> for( var/x in countList_)
> src<<output(x,"Bag.Items:1,[items]")
src<<output(x.suffix,"Bag.Items:2,[items]")
>

I laid out a simple stacking system in id:39699. You can probably come up with ways to improve it, but it shows you the gist.
In response to Lummox JR
150 lines of code, a few pages of explanation. Does that qualify as simple? I mean no offense, I'm sure it's functional but that seems like a really long winded approach to teach someone how to stack items which is really not a very complicated thing to do.
In response to Zecronious
Zecronious wrote:
150 lines of code, a few pages of explanation. Does that qualify as simple? I mean no offense, I'm sure it's functional but that seems like a really long winded approach to teach someone how to stack items which is really not a very complicated thing to do.

Well it's a tutorial. Lots of explanation is kind of the point.

But beyond that, while the concept of stacking systems is simple enough, getting a stacking system right takes effort. The core idea, sure, that's easy--but the actual implementation is trickier. It's the kind of thing that's easy to mess up if you don't go into it with a plan. Any schmo can figure out that they'll want a quantity var and some way of manipulating it. The devil is in the details.
GatewayRa wrote:
There's not much on there. He shouldn't have any trouble reading it in a few minutes.

Well, ask him. He's here.
Best response
@Lummox: I'm not gonna quite jump in on the Zecronious inquisition here, but I would like to offer my own variant of your approach. I'm not fond of that variable loop you've got on there.

atom
proc
//call this to put an object in an acceptable state for garbage collection
//break all circular references here if you add them later in the hierarchy, and make sure this object isn't pointed to by something else. (You should always predict this.)
Cleanup()
src.loc = null

atom/movable
proc
//called when a move was successful.
//use to add post-move events
Moved(atom/OldLoc,ODir=0,Osx=0,Osy=0)

//call Moved() on successful Move()
Move(atom/NewLoc,Dir=0,step_x=0,step_y=0)
var/atom/OldLoc = loc
var/ODir = dir
var/Osx = src.step_x
var/Osy = src.step_y
. = ..()
if(.)
src.Moved(OldLoc,ODir,Osx,Osy)
obj
item
var
//a per-item-type unique identifier
id = 0
proc
//override this deeper in the hierarchy when new member variables are added that must be maintained the same between instances.
//returns a new item with the same specified variables as this one.
Clone()
var/obj/item/i = new src.type()
i.id = id
return i

//override this deeper in the hierarchy when new member variables are added that must be maintained the same between instances.
//returns 1 if the objects have the same specified variables.
//returns 0 if any of the specified variables is not the same.
Compare(obj/item/i)
return id == i.id

stackable
var
stack = 1 //the number of items currently stacked
max_stack = 20 //the maximum of these items that can be stacked a value of 0 is infinite
proc
//call this proc to stack this object with another stack
Stack(obj/item/i)
var/change
if(max_stack)
change = min(stack,i.max_stack-i.stack)
else
change = stack
stack -= change
i.stack += change
if(stack==0)
Cleanup()

//call to duplicate a stack of this item and then set its stack to the specified stack size
Split(size)
if(max_stack)
size = min(max(stack),max_stack)
if(size)
var/obj/item/stackable/s = Clone()
s.stack = size
stack -= size
if(stack==0)
Cleanup()
return s
return null

//when the item moves into a new location, search for similar items and stack them up
Moved(atom/OldLoc,ODir=0,Osx=0,Osy=0)
if(istype(loc,/atom))
for(var/obj/item/stackable/i in loc)
if(i!=src&&Compare(i))
Stack(i)
if(!loc)
return


Admittedly, Lummox, your approach is set-and-forget. Unfortunately, I don't overly care for the idea of nested loops and the use of the in operator to determine variable inclusion in a clone or a compare operation. I'd prefer a manually-programmed unrolled loop which is put together using polymorphic function member overrides combined with intelligent use of supercall.

I prefer to write code short, sweet, simple, and fast, rather than safe. My philosophy is that the developer can put garbage in and he should expect to get garbage out. I don't like safety checking things, and I don't like assuming the developer is an idiot. However, an end-user should never be considered to be anything more than a cat walking across the keyboard, so safety checks should definitely be there.

This would be the simplest way I'd want to implement such a thing. Honestly, I'd prefer to link it into my InstanceDB approach I showed off in Snippet Sunday #3 over at: id:1626900, but since I haven't gotten around to importing the item databases from SQLlite or JSON yet, I'm not exactly going to be tacking on to that approach for some time owing to the way the list() function boils down to a proc.
In response to Ter13
Woah woah. Who said inquisition? Don't need to get personal Ter.
Indeed I'm not fond of the var approach either; the tutorial was deliberately made as generic as possible, but that's not the best system for all cases.

IMO in most cases where you'd use a stacking system, you probably know exactly which vars matter as far as telling whether two objects are alike for stacking purposes.
Indeed I'm not fond of the var approach either; the tutorial was deliberately made as generic as possible, but that's not the best system for all cases.

Yeah, generic is good for this crowd in most cases. Unfortunately with libraries, you can't often depend on people using good habits, such as not overriding Move() in insane ways (improper return values, failing deliberately on movements into movables, etc.), or keeping track of loose references and tmp marking variables.

I often find myself torn on most of the code I share here. Whether it's worth sharing, because I expect too much understanding from the user to the point that most won't be able to use it to its fullest, or on the other hand, whether that's arrogant and presumptuous of me and/or if I should expend the extra effort to explain and teach numerous use-cases of the system to explain how to go about expanding upon it.

It's definitely a pickle when it comes to how best to approach our particular niche, and I definitely want to point out that your approach is entirely sensible if not the simplest/fastest for that reason.

Woah woah. Who said inquisition? Don't need to get personal Ter.

So... Criticizing your words in an off-hand and entirely sarcastic manner is an affront to your person now? TIL. To be frank, though, it's kind of absurd to pop in and say a snippet is too long without chopping code out and showing why it's too long. Not to mention arguing on behalf of someone else that a tutorial is too long for them to read. It's awful patronizing to decide that for someone else, don't you think? Just some friendly food for thought. This is supposed to be a help forum, after all.
In response to Ter13
Ter13, I made a well mannered comment. You exaggerated mine, pretending I was trying to do something other than help.

Sarcasm is a good excuse for acting rude. You're the mod, I'm not supposed to be the one telling you that you were rude with that comment and you're being even more rude now.
In response to Zecronious
Zecronious wrote:
You're the mod, I'm not supposed to be the one telling you that you were rude with that comment and you're being even more rude now.

Actually, neither he nor I are moderators anymore.
In response to Lige
I was unaware. Still, it stands. I meant no offence and made that clear. Ter13 seems intent on trying to offend me and is making no effort to cover it up. Dude's just being out right rude.
Alright, we're moving this over to pager. It's neither the time nor the place for this.
Hopefully we will be able to stack byond pages