Files
Polaris/code/game/magic/library.dm
SkyMarshal cd5e2476bd Added a new object, for storing premade outfits, that is in clothing closets.
Added clothing closets for several new jobs (Chef, Bartender, Virologist, etc.) and outfitted them.
Paper can now be burned, and acts as a hotspot and a light source when it is on fire.
Tweaked the Allinone broadcasters
Nerfed electrical storms
Response Team leader gets a special assignment/title.
Remapped to add Copiers, Filing Cabinets, and wardrobes
2012-01-26 22:19:33 -07:00

890 lines
30 KiB
Plaintext

//*******************************
//
// Library SQL Configuration
//
//*******************************
// Deprecated! See global.dm for new SQL config vars -- TLE
/*
#define SQL_ADDRESS ""
#define SQL_DB ""
#define SQL_PORT "3306"
#define SQL_LOGIN ""
#define SQL_PASS ""
*/
//*******************************
// Requires Dantom.DB library ( http://www.byond.com/developer/Dantom/DB )
/*
The Library
------------
A place for the crew to go, relax, and enjoy a good book.
Aspiring authors can even self publish and, if they're lucky
convince the on-staff Librarian to submit it to the Archives
to be chronicled in history forever - some say even persisting
through alternate dimensions.
Written by TLE for /tg/station 13
Feel free to use this as you like. Some credit would be cool.
Check us out at http://nanotrasen.com/ if you're so inclined.
*/
// CONTAINS:
// Objects:
// - bookcase
// - book
// - barcode scanner
// Machinery:
// - library computer
// - visitor's computer
// - book binder
// - book scanner
// Datum:
// - borrowbook
// Ideas for the future
// ---------------------
// - Visitor's computer should be able to search the current in-round library inventory (that the Librarian has stocked and checked in)
// -- Give computer other features like an Instant Messenger application, or the ability to edit, save, and print documents.
// - Admin interface directly tied to the Archive DB. Right now there's no way to delete uploaded books in-game.
// -- If this gets implemented, allow Librarians to "tag" or "suggest" books to be deleted. The DB ID of the tagged books gets saved to a text file (or another table in the DB maybe?).
// The admin interface would automatically take these IDs and SELECT them all from the DB to be displayed along with a Delete link to drop the row from the table.
// - When the game sets up and the round begins, have it automatically pick random books from the DB to populate the library with. Even if the Librarian is a useless fuck there are at least a few books around.
// - Allow books to be "hollowed out" like the Chaplain's Bible, allowing you to store one pocket-sized item inside.
// - Make books/book cases burn when exposed to flame.
// - Make book binder hackable.
// - Books shouldn't print straight from the library computer. Make it synch with a machine like the book binder to print instead. This should consume some sort of resource.
/obj/structure/bookcase
name = "bookcase"
icon = 'library.dmi'
icon_state = "bookcase"
anchored = 1
density = 1
opacity = 1
var/category
New()
var/list/books = book_mgr.getall()
var/list/catbooks = new()
// get books in category
for(var/datum/archived_book/B in books)
if(!category || (category != B.category))
continue;
catbooks += B
world << "cat [category]: [B.title]"
if(catbooks.len <= 3)
// if 3 or less books, fill shelf with that
for(var/datum/archived_book/AB in catbooks)
var/obj/item/weapon/book/B = new(src)
B.name = "Book: [AB.title]"
B.title = AB.title
B.author = AB.author
B.dat = AB.dat
B.icon_state = "book[rand(1,7)]"
else
// otherwise, pick 3 random books
for(var/i = 1 to 3)
var/datum/archived_book/AB = pick(catbooks)
var/obj/item/weapon/book/B = new(src)
B.name = "Book: [AB.title]"
B.title = AB.title
B.author = AB.author
B.dat = AB.dat
B.icon_state = "book[rand(1,7)]"
attackby(obj/O as obj, mob/user as mob)
if(istype(O, /obj/item/weapon/book))
user.drop_item()
O.loc = src
else if(istype(O, /obj/item/weapon/pen))
var/newname = input("What would you like to title this bookshelf?") as text|null
if(!newname)
return
else
src.setname(sanitize(newname))
else
..()
attack_hand(var/mob/user as mob)
var/list/books = list()
for(var/obj/item/weapon/book/b in src.contents)
books.Add(b)
if(books.len)
var/obj/item/weapon/book/choice = input("Which book would you like to remove from the shelf?") in books|null as obj|null
if(choice)
choice.loc = src.loc
else
return
else
user << "None of these books pique your interest in the slightest."
proc
setname(var/t as text)
if(t)
src.name = "bookcase ([t])"
ex_act(severity)
switch(severity)
if(1.0)
for(var/obj/item/weapon/book/b in src.contents)
del(b)
del(src)
return
if(2.0)
for(var/obj/item/weapon/book/b in src.contents)
if (prob(50)) b.loc = (get_turf(src))
else del(b)
del(src)
return
if(3.0)
if (prob(50))
for(var/obj/item/weapon/book/b in src.contents)
b.loc = (get_turf(src))
del(src)
return
else
return
/obj/structure/bookcase/manuals/medical
name = "Medical Manuals bookcase"
New()
..()
new /obj/item/weapon/book/manual/medical_cloning(src)
/obj/structure/bookcase/manuals/engineering
name = "Engineering Manuals bookcase"
New()
..()
new /obj/item/weapon/book/manual/engineering_construction(src)
new /obj/item/weapon/book/manual/engineering_particle_accelerator(src)
new /obj/item/weapon/book/manual/engineering_hacking(src)
new /obj/item/weapon/book/manual/engineering_guide(src)
new /obj/item/weapon/book/manual/engineering_singularity_safety(src)
new /obj/item/weapon/book/manual/robotics_cyborgs(src)
/obj/structure/bookcase/manuals/research_and_development
name = "R&D Manuals bookcase"
New()
..()
new /obj/item/weapon/book/manual/research_and_development(src)
/obj/item/weapon/book
name = "book"
icon = 'library.dmi'
icon_state ="book"
throw_speed = 1
throw_range = 5
w_class = 1.0
flags = FPRINT | TABLEPASS
var
dat // Actual page content
due_date = 0 // Game time in 1/10th seconds
author // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned
unique = 0 // 0 - Normal book, 1 - Should not be treated as normal book, unable to be copied, unable to be modified
title // The real name of the book.
attack_self(var/mob/user as mob)
if(src.dat)
user << browse("<TT><I>Penned by [author].</I></TT> <BR>" + "[dat]", "window=book")
if(title)
user.visible_message("[user] opens a book titled \"[src.title]\" and begins reading intently.")
else
user.visible_message("[user] opens a book titled \"[src.name]\" and begins reading intently.")
onclose(user, "book")
else
user << "This book is completely blank!"
attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/pen))
if(unique)
user << "These pages don't seem to take the ink well. Looks like you can't modify it."
return
var/choice = input("What would you like to change?") in list("Title", "Contents", "Author", "Cancel")
switch(choice)
if("Title")
var/title = input("Write a new title:") as text|null
if(!title)
return
else
src.name = sanitize(title)
if("Contents")
var/t = "[src.dat]"
do
t = input(user, "What text do you wish to add?", src.name, t) as message
if ((!in_range(src, usr) && src.loc != user && src.loc.loc != user && user.equipped() != W))
return
if(lentext(t) >= MAX_PAPER_MESSAGE_LEN)
var/cont = input(user, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no")
if(cont == "no")
break
while(lentext(t) > MAX_PAPER_MESSAGE_LEN)
if ((!in_range(src, usr) && src.loc != user && src.loc.loc != user && user.equipped() != W))
return
// check for exploits
for(var/tag in paper_blacklist)
if(findtext(t,"<"+tag))
user << "\blue You think to yourself, \"Hm.. this is only paper...\""
return
src.dat = t
if("Author")
var/nauthor = input("Write the author's name:") as text|null
if(!nauthor)
return
else
src.author = sanitize(nauthor)
else
return
else if(istype(W, /obj/item/weapon/barcodescanner))
var/obj/item/weapon/barcodescanner/scanner = W
if(!scanner.computer)
user << "[W]'s screen flashes: 'No associated computer found!'"
else
switch(scanner.mode)
if(0)
scanner.book = src
user << "[W]'s screen flashes: 'Book stored in buffer.'"
if(1)
scanner.book = src
scanner.computer.buffer_book = src.name
user << "[W]'s screen flashes: 'Book stored in buffer. Book title stored in associated computer buffer.'"
if(2)
scanner.book = src
for(var/datum/borrowbook/b in scanner.computer.checkouts)
if(b.bookname == src.name)
scanner.computer.checkouts.Remove(b)
user << "[W]'s screen flashes: 'Book stored in buffer. Book has been checked in.'"
return
user << "[W]'s screen flashes: 'Book stored in buffer. No active check-out record found for current title.'"
if(3)
scanner.book = src
for(var/obj/item/weapon/book in scanner.computer.inventory)
if(book == src)
user << "[W]'s screen flashes: 'Book stored in buffer. Title already present in inventory, aborting to avoid duplicate entry.'"
return
scanner.computer.inventory.Add(src)
user << "[W]'s screen flashes: 'Book stored in buffer. Title added to general inventory.'"
else if(istype(W, /obj/item/weapon/wirecutters) || istype(W, /obj/item/weapon/scalpel))
if(unique)
user << "These pages seem to be made of a very robust paper. Looks like you can't carve it."
return
if(istype(src.loc, /mob) && usr.l_hand != src && usr.r_hand != src)
user << "\red You either need hold the book or put it down on something first."
return
var/obj/item/weapon/storage/book/B = new(loc)
B.icon_state = icon_state
B.name = name
B.desc = desc
user.remove_from_mob(src)
if(user.get_inactive_hand() == null)
user.put_in_inactive_hand(B)
else
B.loc = user.loc
user << "You carve out the inside of the book. Sneaky!"
del(src)
else
..()
/obj/item/weapon/barcodescanner
name = "barcode scanner"
icon = 'library.dmi'
icon_state ="scanner"
throw_speed = 1
throw_range = 5
w_class = 1.0
flags = FPRINT | TABLEPASS
var
obj/machinery/librarycomp/computer // Associated computer - Modes 1 to 3 use this
obj/item/weapon/book/book // Currently scanned book
mode = 0 // 0 - Scan only, 1 - Scan and Set Buffer, 2 - Scan and Attempt to Check In, 3 - Scan and Attempt to Add to Inventory
attack_self(mob/user as mob)
mode += 1
if(mode > 3)
mode = 0
user << "[src] Status Display:"
var/modedesc
switch(mode)
if(0)
modedesc = "Scan book to local buffer."
if(1)
modedesc = "Scan book to local buffer and set associated computer buffer to match."
if(2)
modedesc = "Scan book to local buffer, attempt to check in scanned book."
if(3)
modedesc = "Scan book to local buffer, attempt to add book to general inventory."
else
modedesc = "ERROR"
user << " - Mode [mode] : [modedesc]"
if(src.computer)
user << "<font color=green>Computer has been associated with this unit.</font>"
else
user << "<font color=red>No associated computer found. Only local scans will function properly.</font>"
user << "\n"
datum/borrowbook // Datum used to keep track of who has borrowed what when and for how long.
var
bookname
mobname
getdate
duedate
/obj/machinery/librarypubliccomp
name = "visitor computer"
icon = 'library.dmi'
icon_state = "computer"
anchored = 1
density = 1
var
screenstate = 0
title
category = "Any"
author
SQLquery
/obj/machinery/librarypubliccomp/attack_hand(var/mob/user as mob)
usr.machine = src
var/dat = "<HEAD><TITLE>Library Visitor</TITLE></HEAD><BODY>\n" // <META HTTP-EQUIV='Refresh' CONTENT='10'>
switch(screenstate)
if(0)
dat += "<h2>Search Settings</h2><br>"
dat += "<A href='?src=\ref[src];settitle=1'>Filter by Title: [title]</A><BR>"
dat += "<A href='?src=\ref[src];setcategory=1'>Filter by Category: [category]</A><BR>"
dat += "<A href='?src=\ref[src];setauthor=1'>Filter by Author: [author]</A><BR>"
dat += "<A href='?src=\ref[src];search=1'>\[Start Search\]</A><BR>"
if(1)
if(config.sql_enabled)
var/DBConnection/dbcon = new()
dbcon.Connect("dbi:mysql:[sqldb]:[sqladdress]:[sqlport]","[sqllogin]","[sqlpass]")
if(!dbcon.IsConnected())
dat += "<font color=red><b>ERROR</b>: Unable to contact External Archive. Please contact your system administrator for assistance.</font><BR>"
else if(!SQLquery)
dat += "<font color=red><b>ERROR</b>: Malformed search request. Please contact your system administrator for assistance.</font><BR>"
else
dat += "<table>"
dat += "<tr><td>AUTHOR</td><td>TITLE</td><td>CATEGORY</td><td>SS<sup>13</sup>BN</td></tr>"
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 += "<tr><td>[author]</td><td>[title]</td><td>[category]</td><td>[id]</td></tr>"
dat += "</table><BR>"
dbcon.Disconnect()
else
dat += "<table>"
dat += "<tr><td>AUTHOR</td><td>TITLE</td><td>CATEGORY</td><td>SS<sup>13</sup>BN</td></tr>"
var/list/books = book_mgr.getall()
for(var/datum/archived_book/book in books)
// search queries
if(author && !findtext(author, book.author))
continue;
if(title && !findtext(title, book.title))
continue;
if(!category || (category != "Any" && category != book.category))
continue;
dat += "<tr><td>[book.author]</td><td>[book.title]</td><td>[book.category]</td><td>[book.id]</td></tr>"
dat += "</table><BR>"
dat += "<A href='?src=\ref[src];back=1'>\[Go Back\]</A><BR>"
user << browse(dat, "window=publiclibrary")
onclose(user, "publiclibrary")
/obj/machinery/librarypubliccomp/Topic(href, href_list)
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 = dd_replacetext(title, "'", "''")
if(href_list["setcategory"])
var/newcategory = input("Choose a category to search for:") in list("Any", "Fiction", "Non-Fiction", "Adult", "Reference", "Religion")
if(newcategory)
category = newcategory
else
category = "Any"
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 = dd_replacetext(author, "'", "''")
if(href_list["search"])
if(config.sql_enabled)
SQLquery = "SELECT author, title, category, id FROM 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
// TODO: Make this an actual /obj/machinery/computer that can be crafted from circuit boards and such
/obj/machinery/librarycomp
name = "Check-In/Out Computer"
icon = 'library.dmi'
icon_state = "computer"
anchored = 1
density = 1
var
emagged = 0
arcanecheckout = 0
screenstate = 0 // 0 - Main Menu, 1 - Inventory, 2 - Checked Out, 3 - Check Out a Book
buffer_book
buffer_mob
upload_category = "Fiction"
list/checkouts = list()
list/inventory = list()
checkoutperiod = 5 // In minutes
obj/machinery/libraryscanner/scanner // Book scanner that will be used when uploading books to the Archive
bibledelay = 0 // LOL NO SPAM (1 minute delay) -- Doohl
/obj/machinery/librarycomp/attack_hand(var/mob/user as mob)
usr.machine = src
var/dat = "<HEAD><TITLE>Book Inventory Management</TITLE></HEAD><BODY>\n" // <META HTTP-EQUIV='Refresh' CONTENT='10'>
switch(screenstate)
if(0)
// Main Menu
dat += "<A href='?src=\ref[src];switchscreen=1'>1. View General Inventory</A><BR>"
dat += "<A href='?src=\ref[src];switchscreen=2'>2. View Checked Out Inventory</A><BR>"
dat += "<A href='?src=\ref[src];switchscreen=3'>3. Check out a Book</A><BR>"
dat += "<A href='?src=\ref[src];switchscreen=4'>4. Connect to External Archive</A><BR>"
dat += "<A href='?src=\ref[src];switchscreen=5'>5. Upload New Title to Archive</A><BR>"
dat += "<A href='?src=\ref[src];switchscreen=6'>6. Print a Bible</A><BR>"
if(src.emagged)
dat += "<A href='?src=\ref[src];switchscreen=7'>7. Access the Forbidden Lore Vault</A><BR>"
if(src.arcanecheckout)
new /obj/item/weapon/tome(src.loc)
user << "<font color=red>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.</font>"
for (var/mob/V in hearers(src))
V.show_message("[usr] stares at the blank screen for a few moments, his expression frozen in fear. When he finally awakens from it, he looks a lot older.", 2)
src.arcanecheckout = 0
if(1)
// Inventory
dat += "<H3>Inventory</H3><BR>"
for(var/obj/item/weapon/book/b in inventory)
dat += "[b.name] <A href='?src=\ref[src];delbook=\ref[b]'>(Delete)</A><BR>"
dat += "<A href='?src=\ref[src];switchscreen=0'>(Return to main menu)</A><BR>"
if(2)
// Checked Out
dat += "<h3>Checked Out Books</h3><BR>"
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 = "<font color=red><b>(OVERDUE)</b> [timedue]</font>"
else
timedue = round(timedue)
dat += "\"[b.bookname]\", Checked out to: [b.mobname]<BR>--- Taken: [timetaken] minutes ago, Due: in [timedue] minutes<BR>"
dat += "<A href='?src=\ref[src];checkin=\ref[b]'>(Check In)</A><BR><BR>"
dat += "<A href='?src=\ref[src];switchscreen=0'>(Return to main menu)</A><BR>"
if(3)
// Check Out a Book
dat += "<h3>Check Out a Book</h3><BR>"
dat += "Book: [src.buffer_book] "
dat += "<A href='?src=\ref[src];editbook=1'>\[Edit\]</A><BR>"
dat += "Recipient: [src.buffer_mob] "
dat += "<A href='?src=\ref[src];editmob=1'>\[Edit\]</A><BR>"
dat += "Checkout Date : [world.time/600]<BR>"
dat += "Due Date: [(world.time + checkoutperiod)/600]<BR>"
dat += "(Checkout Period: [checkoutperiod] minutes) (<A href='?src=\ref[src];increasetime=1'>+</A>/<A href='?src=\ref[src];decreasetime=1'>-</A>)"
dat += "<A href='?src=\ref[src];checkout=1'>(Commit Entry)</A><BR>"
dat += "<A href='?src=\ref[src];switchscreen=0'>(Return to main menu)</A><BR>"
if(4)
dat += "<h3>External Archive</h3>"
if(config.sql_enabled)
var/DBConnection/dbcon = new()
dbcon.Connect("dbi:mysql:[sqldb]:[sqladdress]:[sqlport]","[sqllogin]","[sqlpass]")
if(!dbcon.IsConnected())
dat += "<font color=red><b>ERROR</b>: Unable to contact External Archive. Please contact your system administrator for assistance.</font>"
else
dat += "<A href='?src=\ref[src];orderbyid=1'>(Order book by SS<sup>13</sup>BN)</A><BR><BR>"
dat += "<table>"
dat += "<tr><td>AUTHOR</td><td>TITLE</td><td>CATEGORY</td><td></td></tr>"
var/DBQuery/query = dbcon.NewQuery("SELECT id, author, title, category FROM library")
query.Execute()
while(query.NextRow())
var/id = query.item[1]
var/author = query.item[2]
var/title = query.item[3]
var/category = query.item[4]
dat += "<tr><td>[author]</td><td>[title]</td><td>[category]</td><td><A href='?src=\ref[src];targetid=[id]'>\[Order\]</A></td></tr>"
dat += "</table><BR>"
dat += "<A href='?src=\ref[src];switchscreen=0'>(Return to main menu)</A><BR>"
dbcon.Disconnect()
else
dat += "<A href='?src=\ref[src];orderbyid=1'>(Order book by SS<sup>13</sup>BN)</A><BR><BR>"
dat += "<table>"
dat += "<tr><td>AUTHOR</td><td>TITLE</td><td>CATEGORY</td><td></td></tr>"
var/list/books = book_mgr.getall()
for(var/datum/archived_book/book in books)
dat += "<tr><td>[book.author]</td><td>[book.title]</td><td>[book.category]</td><td>[book.id]</td></tr>"
dat += "</table><BR>"
dat += "<A href='?src=\ref[src];switchscreen=0'>(Return to main menu)</A><BR>"
if(5)
dat += "<H3>Upload a New Title</H3>"
if(!scanner)
for(var/obj/machinery/libraryscanner/S in range(9))
scanner = S
break
if(!scanner)
dat += "<FONT color=red>No scanner found within wireless network range.</FONT><BR>"
else if(!scanner.cache)
dat += "<FONT color=red>No data found in scanner memory.</FONT><BR>"
else
dat += "<TT>Data marked for upload...</TT><BR>"
dat += "<TT>Title: </TT>[scanner.cache.name]<BR>"
if(!scanner.cache.author)
scanner.cache.author = "Anonymous"
dat += "<TT>Author: </TT><A href='?src=\ref[src];setauthor=1'>[scanner.cache.author]</A><BR>"
dat += "<TT>Category: </TT><A href='?src=\ref[src];setcategory=1'>[upload_category]</A><BR>"
dat += "<A href='?src=\ref[src];upload=1'>\[Upload\]</A><BR>"
dat += "<A href='?src=\ref[src];switchscreen=0'>(Return to main menu)</A><BR>"
if(7)
dat += "<h3>Accessing Forbidden Lore Vault v 1.3</h3>"
dat += "Are you absolutely sure you want to proceed? EldritchTomes Inc. takes no responsibilities for loss of sanity resulting from this action.<p>"
dat += "<A href='?src=\ref[src];arccheckout=1'>Yes.</A><BR>"
dat += "<A href='?src=\ref[src];switchscreen=0'>No.</A><BR>"
//dat += "<A HREF='?src=\ref[user];mach_close=library'>Close</A><br><br>"
user << browse(dat, "window=library")
onclose(user, "library")
/obj/machinery/librarycomp/attackby(obj/item/weapon/W as obj, mob/user as mob)
if (src.density && istype(W, /obj/item/weapon/card/emag))
src.emagged = 1
if(istype(W, /obj/item/weapon/barcodescanner))
var/obj/item/weapon/barcodescanner/scanner = W
scanner.computer = src
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(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/weapon/storage/bible/B = new /obj/item/weapon/storage/bible(src.loc)
if(ticker && ( ticker.Bible_icon_state && ticker.Bible_item_state) )
B.icon_state = ticker.Bible_icon_state
B.item_state = ticker.Bible_item_state
B.name = ticker.Bible_name
bibledelay = 60
spawn(0)
while(bibledelay >= 1 && src)
sleep(10)
bibledelay -- // subtract one second to countdown
bibledelay = 0
else
for (var/mob/V in hearers(src))
V.show_message("<b>[src]</b>'s monitor flashes, \"[bibledelay] seconds remaining until the bible printer is ready for use.\"")
if("7")
screenstate = 7
if(href_list["arccheckout"])
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 = input("Enter the book's title:") as text|null
if(href_list["editmob"])
buffer_mob = input("Enter the recipient's name:") as text|null
if(href_list["checkout"])
var/datum/borrowbook/b = new /datum/borrowbook
b.bookname = sanitize(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/weapon/book/b = locate(href_list["delbook"])
inventory.Remove(b)
if(href_list["setauthor"])
var/newauthor = input("Enter the author's name: ") as text|null
if(newauthor)
scanner.cache.author = sanitize(newauthor)
if(href_list["setcategory"])
var/newcategory = input("Choose a category: ") in list("Fiction", "Non-Fiction", "Adult", "Reference", "Religion")
if(newcategory)
upload_category = newcategory
if(href_list["upload"])
if(scanner)
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(config.sql_enabled)
var/DBConnection/dbcon = new()
dbcon.Connect("dbi:mysql:[sqldb]:[sqladdress]:[sqlport]","[sqllogin]","[sqlpass]")
if(!dbcon.IsConnected())
alert("Connection to Archive has been severed. Aborting.")
else
/*
var/sqltitle = dbcon.Quote(scanner.cache.name)
var/sqlauthor = dbcon.Quote(scanner.cache.author)
var/sqlcontent = dbcon.Quote(scanner.cache.dat)
var/sqlcategory = dbcon.Quote(upload_category)
*/
var/sqltitle = dd_replacetext(scanner.cache.name, "'", "''")
var/sqlauthor = dd_replacetext(scanner.cache.author, "'", "''")
var/sqlcontent = dd_replacetext(scanner.cache.dat, "'", "''")
var/sqlcategory = upload_category
///proc/dd_replacetext(text, search_string, replacement_string)
var/DBQuery/query = dbcon.NewQuery("INSERT INTO library (author, title, content, category) VALUES ('[sqlauthor]', '[sqltitle]', '[sqlcontent]', '[sqlcategory]')")
if(!query.Execute())
usr << query.ErrorMsg()
else
log_game("[usr.name]/[usr.key] has uploaded the book titled [scanner.cache.name], [length(scanner.cache.dat)] signs")
alert("Upload Complete.")
dbcon.Disconnect()
else
var/datum/archived_book/B = new()
B.title = scanner.cache.name
B.author = scanner.cache.author
B.dat = scanner.cache.dat
B.category = upload_category
B.id = book_mgr.freeid()
B.save()
log_game("[usr.name]/[usr.key] has uploaded the book titled [scanner.cache.name], [length(scanner.cache.dat)] signs")
alert("Upload Complete.")
if(href_list["targetid"])
if(config.sql_enabled)
var/sqlid = href_list["targetid"]
var/DBConnection/dbcon = new()
dbcon.Connect("dbi:mysql:[sqldb]:[sqladdress]:[sqlport]","[sqllogin]","[sqlpass]")
if(!dbcon.IsConnected())
alert("Connection to Archive has been severed. Aborting.")
else
var/DBQuery/query = dbcon.NewQuery("SELECT * FROM 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/weapon/book/B = new(src.loc)
if(title)
B.name = "[title]"
else
B.name = "Untitled book"
B.title = title
B.author = author
B.dat = content
B.icon_state = "book[rand(1,7)]"
src.visible_message("[src]'s printer hums as it produces a completely bound book. How did it do that?")
break
dbcon.Disconnect()
else
var/datum/archived_book/AB = new(book_mgr.path(text2num(href_list["targetid"])))
if(!AB)
alert("Book not found!")
else
var/obj/item/weapon/book/B = new(src.loc)
B.name = "Book: [AB.title]"
B.title = AB.title
B.author = AB.author
B.dat = AB.dat
B.icon_state = "book[rand(1,7)]"
src.visible_message("[src]'s printer hums as it produces a completely bound book. How did it do that?")
if(href_list["orderbyid"])
var/orderid = input("Enter your order:") as num|null
if(orderid)
var/nhref = "src=\ref[src];targetid=[orderid]"
spawn() src.Topic(nhref, params2list(nhref), src)
src.add_fingerprint(usr)
src.updateUsrDialog()
return
/obj/machinery/libraryscanner
name = "scanner"
icon = 'library.dmi'
icon_state = "bigscanner"
anchored = 1
density = 1
var
obj/item/weapon/book/cache // Last scanned book
/obj/machinery/libraryscanner/attackby(var/obj/O as obj, var/mob/user as mob)
if(istype(O, /obj/item/weapon/book))
user.drop_item()
O.loc = src
/obj/machinery/libraryscanner/attack_hand(var/mob/user as mob)
usr.machine = src
var/dat = "<HEAD><TITLE>Scanner Control Interface</TITLE></HEAD><BODY>\n" // <META HTTP-EQUIV='Refresh' CONTENT='10'>
if(cache)
dat += "<FONT color=#005500>Data stored in memory.</FONT><BR>"
else
dat += "No data stored in memory.<BR>"
dat += "<A href='?src=\ref[src];scan=1'>\[Scan\]</A>"
if(cache)
dat += " <A href='?src=\ref[src];clear=1'>\[Clear Memory\]</A><BR><BR><A href='?src=\ref[src];eject=1'>\[Remove Book\]</A>"
else
dat += "<BR>"
user << browse(dat, "window=scanner")
onclose(user, "scanner")
/obj/machinery/libraryscanner/Topic(href, href_list)
if(href_list["scan"])
for(var/obj/item/weapon/book/B in contents)
cache = B
break
if(href_list["clear"])
cache = null
if(href_list["eject"])
for(var/obj/item/weapon/book/B in contents)
B.loc = src.loc
src.add_fingerprint(usr)
src.updateUsrDialog()
return
/obj/machinery/bookbinder
name = "Book Binder"
icon = 'library.dmi'
icon_state = "binder"
anchored = 1
density = 1
attackby(var/obj/O as obj, var/mob/user as mob)
if(istype(O, /obj/item/weapon/paper))
user.drop_item()
O.loc = src
user.visible_message("[user] loads some paper into [src].", "You load some paper into [src].")
src.visible_message("[src] begins to hum as it warms up its printing drums.")
sleep(rand(200,400))
src.visible_message("[src] whirs as it prints and binds a new book.")
var/obj/item/weapon/book/b = new(src.loc)
b.dat = O:info
b.name = "Print Job #" + "[rand(100, 999)]"
b.icon_state = "book[rand(1,7)]"
del(O)
else
..()