/* Library Machines * * Contains: * Borrowbook datum * Library Public Computer * Library Computer * Library Scanner * Book Binder */ /* * Borrowbook datum */ /datum/borrowbook // Datum used to keep track of who has borrowed what when and for how long. var/bookname var/mobname var/getdate var/duedate /* * Library Public Computer */ /obj/machinery/librarypubliccomp name = "public library computer" desc = "A computer." icon = 'icons/obj/library.dmi' icon_state = "computer" anchored = TRUE density = TRUE var/screenstate = 0 var/title var/category = "Any" var/author var/SQLquery /obj/machinery/librarypubliccomp/attack_hand(var/mob/user) usr.set_machine(src) var/dat = "Library Visitor\n" // switch(screenstate) if(0) dat += {"

Search Settings


Filter by Title: [title]
Filter by Category: [category]
Filter by Author: [author]
\[Start Search\]
"} if(1) if(!establish_db_connection(dbcon)) dat += "ERROR: Unable to contact External Archive. Please contact your system administrator for assistance.
" else if(!SQLquery) dat += "ERROR: Malformed search request. Please contact your system administrator for assistance.
" else dat += {""} var/DBQuery/query = dbcon.NewQuery(SQLquery) query.Execute() while(query.NextRow()) var/author = query.item[1] var/title = query.item[2] var/category = query.item[3] var/id = query.item[4] dat += "" dat += "
AUTHORTITLECATEGORYSS13BN
[author][title][category][id]

" dat += "\[Go Back\]
" user << browse(dat, "window=publiclibrary") onclose(user, "publiclibrary") /obj/machinery/librarypubliccomp/Topic(href, href_list) if(..()) usr << browse(null, "window=publiclibrary") onclose(usr, "publiclibrary") return if(href_list["settitle"]) var/newtitle = input("Enter a title to search for:") as text|null if(newtitle) title = sanitize(newtitle) else title = null title = sanitizeSQL(title) if(href_list["setcategory"]) var/newcategory = input("Choose a category to search for:") in list("Any", "Fiction", "Non-Fiction", "Reference", "Religion") if(newcategory) category = sanitize(newcategory) else category = "Any" category = sanitizeSQL(category) if(href_list["setauthor"]) var/newauthor = input("Enter an author to search for:") as text|null if(newauthor) author = sanitize(newauthor) else author = null author = sanitizeSQL(author) if(href_list["search"]) SQLquery = "SELECT author, title, category, id FROM ss13_library WHERE " if(category == "Any") SQLquery += "author LIKE '%[author]%' AND title LIKE '%[title]%'" else SQLquery += "author LIKE '%[author]%' AND title LIKE '%[title]%' AND category='[category]'" screenstate = 1 if(href_list["back"]) screenstate = 0 src.add_fingerprint(usr) src.updateUsrDialog() return /* * Library Computer */ /obj/machinery/librarycomp name = "library computer" desc = "A computer." icon = 'icons/obj/library.dmi' icon_state = "computer" anchored = TRUE density = TRUE var/arcanecheckout = FALSE var/screenstate = 0 // 0: Main Menu - 1: Inventory - 2: Checked Out - 3: Check Out var/sortby = "author" var/buffer_book var/buffer_mob var/upload_category = "Fiction" var/list/checkouts = list() var/list/inventory = list() var/checkoutperiod = 5 // In minutes var/bibledelay = 0 var/is_public = FALSE var/obj/machinery/libraryscanner/scanner // Book scanner that will be used when uploading books to the Archive /obj/machinery/librarycomp/attack_hand(var/mob/user) user.set_machine(src) var/dat // Public Related Code if(!is_public) dat = "[current_map.station_name] Library Management\n" else dat = "[current_map.station_name] Library\n" switch(screenstate) if(0) // Main Menu dat += "View Stock
" dat += "View Checked Out Books
" dat += "Check out a Book
" dat += "Order From Library Database
" if(!is_public) dat += "Upload New Title to Library Database
" dat += "Print a Bible
" if(emagged) dat += "7. Access the Forbidden Lore Vault
" if(arcanecheckout) new /obj/item/book/tome(get_turf(src)) to_chat(user, "Your sanity barely endures the seconds spent in the vault's browsing window. The only thing to remind you of this when you stop browsing is a dusty old tome sitting on the desk. You don't really remember printing it.") user.visible_message("\The [user] stares at the blank screen for a few moments, [user.get_pronoun("his")] expression frozen in fear. When [user.get_pronoun("he")] finally awakens from it, [user.get_pronoun("he")] looks a lot older.", range = 2) arcanecheckout = FALSE if(1) // Inventory dat += "

