Files
Bubberstation/code/modules/library/book.dm
SkyratBot 4c0da7d43b [MIRROR] Book patches [MDB IGNORE] (#21321)
* Book patches (#75565)

## About The Pull Request
1. Fixes #75555 knives already have their `sharpness = SHARP_EDGED` so
there's no need to explicitly type check for them and overall that if
condition was just a mind blender, so it's better now
2. Fixes #75577 bibles can convert other bibles again and will not
attempt to store it inside. Carrying over the fix that was implemented
in #73137

## Changelog
🆑
fix: wire cutter's can carve out book's again.
fix: bibles can convert other bibles
/🆑

---------

Co-authored-by: carlarctg <53100513+carlarctg@ users.noreply.github.com>
Co-authored-by: Mothblocks <35135081+Mothblocks@ users.noreply.github.com>

* Book patches

---------

Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com>
Co-authored-by: carlarctg <53100513+carlarctg@ users.noreply.github.com>
Co-authored-by: Mothblocks <35135081+Mothblocks@ users.noreply.github.com>
2023-05-21 22:07:43 +01:00

198 lines
7.5 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)
to_chat(user, span_alert("[scanner]'s screen flashes: 'No associated computer found!'"))
return
scanner.book_data = book_data.return_copy()
switch(scanner.mode)
if(0)
to_chat(user, span_notice("[scanner]'s screen flashes: 'Book stored in buffer.'"))
if(1)
computer.buffer_book = book_data.return_copy()
to_chat(user, span_notice("[scanner]'s screen flashes: 'Book stored in buffer. Book title stored in associated computer buffer.'"))
if(2)
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()
to_chat(user, span_notice("[scanner]'s screen flashes: 'Book stored in buffer. Book has been checked in.'"))
return
to_chat(user, span_notice("[scanner]'s screen flashes: 'Book stored in buffer. No active check-out record found for current title.'"))
if(3)
var/datum/book_info/our_copy = book_data.return_copy()
computer.inventory[ref(our_copy)] = our_copy
computer.inventory_update()
to_chat(user, span_notice("[scanner]'s screen flashes: 'Book stored in buffer. Title added to general 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