ID:267118
 
I have bookshelfs that use verbs to save books in them.
My code is bellow for one book shelf.
obj/shelf1
icon='Doodads.dmi'
icon_state="shelf1"
density=1
var/list/L = new(200)
verb/Put_In()
set src in oview(1)
var/mob/pc/M = usr
if(M.contents==null)
return
var/book = input("Select the book you wish to add to the shelf.","Select Book",) in M
var/savefile/F
F = new("shelf.sav")
F["Books"] >> L
book:Move(L)
F["Books"] << L
verb/Take_Out()
set src in oview(1)
var/mob/pc/M = usr
var/savefile/F
F = new("shelf.sav")
F["Books"] >> L
if(L!=null)
var/book = input("Select the book you want from the shelf.","Select Book",) in L
book:Move(M)
F["Books"] << L

The diffrence from the other shelfs is diffrent type names and diffrent .sav filenames.
But when I have a scroll or other book item and I try and add it to the shelf using put_in() verb it doesnt goto it.

Could any one please tell me why? and how I could fix this?</<>
Green Lime wrote:
var/mob/pc/M = usr

Why are you bothering to type-cast usr? You're not using any vars inherent to /mob/pc instead of /mob; all you're doing is using contents and Move(), both of which work fine for usr.

if(M.contents==null)
return

The contents list is never null. However, it may be empty. The correct if() would be if(!usr.contents.len).

var/book = input("Select the book you wish to add to the shelf.","Select Book",) in M

You can save yourself some hassle by culling out non-books first. Build a list of books in place of the above if(), and then use that list instead of "in M".
var/list/books=new
var/obj/book/B
for(B in M) books+=B
B=input("Select the book you wish to add to the shelf.","Select Book",) as null|obj in books
if(!B) return
Now you have a more reliable list, and a cancel option. Take out the if() statement above, since it won't be needed here. input() will automatically return null if the list is empty.

book:Move(L)

This is wrong on a whole lot of levels.
First, you made book a regular var, not a specific obj type. Since you did that, DM doesn't know it's supposed to be an obj and that it therefore has the Move() proc, so you obviously put in the : operator (which is sloppy coding) instead of fixing the real problem. This is why above I declared var/obj/book/B, where B is of the correct type.

The second problem you have is that a list isn't a location; you can't Move() anything to it. book.Move(L) is the same as saying book.loc=L, if of course the Enter() checks and such work out. Well, L is a list, not an atom. It's not a physical location that can hold things; it's a concept that can list things.
To add the book (which I'll call B to match my code) to the list, you'd have to do this:
L+=B
Of course, you also have to change that new(200) list initialization above to just a regular new, because you don't want the list to have 200 nulls in it now. Adding a book to that would make it the 201st item, which isn't what you want. And I'm sure you don't want to search the list to find the first null slot to put the book into; that would be a pain. So change var/list/L=new(200) to just var/list/L=new, and then put in this code to add a book to the list:
if(!L) L=new     // if there's no list in the save file for this shelf
if(L.len>=200)
usr << "This bookshelf is full."
return
L+=B
Now onto the rest:
verb/Take_Out()
set src in oview(1)
var/mob/pc/M = usr
var/savefile/F
F = new("shelf.sav")
F["Books"] >> L
if(L!=null)
var/book = input("Select the book you want from the shelf.","Select Book",) in L
book:Move(M)
F["Books"] << L

Taking the book out will actually work here, because once the list is loaded, all the objs in it will be loaded too. They're now objects, whose location is null, which can be moved to the usr. Again I'd suggest actually using var/obj/book/B for this instead.

However, taking out a book will move it into the player's inventory but it won't remove it from the shelf. The reason is that because the list is not a valid loc to begin with, Move() won't remove it from the list on its own. If the book was in something's contents, that is if its loc was the shelf, then it would be removed from shelf.contents on its own when loc changed--because atom.contents is not a regular list, and looks after itself.
So, you have to manually remove the book from the list:
if(!B) return    // no book selected
if(B.Move(usr)) // this will be non-zero if the move works
L-=B

Lummox JR
In response to Lummox JR
WOW I did alot of things wrong on that code. Thanks Lummox JR. Guess im kinda new to dealing with list.