Files
Aurora.3/code/modules/library/lib_items.dm
Alberyk 76b743a986 Adds the Aut'akh unathi (#5919)
* Base work for the unathi robot subspecies.

* Adds metabolism species, kidney vars, and the robot unathi organs.

* Moves some action buttons to organs, pretty much a bay port right now. Todo: the unathi and alien stuff should also go here.

* First autakh implant power.

* Fixes the organs action button this time.

* Finishes more implants, and interactions with flashs and vaurca.

* Prepare for great changes.

* Drops the real bomb, boss.

* He who fights with monsters.

* Far more work into augments and limb removing powers.

* Limb verbs should be good now.

* A LOT of work into the assited organ, allowing it to bleed and etc, as well adding a new chem that will stop bleeding in their case.

* Probably the last work on implants.

* Some extra touches.

* Some tweaks to the species.

* More fixes and adds kyre's sprites.

* More runtime fixes.

* Fixes the species name too.

* Fixes travis.

* Updates this file too to work with the new tools procs.

* Adds changelog

* Fixed changelog.

* Unathi hair and lore description.

* Some tweaks to this too.

* Locks away them for now, they will be released after we got all the events and etc done.

* Changes this chemical.

* Fixes an airlock runtime.

* Adds the non scan flag to the autakh, mostly due to some bizzare interactions with changelings and cloning.

* Organs removal changes; can't take out the organ if it is too damage.

* Restricts them back again.

* Robotic organs now have the proper icons and names.

* Adds sprites for their organs and some extra tweaks.

* Fixes this missing icon.

* emp should also now hurt assited organs.

* Tweaks more organ related things.

* Fixes the head not being properly set as well.

* Fixes their flags.

* fixes the flag for real this time.

* Poze's review.

* Changes the au'takh organ buttons to don't be animated.

* Helps with adminbus or something.

* Fowl's requested changes.

* Fixes a typo.

* Robotic limb's brute and burn mods are now controlled by the limb model.

* Fowl's changes once more.

* Stops some spam.

* More grammar.

* No eal.

* Skull's review.
2019-01-23 19:27:44 +01:00

350 lines
11 KiB
Plaintext