Inventory


" for(var/obj/item/book/b in inventory) dat += "[b.name] (Delete)
" dat += "(<-- Return to Main Menu)
" if(2) // Checked Out dat += "

Checked Out Books


" for(var/datum/borrowbook/b in checkouts) var/timetaken = world.time - b.getdate //timetaken *= 10 timetaken /= 600 timetaken = round(timetaken) var/timedue = b.duedate - world.time //timedue *= 10 timedue /= 600 if(timedue <= 0) timedue = "(OVERDUE) [timedue]" else timedue = round(timedue) dat += {"\"[b.bookname]\", Checked out to: [b.mobname]
--- Taken: [timetaken] minutes ago, Due: in [timedue] minutes
(Check In)

"} dat += "(<-- Return to Main Menu)
" if(3) // Check Out a Book dat += {"

Check Out a Book


Book: [src.buffer_book] \[Edit\]
Recipient: [src.buffer_mob] \[Edit\]
Checkout Date: [world.time / 600]
Due Date: [(world.time + checkoutperiod) / 600]
(Checkout Period: [checkoutperiod] minutes) (+/-)
(Commit Entry)
(<-- Return to Main Menu)
"} if(4) dat += "

External Archive

" if(!establish_db_connection(dbcon)) dat += "ERROR: Unable to contact External Archive. Please contact your system administrator for assistance." else dat += {"(Order Book by ISBN)

" dat += "
TITLE\[Order\]
" dat += "
(<-- Return to Main Menu)
" if(5) dat += "

Upload a New Title

" if(!scanner) for(var/obj/machinery/libraryscanner/S in range(9)) if(S.anchored) scanner = S break if(!(scanner?.anchored)) dat += "No scanner found within wireless network range.
" else if(!scanner.cache) dat += "No data found in scanner memory.
" else dat += {"Data marked for upload...
Title: [scanner.cache.name]
"} if(!scanner.cache.author) scanner.cache.author = "Anonymous" dat += {"Author: [scanner.cache.author]
Category: [upload_category]
\[Upload\]
"} dat += "(<-- Return to Main Menu)
" if(7) dat += {"

Accessing Forbidden Lore Vault v 1.3

Are you absolutely sure you want to proceed? EldritchTomes Inc. takes no responsibilities for loss of sanity resulting from this action.

Yes.
No.
"} //dat += "Close

