Files
Bubberstation/code/modules/library/bookcase.dm
SmArtKar 4ac4375faf Adds pen clicking, changes most pen typechecks into writing implement checks (#84186)
## About The Pull Request

Fixes #84170 
Adds pen clicking and changes some of edagger and pendriver code to use
it instead.
Also replaces most pen typechecks to writing implement checks where it
makes sense, so now you can rename things with everything you can write
with (crayons)


![3d6NwcATNp](https://github.com/tgstation/tgstation/assets/44720187/f6b3ba2f-f3de-4e40-827f-2bad153a92f4)

Twisting pen caps (for traitor uplinks) has been moved to ctrl + click
instead.
2024-06-24 16:08:37 -05:00

213 lines
6.8 KiB
Plaintext

#define BOOKCASE_UNANCHORED 0
#define BOOKCASE_ANCHORED 1
#define BOOKCASE_FINISHED 2
/obj/structure/bookcase
name = "bookcase"
icon = 'icons/obj/service/library.dmi'
icon_state = "bookempty"
desc = "A great place for storing knowledge."
anchored = FALSE
density = TRUE
opacity = FALSE
resistance_flags = FLAMMABLE
max_integrity = 200
armor_type = /datum/armor/structure_bookcase
var/state = BOOKCASE_UNANCHORED
/// When enabled, books_to_load number of random books will be generated for this bookcase
var/load_random_books = FALSE
/// The category of books to pick from when populating random books.
var/random_category = null
/// How many random books to generate.
var/books_to_load = 0
/datum/armor/structure_bookcase
fire = 50
/obj/structure/bookcase/Initialize(mapload)
. = ..()
if(!mapload || QDELETED(src))
return
// Only mapload from here on
set_anchored(TRUE)
state = BOOKCASE_FINISHED
for(var/obj/item/I in loc)
if(!isbook(I))
continue
I.forceMove(src)
update_appearance()
if(SSlibrary.initialized)
INVOKE_ASYNC(src, PROC_REF(load_shelf))
else
SSlibrary.shelves_to_load += src
///proc for doing things after a bookcase is randomly populated
/obj/structure/bookcase/proc/after_random_load()
return
///Loads the shelf, both by allowing it to generate random items, and by adding its contents to a list used by library machines
/obj/structure/bookcase/proc/load_shelf()
//Loads a random selection of books in from the db, adds a copy of their info to a global list
//To send to library consoles as a starting inventory
if(load_random_books)
create_random_books(books_to_load, src, FALSE, random_category)
after_random_load()
update_appearance() //Make sure you look proper
var/area/our_area = get_area(src)
var/area_type = our_area.type //Save me from the dark
if(!SSlibrary.books_by_area[area_type])
SSlibrary.books_by_area[area_type] = list()
//Time to populate that list
var/list/books_in_area = SSlibrary.books_by_area[area_type]
for(var/obj/item/book/book in contents)
var/datum/book_info/info = book.book_data
books_in_area += info.return_copy()
/obj/structure/bookcase/examine(mob/user)
. = ..()
if(!anchored)
. += span_notice("The <i>bolts</i> on the bottom are unsecured.")
else
. += span_notice("It's secured in place with <b>bolts</b>.")
switch(state)
if(BOOKCASE_UNANCHORED)
. += span_notice("There's a <b>small crack</b> visible on the back panel.")
if(BOOKCASE_ANCHORED)
. += span_notice("There's space inside for a <i>wooden</i> shelf.")
if(BOOKCASE_FINISHED)
. += span_notice("There's a <b>small crack</b> visible on the shelf.")
/obj/structure/bookcase/set_anchored(anchorvalue)
. = ..()
if(isnull(.))
return
state = anchorvalue
if(!anchorvalue) //in case we were vareditted or uprooted by a hostile mob, ensure we drop all our books instead of having them disappear till we're rebuild.
var/atom/Tsec = drop_location()
for(var/obj/I in contents)
if(!isbook(I))
continue
I.forceMove(Tsec)
update_appearance()
/obj/structure/bookcase/attackby(obj/item/I, mob/user, params)
switch(state)
if(BOOKCASE_UNANCHORED)
if(I.tool_behaviour == TOOL_WRENCH)
if(I.use_tool(src, user, 20, volume=50))
to_chat(user, span_notice("You wrench the frame into place."))
set_anchored(TRUE)
else if(I.tool_behaviour == TOOL_CROWBAR)
if(I.use_tool(src, user, 20, volume=50))
to_chat(user, span_notice("You pry the frame apart."))
deconstruct(TRUE)
if(BOOKCASE_ANCHORED)
if(istype(I, /obj/item/stack/sheet/mineral/wood))
var/obj/item/stack/sheet/mineral/wood/W = I
if(W.get_amount() >= 2)
W.use(2)
to_chat(user, span_notice("You add a shelf."))
state = BOOKCASE_FINISHED
update_appearance()
else if(I.tool_behaviour == TOOL_WRENCH)
I.play_tool_sound(src, 100)
to_chat(user, span_notice("You unwrench the frame."))
set_anchored(FALSE)
if(BOOKCASE_FINISHED)
if(isbook(I))
if(!user.transferItemToLoc(I, src))
return
update_appearance()
else if(atom_storage)
for(var/obj/item/T in I.contents)
if(istype(T, /obj/item/book) || istype(T, /obj/item/spellbook))
atom_storage.attempt_remove(T, src)
to_chat(user, span_notice("You empty \the [I] into \the [src]."))
update_appearance()
else if(IS_WRITING_UTENSIL(I))
if(!user.can_perform_action(src) || !user.can_write(I))
return
var/newname = tgui_input_text(user, "What would you like to title this bookshelf?", "Bookshelf Renaming", max_length = MAX_NAME_LEN)
if(!user.can_perform_action(src) || !user.can_write(I))
return
if(!newname)
return
else
name = "bookcase ([sanitize(newname)])"
else if(I.tool_behaviour == TOOL_CROWBAR)
if(length(contents))
to_chat(user, span_warning("You need to remove the books first!"))
else
I.play_tool_sound(src, 100)
to_chat(user, span_notice("You pry the shelf out."))
new /obj/item/stack/sheet/mineral/wood(drop_location(), 2)
state = BOOKCASE_ANCHORED
update_appearance()
else
return ..()
/obj/structure/bookcase/attack_hand(mob/living/user, list/modifiers)
. = ..()
if(.)
return
if(!istype(user))
return
if(!length(contents))
return
var/obj/item/book/choice = tgui_input_list(user, "Book to remove from the shelf", "Remove Book", sort_names(contents.Copy()))
if(isnull(choice))
return
if(!(user.mobility_flags & MOBILITY_USE) || user.stat != CONSCIOUS || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED) || !in_range(loc, user))
return
if(ishuman(user))
if(!user.get_active_held_item())
user.put_in_hands(choice)
else
choice.forceMove(drop_location())
update_appearance()
/obj/structure/bookcase/atom_deconstruct(disassembled = TRUE)
var/atom/Tsec = drop_location()
new /obj/item/stack/sheet/mineral/wood(Tsec, 4)
for(var/obj/item/I in contents)
if(!isbook(I)) //Wake me up inside
continue
I.forceMove(Tsec)
/obj/structure/bookcase/update_icon_state()
if(state == BOOKCASE_UNANCHORED || state == BOOKCASE_ANCHORED)
icon_state = "bookempty"
return ..()
var/amount = length(contents)
icon_state = "book-[clamp(amount, 0, 5)]"
return ..()
/obj/structure/bookcase/manuals/engineering
name = "engineering manuals bookcase"
/obj/structure/bookcase/manuals/engineering/Initialize(mapload)
. = ..()
new /obj/item/book/manual/wiki/engineering_construction(src)
new /obj/item/book/manual/wiki/engineering_hacking(src)
new /obj/item/book/manual/wiki/engineering_guide(src)
new /obj/item/book/manual/wiki/robotics_cyborgs(src)
update_appearance()
/obj/structure/bookcase/manuals/research_and_development
name = "\improper R&D manuals bookcase"
/obj/structure/bookcase/manuals/research_and_development/Initialize(mapload)
. = ..()
new /obj/item/book/manual/wiki/research_and_development(src)
update_appearance()
#undef BOOKCASE_UNANCHORED
#undef BOOKCASE_ANCHORED
#undef BOOKCASE_FINISHED