/* Library Items
*
* Contains:
* Bookcase
* Book
* Barcode Scanner
*/
/*
* Bookcase
*/
/obj/structure/bookcase
name = "bookcase"
icon = 'icons/obj/library.dmi'
icon_state = "book-0"
anchored = 1
density = 1
opacity = 1
/obj/structure/bookcase/Initialize()
. = ..()
for(var/obj/item/I in loc)
if(istype(I, /obj/item/weapon/book))
I.forceMove(src)
update_icon()
/obj/structure/bookcase/attackby(obj/O as obj, mob/user as mob)
if(istype(O, /obj/item/weapon/book))
user.drop_from_inventory(O,src)
update_icon()
else if(istype(O, /obj/item/weapon/pen))
var/newname = sanitizeSafe(input("What would you like to title this bookshelf?"), MAX_NAME_LEN)
if(!newname)
return
else
name = ("bookcase ([newname])")
else if(O.iswrench())
playsound(src.loc, 'sound/items/Ratchet.ogg', 100, 1)
user << (anchored ? "<span class='notice'>You unfasten \the [src] from the floor.</span>" : "<span class='notice'>You secure \the [src] to the floor.</span>")
anchored = !anchored
else if(O.isscrewdriver())
playsound(loc, 'sound/items/Screwdriver.ogg', 75, 1)
user << "<span class='notice'>You begin dismantling \the [src].</span>"
if(do_after(user,25))
user << "<span class='notice'>You dismantle \the [src].</span>"
new /obj/item/stack/material/wood(get_turf(src), 3)
for(var/obj/item/weapon/book/b in contents)
b.forceMove((get_turf(src)))
qdel(src)
else
..()
/obj/structure/bookcase/attack_hand(var/mob/user as mob)
if(contents.len)
var/obj/item/weapon/book/choice = input("Which book would you like to remove from the shelf?") as null|obj in contents
if(choice)
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr))
return
if(ishuman(user))
if(!user.get_active_hand())
user.put_in_hands(choice)
else
choice.forceMove(get_turf(src))
update_icon()
/obj/structure/bookcase/ex_act(severity)
switch(severity)
if(1.0)
for(var/obj/item/weapon/book/b in contents)
qdel(b)
qdel(src)
return
if(2.0)
for(var/obj/item/weapon/book/b in contents)
if (prob(50)) b.forceMove(get_turf(src))
else qdel(b)
qdel(src)
return
if(3.0)
if (prob(50))
for(var/obj/item/weapon/book/b in contents)
b.forceMove(get_turf(src))
qdel(src)
return
else
return
/obj/structure/bookcase/update_icon()
if(contents.len < 5)
icon_state = "book-[contents.len]"
else
icon_state = "book-5"
/obj/structure/bookcase/libraryspawn
var/spawn_category
var/spawn_amount = 3
/obj/structure/bookcase/libraryspawn/Initialize()
. = ..()
name = "[initial(name)] ([spawn_category])"
addtimer(CALLBACK(src, .proc/populate_shelves), 0)
/obj/structure/bookcase/libraryspawn/proc/populate_shelves()
if (!establish_db_connection(dbcon))
return
var/query_str = "SELECT author, title, content FROM ss13_library ORDER BY RAND() LIMIT :amount:"
var/list/query_data = list("amount" = spawn_amount)
if (spawn_category)
query_str = "SELECT author, title, content FROM ss13_library WHERE category = :cat: ORDER BY RAND() LIMIT :amount:"
query_data["cat"] = spawn_category
var/DBQuery/query_books = dbcon.NewQuery(query_str)
query_books.Execute(query_data)
while (query_books.NextRow())
CHECK_TICK
var/author = query_books.item[1]
var/title = query_books.item[2]
var/content = query_books.item[3]
var/obj/item/weapon/book/B = new(src)
B.name = "Book: [title]"
B.title = title
B.author = author
B.dat = content
B.icon_state = "book[rand(1,7)]"
update_icon()
/obj/structure/bookcase/libraryspawn/fiction
spawn_category = "Fiction"
/obj/structure/bookcase/libraryspawn/nonfiction
spawn_category = "Non-Fiction"
/obj/structure/bookcase/libraryspawn/adult
spawn_category = "Adult"
/obj/structure/bookcase/libraryspawn/reference
spawn_category = "Reference"
/obj/structure/bookcase/libraryspawn/religion
spawn_category = "Religion"
/obj/structure/bookcase/manuals/medical
name = "Medical Manuals bookcase"
New()
..()
new /obj/item/weapon/book/manual/medical_cloning(src)
new /obj/item/weapon/book/manual/medical_diagnostics_manual(src)
new /obj/item/weapon/book/manual/medical_diagnostics_manual(src)
new /obj/item/weapon/book/manual/medical_diagnostics_manual(src)
update_icon()
/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/atmospipes(src)
new /obj/item/weapon/book/manual/engineering_singularity_safety(src)
new /obj/item/weapon/book/manual/evaguide(src)
update_icon()
/obj/structure/bookcase/manuals/research_and_development
name = "R&D Manuals bookcase"
New()
..()
new /obj/item/weapon/book/manual/research_and_development(src)
update_icon()
/*
* Book
*/
/obj/item/weapon/book
name = "book"
icon = 'icons/obj/library.dmi'
icon_state ="book"
throw_speed = 1
throw_range = 5
w_class = 3 //upped to three because books are, y'know, pretty big. (and you could hide them inside eachother recursively forever)
attack_verb = list("bashed", "whacked", "educated")
var/dat // Actual page content
var/due_date = 0 // Game time in 1/10th seconds
var/author // Who wrote the thing, can be changed by pen or PC. It is not automatically assigned
var/unique = 0 // 0 - Normal book, 1 - Should not be treated as normal book, unable to be copied, unable to be modified
var/title // The real name of the book.
var/carved = 0 // Has the book been hollowed out for use as a secret storage item?
var/obj/item/store //What's in the book?
/obj/item/weapon/book/attack_self(var/mob/user as mob)
if(carved)
if(store)
user << "<span class='notice'>[store] falls out of [title]!</span>"
store.forceMove(get_turf(src.loc))
store = null
return
else
user << "<span class='notice'>The pages of [title] have been cut out!</span>"
return
if(src.dat)
user << browse("<TT><I>Penned by [author].</I></TT> <BR>" + "[dat]", "window=book")
user.visible_message("[user] opens a book titled \"[src.title]\" and begins reading intently.")
onclose(user, "book")
else
user << "This book is completely blank!"
/obj/item/weapon/book/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(carved)
if(!store)
if(W.w_class < 3)
user.drop_from_inventory(W,src)
store = W
user << "<span class='notice'>You put [W] in [title].</span>"
return
else
user << "<span class='notice'>[W] won't fit in [title].</span>"
return
else
user << "<span class='notice'>There's already something in [title]!</span>"
return
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/newtitle = reject_bad_text(sanitizeSafe(input("Write a new title:")))
if(!newtitle)
usr << "The title is invalid."
return
else
src.name = newtitle
src.title = newtitle
if("Contents")
var/content = sanitize(input("Write your book's contents (HTML NOT allowed):") as message|null, MAX_BOOK_MESSAGE_LEN)
if(!content)
usr << "The content is invalid."
return
else
src.dat += content
if("Author")
var/newauthor = sanitize(input(usr, "Write the author's name:"))
if(!newauthor)
usr << "The name is invalid."
return
else
src.author = newauthor
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/material/knife) || W.iswirecutter())
if(carved) return
user << "<span class='notice'>You begin to carve out [title].</span>"
if(do_after(user, 30))
user << "<span class='notice'>You carve out the pages from [title]! You didn't want to read it anyway.</span>"
carved = 1
return
else
..()
/obj/item/weapon/book/attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob, var/target_zone)
if(target_zone == "eyes")
user.visible_message("<span class='notice'>You open up the book and show it to [M]. </span>", \
"<span class='notice'> [user] opens up a book and shows it to [M]. </span>")
M << browse("<TT><I>Penned by [author].</I></TT> <BR>" + "[dat]", "window=book")
user.setClickCooldown(DEFAULT_QUICK_COOLDOWN) //to prevent spam
/*
* Barcode Scanner
*/
/obj/item/weapon/barcodescanner
name = "barcode scanner"
icon = 'icons/obj/library.dmi'
icon_state ="scanner"
throw_speed = 1
throw_range = 5
w_class = 2.0
var/obj/machinery/librarycomp/computer // Associated computer - Modes 1 to 3 use this
var/obj/item/weapon/book/book // Currently scanned book
var/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"