" user << browse(dat, "window=library") onclose(user, "library") /obj/machinery/librarycomp/emag_act(var/remaining_charges, var/mob/user) if (src.density && !src.emagged) src.emagged = 1 return 1 /obj/machinery/librarycomp/attackby(obj/item/W, mob/user) if(istype(W, /obj/item/barcodescanner)) var/obj/item/barcodescanner/scanner = W scanner.computer = src to_chat(user, "[scanner]'s associated machine has been set to [src].") for (var/mob/V in hearers(src)) V.show_message("[src] lets out a low, short blip.", 2) else ..() /obj/machinery/librarycomp/Topic(href, href_list) if(..()) usr << browse(null, "window=library") onclose(usr, "library") return if(href_list["switchscreen"]) switch(href_list["switchscreen"]) if("0") screenstate = 0 if("1") screenstate = 1 if("2") screenstate = 2 if("3") screenstate = 3 if("4") screenstate = 4 if("5") screenstate = 5 if("6") if(!bibledelay) var/obj/item/storage/bible/B = new /obj/item/storage/bible(src.loc) B.verbs += /obj/item/storage/bible/verb/Set_Religion var/randbook = "book" + pick("1", "2", "3", "4", "5", "6" , "7", "8", "9", "10", "11", "12", "13" , "14", "15" , "16") B.icon_state = randbook B.item_state = randbook B.name = "religious book" bibledelay = 1 spawn(60) bibledelay = 0 else for (var/mob/V in hearers(src)) V.show_message("[src]'s monitor flashes, \"Bible printer currently unavailable, please wait a moment.\"") if("7") screenstate = 7 if(href_list["arccheckout"]) if(src.emagged) src.arcanecheckout = 1 src.screenstate = 0 if(href_list["increasetime"]) checkoutperiod += 1 if(href_list["decreasetime"]) checkoutperiod -= 1 if(checkoutperiod < 1) checkoutperiod = 1 if(href_list["editbook"]) buffer_book = sanitizeSafe(input("Enter the book's title:") as text|null) if(href_list["editmob"]) buffer_mob = sanitize(input("Enter the recipient's name:") as text|null, MAX_NAME_LEN) if(href_list["checkout"]) var/datum/borrowbook/b = new /datum/borrowbook b.bookname = sanitizeSafe(buffer_book) b.mobname = sanitize(buffer_mob) b.getdate = world.time b.duedate = world.time + (checkoutperiod * 600) checkouts.Add(b) if(href_list["checkin"]) var/datum/borrowbook/b = locate(href_list["checkin"]) checkouts.Remove(b) if(href_list["delbook"]) var/obj/item/book/b = locate(href_list["delbook"]) inventory.Remove(b) if(href_list["setauthor"]) var/newauthor = sanitize(input("Enter the author's name: ") as text|null) if(newauthor) scanner.cache.author = newauthor if(href_list["setcategory"]) var/newcategory = input("Choose a category: ") in list("Fiction", "Non-Fiction", "Reference", "Religion") if(newcategory) upload_category = newcategory if(href_list["upload"]) if(scanner?.anchored) if(scanner.cache) var/choice = input("Are you certain you wish to upload this title to the Archive?") in list("Confirm", "Abort") if(choice == "Confirm") if(scanner.cache.unique) alert("This book has been rejected from the database. Aborting!") else if(!establish_db_connection(dbcon)) alert("Connection to Archive has been severed. Aborting.") else var/sqltitle = sanitizeSQL(scanner.cache.name) var/sqlauthor = sanitizeSQL(scanner.cache.author) var/sqlcontent = sanitizeSQL(scanner.cache.dat) var/sqlcategory = sanitizeSQL(upload_category) var/sqlckey = sanitizeSQL(ckey(usr.client.ckey)) var/DBQuery/query = dbcon.NewQuery("INSERT INTO ss13_library (author, title, content, category, uploadtime, uploader) VALUES ('[sqlauthor]', '[sqltitle]', '[sqlcontent]', '[sqlcategory]', NOW(), '[sqlckey]')") if(!query.Execute()) to_chat(usr, query.ErrorMsg()) else log_and_message_admins("has uploaded the book titled [scanner.cache.name], [length(scanner.cache.dat)] signs") log_game("[usr.name]/[usr.key] has uploaded the book titled [scanner.cache.name], [length(scanner.cache.dat)] signs",ckey=key_name(usr)) alert("Upload Complete.") if(href_list["targetid"]) var/sqlid = sanitizeSQL(href_list["targetid"]) if(!establish_db_connection(dbcon)) alert("Connection to Archive has been severed. Aborting.") if(bibledelay) for (var/mob/V in hearers(src)) V.show_message("[src]'s monitor flashes, \"Printer unavailable. Please allow a short time before attempting to print.\"") else bibledelay = 1 spawn(60) bibledelay = 0 var/DBQuery/query = dbcon.NewQuery("SELECT * FROM ss13_library WHERE id=[sqlid]") query.Execute() while(query.NextRow()) var/author = query.item[2] var/title = query.item[3] var/content = query.item[4] var/obj/item/book/B = new(src.loc) B.name = "Book: [title]" B.title = title B.author = author B.dat = content B.icon_state = "book[rand(1,7)]" src.visible_message("\The [src]\s printer hums as it produces a book.") break if(href_list["orderbyid"]) var/orderid = input("Enter your order:") as num|null if(orderid) if(isnum(orderid)) var/nhref = "src=\ref[src];targetid=[orderid]" spawn() src.Topic(nhref, params2list(nhref), src) if(href_list["sort"] in list("author", "title", "category")) sortby = href_list["sort"] src.add_fingerprint(usr) src.updateUsrDialog() return // Public Related Code /obj/machinery/librarycomp/public name = "public library computer" is_public = TRUE /* * Library Scanner */ /obj/machinery/libraryscanner name = "book scanner" desc = "A machine that scans books for upload to the library database." icon = 'icons/obj/library.dmi' icon_state = "bigscanner" var/insert_anim = "bigscanner1" anchored = TRUE density = TRUE var/obj/item/book/cache // Last scanned book /obj/machinery/libraryscanner/attackby(obj/item/O, mob/user) if(istype(O, /obj/item/book)) if(!anchored) to_chat(user, SPAN_WARNING("\The [src] must be secured to the floor first!")) return user.drop_from_inventory(O,src) if(O.iswrench()) playsound(get_turf(src), O.usesound, 75, TRUE) if(anchored) user.visible_message(SPAN_NOTICE("\The [user] unsecures \the [src] from the floor."), \ SPAN_NOTICE("You unsecure \the [src] from the floor."), \ SPAN_WARNING("You hear a ratcheting noise.")) else user.visible_message(SPAN_NOTICE("\The [user] secures \the [src] to the floor."), \ SPAN_NOTICE("You secure \the [src] to the floor."), \ SPAN_WARNING("You hear a ratcheting noise.")) anchored = !anchored /obj/machinery/libraryscanner/attack_hand(var/mob/user) usr.set_machine(src) var/dat = "Scanner Control Interface\n" // if(cache) dat += "Data stored in memory.
" else dat += "No data stored in memory.
" dat += "\[Scan\]" if(cache) dat += " \[Clear Memory\]

