mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-02-07 23:09:28 +00:00
* Improves some confusing aspects of the Library (#75781) ## About The Pull Request The barcode scanner now uses balloon alerts and only has 2 modes: check in and add to inventory. It used to have 4, 2 of which were useless. Added a title and author to chuuni granter so it's not broken to the Curator's console. Moves inventory ui data stuff to ui static data so we can reference it in checkout, which now uses a dropdown list of all books in checkout, instead of having you fill out the name of the book yourself. Removes sending things to a computer by scanning a book then connecting it to a computer. Just connect it to a computer first, there's no need for this copy and paste stuff. Finally, lets the book bag hold posters, since the Curator prints them and it would be nice if they can also carry them without filling a bag. Video was taken before the balloon alert stuff so just ignore that part https://github.com/tgstation/tgstation/assets/53777086/e78011af-fb23-4553-a92d-f3dcc8bb5601 ## Why It's Good For The Game The library is currently very confusing for new people to figure out, I thought this might be able to help with that. The dropdown in the UI now means it's easier to give out books in inventory, and you can no longer just type whatever the hell you wanted. ## Changelog 🆑 qol: The Curator's barcode scanner has been simplified into 2 modes: check-in and add to inventory. qol: The Book bag can now hold posters. ui: The library console can now lend books out easier with a dropdown menu to all inventory books. /🆑 --------- Co-authored-by: MrMelbert <51863163+MrMelbert@ users.noreply.github.com> * Improves some confusing aspects of the Library --------- Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com> Co-authored-by: MrMelbert <51863163+MrMelbert@ users.noreply.github.com>
195 lines
6.9 KiB
Plaintext
195 lines
6.9 KiB
Plaintext
/obj/item/book
|
|
name = "book"
|
|
desc = "Crack it open, inhale the musk of its pages, and learn something new."
|
|
icon = 'icons/obj/library.dmi'
|
|
icon_state ="book"
|
|
worn_icon_state = "book"
|
|
throw_speed = 1
|
|
throw_range = 5
|
|
w_class = WEIGHT_CLASS_NORMAL //upped to three because books are, y'know, pretty big. (and you could hide them inside eachother recursively forever)
|
|
attack_verb_continuous = list("bashes", "whacks", "educates")
|
|
attack_verb_simple = list("bash", "whack", "educate")
|
|
resistance_flags = FLAMMABLE
|
|
drop_sound = 'sound/items/handling/book_drop.ogg'
|
|
pickup_sound = 'sound/items/handling/book_pickup.ogg'
|
|
/// Maximum icon state number
|
|
var/maximum_book_state = 8
|
|
/// Game time in 1/10th seconds
|
|
var/due_date = 0
|
|
/// false - Normal book, true - Should not be treated as normal book, unable to be copied, unable to be modified
|
|
var/unique = FALSE
|
|
/// whether or not we have been carved out
|
|
var/carved = FALSE
|
|
|
|
/// Specific window size for the book, i.e: "1920x1080", Size x Width
|
|
var/window_size = null
|
|
/// The initial title, for use in var editing and such
|
|
var/starting_title
|
|
/// The initial author, for use in var editing and such
|
|
var/starting_author
|
|
/// The initial bit of content, for use in var editing and such
|
|
var/starting_content
|
|
/// The packet of information that describes this book
|
|
var/datum/book_info/book_data
|
|
|
|
/obj/item/book/Initialize(mapload)
|
|
. = ..()
|
|
book_data = new(starting_title, starting_author, starting_content)
|
|
|
|
AddElement(/datum/element/falling_hazard, damage = 5, wound_bonus = 0, hardhat_safety = TRUE, crushes = FALSE, impact_sound = drop_sound)
|
|
|
|
/obj/item/book/examine(mob/user)
|
|
. = ..()
|
|
if(carved)
|
|
. += span_notice("[src] has been hollowed out.")
|
|
|
|
/obj/item/book/ui_static_data(mob/user)
|
|
var/list/data = list()
|
|
data["author"] = book_data.get_author()
|
|
data["title"] = book_data.get_title()
|
|
data["content"] = book_data.get_content()
|
|
return data
|
|
|
|
/obj/item/book/ui_interact(mob/living/user, datum/tgui/ui)
|
|
if(carved)
|
|
balloon_alert(user, "book is carved out!")
|
|
return
|
|
if(!length(book_data.get_content()))
|
|
balloon_alert(user, "book is blank!")
|
|
return
|
|
|
|
if(istype(user) && !isnull(user.mind))
|
|
LAZYINITLIST(user.mind.book_titles_read)
|
|
var/has_not_read_book = !(starting_title in user.mind.book_titles_read)
|
|
if(has_not_read_book)
|
|
user.add_mood_event("book_nerd", /datum/mood_event/book_nerd)
|
|
user.mind.book_titles_read[starting_title] = TRUE
|
|
|
|
ui = SStgui.try_update_ui(user, src, ui)
|
|
if(!ui)
|
|
ui = new(user, src, "MarkdownViewer", name)
|
|
ui.open()
|
|
|
|
/obj/item/book/attack_self(mob/user)
|
|
if(user.is_blind())
|
|
to_chat(user, span_warning("You are blind and can't read anything!"))
|
|
return
|
|
|
|
if(!user.can_read(src))
|
|
return
|
|
|
|
user.visible_message(span_notice("[user] opens a book titled \"[book_data.title]\" and begins reading intently."))
|
|
ui_interact(user)
|
|
|
|
/obj/item/book/attackby(obj/item/attacking_item, mob/living/user, params)
|
|
if(burn_paper_product_attackby_check(attacking_item, user))
|
|
return
|
|
|
|
if(istype(attacking_item, /obj/item/pen))
|
|
if(!user.can_perform_action(src) || !user.can_write(attacking_item))
|
|
return
|
|
if(user.is_blind())
|
|
to_chat(user, span_warning("As you are trying to write on the book, you suddenly feel very stupid!"))
|
|
return
|
|
if(unique)
|
|
to_chat(user, span_warning("These pages don't seem to take the ink well! Looks like you can't modify it."))
|
|
return
|
|
if(carved)
|
|
to_chat(user, span_warning("The book has been carved out! There is nothing to be vandalized."))
|
|
return
|
|
|
|
var/choice = tgui_input_list(usr, "What would you like to change?", "Book Alteration", list("Title", "Contents", "Author", "Cancel"))
|
|
if(isnull(choice))
|
|
return
|
|
if(!user.can_perform_action(src) || !user.can_write(attacking_item))
|
|
return
|
|
switch(choice)
|
|
if("Title")
|
|
var/newtitle = reject_bad_text(tgui_input_text(user, "Write a new title", "Book Title", max_length = 30))
|
|
if(!user.can_perform_action(src) || !user.can_write(attacking_item))
|
|
return
|
|
if (length_char(newtitle) > 30)
|
|
to_chat(user, span_warning("That title won't fit on the cover!"))
|
|
return
|
|
if(!newtitle)
|
|
to_chat(user, span_warning("That title is invalid."))
|
|
return
|
|
name = newtitle
|
|
book_data.set_title(html_decode(newtitle)) //Don't want to double encode here
|
|
if("Contents")
|
|
var/content = tgui_input_text(user, "Write your book's contents (HTML NOT allowed)", "Book Contents", multiline = TRUE)
|
|
if(!user.can_perform_action(src) || !user.can_write(attacking_item))
|
|
return
|
|
if(!content)
|
|
to_chat(user, span_warning("The content is invalid."))
|
|
return
|
|
book_data.set_content(html_decode(content))
|
|
if("Author")
|
|
var/author = tgui_input_text(user, "Write the author's name", "Author Name")
|
|
if(!user.can_perform_action(src) || !user.can_write(attacking_item))
|
|
return
|
|
if(!author)
|
|
to_chat(user, span_warning("The name is invalid."))
|
|
return
|
|
book_data.set_author(html_decode(author)) //Setting this encodes, don't want to double up
|
|
|
|
else if(istype(attacking_item, /obj/item/barcodescanner))
|
|
var/obj/item/barcodescanner/scanner = attacking_item
|
|
var/obj/machinery/computer/libraryconsole/bookmanagement/computer = scanner.computer_ref?.resolve()
|
|
if(!computer)
|
|
user.balloon_alert(user, "not connected to computer!")
|
|
return
|
|
|
|
switch(scanner.scan_mode)
|
|
if(BARCODE_SCANNER_CHECKIN)
|
|
var/list/checkouts = computer.checkouts
|
|
for(var/checkout_ref in checkouts)
|
|
var/datum/borrowbook/maybe_ours = checkouts[checkout_ref]
|
|
if(!book_data.compare(maybe_ours.book_data))
|
|
continue
|
|
checkouts -= checkout_ref
|
|
computer.checkout_update()
|
|
user.balloon_alert(user, "book checked in")
|
|
return
|
|
|
|
user.balloon_alert(user, "book not checked out!")
|
|
return
|
|
if(BARCODE_SCANNER_INVENTORY)
|
|
var/datum/book_info/our_copy = book_data.return_copy()
|
|
computer.inventory[ref(our_copy)] = our_copy
|
|
computer.inventory_update()
|
|
user.balloon_alert(user, "book added to inventory")
|
|
|
|
else if(try_carve(attacking_item, user, params))
|
|
return
|
|
return ..()
|
|
|
|
/// Generates a random icon state for the book
|
|
/obj/item/book/proc/gen_random_icon_state()
|
|
icon_state = "book[rand(1, maximum_book_state)]"
|
|
|
|
/// Called when user attempts to carve the book with an item
|
|
/obj/item/book/proc/try_carve(obj/item/carving_item, mob/living/user, params)
|
|
if(carved)
|
|
return FALSE
|
|
if(!user.combat_mode)
|
|
return FALSE
|
|
//special check for wirecutter's because they don't have a sharp edge
|
|
if((carving_item.sharpness & SHARP_EDGED) || (carving_item.tool_behaviour == TOOL_WIRECUTTER))
|
|
balloon_alert(user, "carving out...")
|
|
if(!do_after(user, 3 SECONDS, target = src))
|
|
balloon_alert(user, "interrupted!")
|
|
return FALSE
|
|
carve_out(carving_item, user)
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/// Called when the book gets carved successfully
|
|
/obj/item/book/proc/carve_out(obj/item/carving_item, mob/living/user)
|
|
if(user)
|
|
balloon_alert(user, "carved out")
|
|
playsound(src, 'sound/effects/cloth_rip.ogg', vol = 75, vary = TRUE)
|
|
carved = TRUE
|
|
create_storage(max_slots = 1)
|
|
return TRUE
|