\[Remove Book\]" else dat += "
" user << browse(dat, "window=scanner") onclose(user, "scanner") /obj/machinery/libraryscanner/Topic(href, href_list) if(..()) usr << browse(null, "window=scanner") onclose(usr, "scanner") return if(href_list["scan"]) flick(insert_anim, src) playsound(loc, 'sound/bureaucracy/scan.ogg', 75, 1) for(var/obj/item/book/B in contents) cache = B break if(href_list["clear"]) cache = null if(href_list["eject"]) for(var/obj/item/book/B in contents) B.forceMove(src.loc) src.add_fingerprint(usr) src.updateUsrDialog() return /* * Book binder */ /obj/machinery/bookbinder name = "book binder" desc = "A machine that takes paper and binds them into books. Fascinating!" icon = 'icons/obj/library.dmi' icon_state = "binder" anchored = TRUE density = TRUE var/binding = FALSE /obj/machinery/bookbinder/attackby(var/obj/O, mob/user) if(istype(O, /obj/item/paper)) if(!anchored) to_chat(user, SPAN_WARNING("\The [src] must be secured to the floor first!")) return if(binding) to_chat(user, SPAN_WARNING("You must wait for \the [src] to finish its current operation!")) return var/turf/T = get_turf(src) user.drop_from_inventory(O,src) user.visible_message(SPAN_NOTICE("\The [user] loads some paper into \the [src]."), SPAN_NOTICE("You load some paper into \the [src].")) visible_message(SPAN_NOTICE("\The [src] begins to hum as it warms up its printing drums.")) playsound(T, 'sound/bureaucracy/binder.ogg', 75, 1) binding = TRUE sleep(rand(200,400)) binding = FALSE if(!anchored) visible_message(SPAN_WARNING("\The [src] buzzes and flashes an error light.")) O.forceMove(T) return visible_message(SPAN_NOTICE("\The [src] whirs as it prints and binds a new book.")) playsound(T, 'sound/bureaucracy/print.ogg', 75, 1) var/obj/item/book/b = new(T) b.dat = O:info b.name = "blank book" b.icon_state = "book[rand(1,7)]" qdel(O) return if(O.iswrench()) playsound(get_turf(src), O.usesound, 75, TRUE) if(anchored) user.visible_message(SPAN_NOTICE("\The [user] unsecures \the [src] from the floor."), \ SPAN_NOTICE("You unsecure \the [src] from the floor."), \ SPAN_WARNING("You hear a ratcheting noise.")) else user.visible_message(SPAN_NOTICE("\The [user] secures \the [src] to the floor."), \ SPAN_NOTICE("You secure \the [src] to the floor."), \ SPAN_WARNING("You hear a ratcheting noise.")) anchored = !anchored