mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 20:48:56 +01:00
Refactors book attackby into item interaction procs, adding screentips, minor qol (#91273)
## About The Pull Request This mostly just refactors the book `attackby(...)` proc into `item_interaction(...)`, with some side-effects and screentips. Notable ones follow here: We move carving away from combat mode, and instead based it on whether our tool is a pure writing utensil, a pure carving tool, or both at once like the captain's fountain pen. If it's a pure tool, both left click and right click are its respective primary action. If it's both, however, left click is vandalizing and right click is carving. This tries to ensure the expected primary interaction is always left-click, without blocking anything if it could do both. We move the barcode scanner interaction to the barcode scanner instead. There's no good reason for this to stay on the book itself. We add `can_vandalize(...)` as a proc and move all checks in there, so we can call it after every tgui input. We don't replace the `to_chat(...)` calls here with balloon alerts because the additional clarifying info is needed, and it keeps the 'soulful' blind message. We add `get_attack_self_context(...)` as a proc for getting screentips on hovering over it in your active hand, because both the bible subtype and the syndicate bible _bible subtype_ want different screentips there in different situations, and so while it's clunky it's much less clunky than the alternatives I considered. Making it use actual storage datums avoids subtypes needing to make manual changes to it in the `carve_out(...)` proc, and is just good for organization. This doesn't add screentips to most bible-specific interactions, as I deemed them outside of the scope of this pr. Those are better off done atomized into another pr. ## Why It's Good For The Game less attackby, more item interaction screentips good I think having the carving interaction on combat mode is unintuitive, especially when that's the only interaction it can do. This ensures the expected primary interaction is always left-click. ## Changelog 🆑 refactor: Refactored the book interaction chain. Please report any issues. fix: You can no longer vandalize carved out books if you carve it after opening the input menu but before entering anything. qol: Added screentips to book interactions. qol: Added screentips to barcode scanner interactions. qol: Carving out books no longer uses combat mode, instead using left-click by default and right-click if your tool can also write. Screentips account for this. /🆑 --------- Co-authored-by: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com>
This commit is contained in:
committed by
Roxy
co-authored by
Ben10Omintrix
parent
e15937696f
commit
5d8e4f09ea
@@ -12,18 +12,77 @@
|
||||
///The current scanning mode (BARCODE_SCANNER_CHECKIN|BARCODE_SCANNER_INVENTORY)
|
||||
var/scan_mode = BARCODE_SCANNER_CHECKIN
|
||||
|
||||
/obj/item/barcodescanner/Initialize(mapload)
|
||||
. = ..()
|
||||
register_item_context()
|
||||
register_context()
|
||||
|
||||
/obj/item/barcodescanner/add_item_context(obj/item/source, list/context, atom/target, mob/living/user)
|
||||
if(!istype(target, /obj/item/book))
|
||||
return NONE
|
||||
|
||||
switch(scan_mode)
|
||||
if(BARCODE_SCANNER_CHECKIN)
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Check in"
|
||||
if(BARCODE_SCANNER_INVENTORY)
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Add to inventory"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
/obj/item/barcodescanner/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
|
||||
if(held_item == src)
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Toggle scanning mode"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
return NONE
|
||||
|
||||
/obj/item/barcodescanner/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers)
|
||||
if(istype(interacting_with, /obj/item/book))
|
||||
return interact_with_book(interacting_with, user)
|
||||
return NONE
|
||||
|
||||
/obj/item/barcodescanner/proc/interact_with_book(obj/item/book/target_book, mob/living/user)
|
||||
var/obj/machinery/computer/libraryconsole/bookmanagement/linked_computer = computer_ref?.resolve()
|
||||
if(isnull(linked_computer))
|
||||
user.balloon_alert(user, "not connected to computer!")
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
switch(scan_mode)
|
||||
if(BARCODE_SCANNER_CHECKIN)
|
||||
var/list/checkouts = linked_computer.checkouts
|
||||
for(var/checkout_ref in checkouts)
|
||||
var/datum/borrowbook/maybe_ours = checkouts[checkout_ref]
|
||||
if(!target_book.book_data.compare(maybe_ours.book_data))
|
||||
continue
|
||||
checkouts -= checkout_ref
|
||||
linked_computer.checkout_update()
|
||||
balloon_alert(user, "checked in")
|
||||
playsound(src, 'sound/items/barcodebeep.ogg', 20, FALSE)
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
user.balloon_alert(user, "isn't checked out!")
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
if(BARCODE_SCANNER_INVENTORY)
|
||||
var/datum/book_info/our_copy = target_book.book_data.return_copy()
|
||||
linked_computer.inventory[ref(our_copy)] = our_copy
|
||||
linked_computer.inventory_update()
|
||||
balloon_alert(user, "added to inventory")
|
||||
playsound(src, 'sound/items/barcodebeep.ogg', 20, FALSE)
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
return NONE
|
||||
|
||||
/obj/item/barcodescanner/attack_self(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(!computer_ref?.resolve())
|
||||
user.balloon_alert(user, "not connected to computer!")
|
||||
balloon_alert(user, "connect to computer!")
|
||||
return
|
||||
switch(scan_mode)
|
||||
if(BARCODE_SCANNER_CHECKIN)
|
||||
scan_mode = BARCODE_SCANNER_INVENTORY
|
||||
user.balloon_alert(user, "inventory adding mode")
|
||||
balloon_alert(user, "inventory adding mode")
|
||||
if(BARCODE_SCANNER_INVENTORY)
|
||||
scan_mode = BARCODE_SCANNER_CHECKIN
|
||||
user.balloon_alert(user, "check-in mode")
|
||||
balloon_alert(user, "check-in mode")
|
||||
playsound(loc, 'sound/items/click.ogg', 20, TRUE)
|
||||
|
||||
@@ -75,6 +75,8 @@ GLOBAL_LIST_INIT(bibleitemstates, list(
|
||||
righthand_file = 'icons/mob/inhands/items/books_righthand.dmi'
|
||||
force_string = "holy"
|
||||
unique = TRUE
|
||||
carved_storage_type = /datum/storage/carved_book/bible
|
||||
|
||||
/// Deity this bible is related to
|
||||
var/deity_name = "Space Jesus"
|
||||
|
||||
@@ -114,6 +116,10 @@ GLOBAL_LIST_INIT(bibleitemstates, list(
|
||||
else
|
||||
. += span_notice("[src] can be unpacked by hitting the floor of a holy area with it.")
|
||||
|
||||
/obj/item/book/bible/get_attack_self_context(mob/living/user)
|
||||
if(can_set_bible_skin(user))
|
||||
return "Select bible skin"
|
||||
|
||||
/obj/item/book/bible/proc/curse_heathen(datum/source, mob/living/user, obj/item/burning_tool)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
@@ -131,19 +137,20 @@ GLOBAL_LIST_INIT(bibleitemstates, list(
|
||||
to_chat(user, span_userdanger("[deity_name] cast a curse upon thee!"))
|
||||
user.AddComponent(/datum/component/omen/bible)
|
||||
|
||||
/obj/item/book/bible/carve_out(obj/item/carving_item, mob/living/user)
|
||||
. = ..()
|
||||
atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL
|
||||
|
||||
/obj/item/book/bible/suicide_act(mob/living/user)
|
||||
user.visible_message(span_suicide("[user] is offering [user.p_them()]self to [deity_name]! It looks like [user.p_theyre()] trying to commit suicide!"))
|
||||
return BRUTELOSS
|
||||
|
||||
/obj/item/book/bible/attack_self(mob/living/carbon/human/user)
|
||||
/obj/item/book/bible/proc/can_set_bible_skin(mob/living/user)
|
||||
if(GLOB.bible_icon_state)
|
||||
return FALSE
|
||||
if(user?.mind?.holy_role != HOLY_ROLE_HIGHPRIEST)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/obj/item/book/bible/attack_self(mob/living/carbon/human/user)
|
||||
if(!can_set_bible_skin(user))
|
||||
return FALSE
|
||||
|
||||
var/list/skins = list()
|
||||
for(var/i in 1 to GLOB.biblestates.len)
|
||||
@@ -183,13 +190,11 @@ GLOBAL_LIST_INIT(bibleitemstates, list(
|
||||
* * user The mob interacting with the menu
|
||||
*/
|
||||
/obj/item/book/bible/proc/check_menu(mob/living/carbon/human/user)
|
||||
if(GLOB.bible_icon_state)
|
||||
return FALSE
|
||||
if(!istype(user) || !user.is_holding(src))
|
||||
return FALSE
|
||||
if(user.incapacitated)
|
||||
return FALSE
|
||||
if(user.mind?.holy_role != HOLY_ROLE_HIGHPRIEST)
|
||||
if(!can_set_bible_skin(user))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -384,6 +389,10 @@ GLOBAL_LIST_INIT(bibleitemstates, list(
|
||||
if(owner_name)
|
||||
. += span_warning("The name [owner_name] is written in blood inside the cover.")
|
||||
|
||||
/obj/item/book/bible/syndicate/get_attack_self_context(mob/living/user)
|
||||
if(uses)
|
||||
return "Read"
|
||||
|
||||
/obj/item/book/bible/syndicate/attack(mob/living/target_mob, mob/living/carbon/human/user, params, heal_mode = TRUE)
|
||||
if(!user.combat_mode)
|
||||
return ..()
|
||||
|
||||
+149
-105
@@ -18,8 +18,10 @@
|
||||
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
|
||||
/// Whether or not we have been carved out.
|
||||
var/carved = FALSE
|
||||
/// The typepath for the storage datum we use when carved out.
|
||||
var/carved_storage_type = /datum/storage/carved_book
|
||||
|
||||
/// The initial title, for use in var editing and such
|
||||
var/starting_title
|
||||
@@ -36,12 +38,39 @@
|
||||
|
||||
AddElement(/datum/element/falling_hazard, damage = 5, wound_bonus = 0, hardhat_safety = TRUE, crushes = FALSE, impact_sound = drop_sound)
|
||||
AddElement(/datum/element/burn_on_item_ignition)
|
||||
register_context()
|
||||
|
||||
/obj/item/book/examine(mob/user)
|
||||
. = ..()
|
||||
if(carved)
|
||||
. += span_notice("[src] has been hollowed out.")
|
||||
|
||||
/obj/item/book/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
|
||||
if(isnull(held_item))
|
||||
return NONE
|
||||
|
||||
if(held_item == src)
|
||||
var/attack_self_context = get_attack_self_context(user)
|
||||
if(!attack_self_context)
|
||||
return NONE
|
||||
context[SCREENTIP_CONTEXT_LMB] = attack_self_context
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
if(IS_WRITING_UTENSIL(held_item))
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Vandalize"
|
||||
if(is_carving_tool(held_item))
|
||||
context[SCREENTIP_CONTEXT_RMB] = "Carve out"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
|
||||
if(is_carving_tool(held_item))
|
||||
context[SCREENTIP_CONTEXT_LMB] = "Carve out"
|
||||
return CONTEXTUAL_SCREENTIP_SET
|
||||
return NONE
|
||||
|
||||
/// Gets the context to add for clicking the book inhand. Returns null if none.
|
||||
/obj/item/book/proc/get_attack_self_context(mob/living/user)
|
||||
return "Read"
|
||||
|
||||
/obj/item/book/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
data["author"] = book_data.get_author()
|
||||
@@ -98,116 +127,131 @@
|
||||
user.visible_message(span_notice("[user] opens a book titled \"[book_data.title]\" and begins reading intently."))
|
||||
display_content(user)
|
||||
|
||||
/obj/item/book/attackby(obj/item/attacking_item, mob/living/user, list/modifiers, list/attack_modifiers)
|
||||
if(IS_WRITING_UTENSIL(attacking_item))
|
||||
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
|
||||
/obj/item/book/proc/is_carving_tool(obj/item/tool)
|
||||
PRIVATE_PROC(TRUE)
|
||||
if(tool.get_sharpness() & SHARP_EDGED)
|
||||
return TRUE
|
||||
if(tool.tool_behaviour == TOOL_WIRECUTTER)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
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
|
||||
playsound(src, SFX_WRITING_PEN, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, SOUND_FALLOFF_EXPONENT + 3, ignore_walls = FALSE)
|
||||
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", max_length = MAX_PAPER_LENGTH, 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))
|
||||
playsound(src, SFX_WRITING_PEN, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, SOUND_FALLOFF_EXPONENT + 3, ignore_walls = FALSE)
|
||||
if("Author")
|
||||
var/author = tgui_input_text(user, "Write the author's name", "Author Name", max_length = MAX_NAME_LEN)
|
||||
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
|
||||
playsound(src, SFX_WRITING_PEN, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, SOUND_FALLOFF_EXPONENT + 3, ignore_walls = FALSE)
|
||||
/// Checks for whether we can vandalize this book, to ensure we still can after each input.
|
||||
/// Uses to_chat over balloon alerts to give more detailed information as to why.
|
||||
/obj/item/book/proc/can_vandalize(mob/living/user, obj/item/tool)
|
||||
if(!user.can_perform_action(src) || !user.can_write(tool))
|
||||
return FALSE
|
||||
if(user.is_blind())
|
||||
to_chat(user, span_warning("As you are trying to write on the book, you suddenly feel very stupid!"))
|
||||
return FALSE
|
||||
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 FALSE
|
||||
if(carved)
|
||||
to_chat(user, span_warning("The book has been carved out! There is nothing to be vandalized."))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
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
|
||||
/obj/item/book/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
|
||||
// Items can both be carving tools and writing utensils.
|
||||
// Because of this, we flip interaction priority on secondary.
|
||||
// This means pure writing utensils have writing as their primary action,
|
||||
// pure carving tools have carving as their primary action,
|
||||
// but items with both have primary write secondary carve.
|
||||
if(IS_WRITING_UTENSIL(tool))
|
||||
return writing_utensil_act(user, tool)
|
||||
if(is_carving_tool(tool))
|
||||
return carving_act(user, tool)
|
||||
return NONE
|
||||
|
||||
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")
|
||||
playsound(loc, 'sound/items/barcodebeep.ogg', 20, FALSE)
|
||||
return
|
||||
/obj/item/book/item_interaction_secondary(mob/living/user, obj/item/tool, list/modifiers)
|
||||
if(is_carving_tool(tool))
|
||||
return carving_act(user, tool)
|
||||
if(IS_WRITING_UTENSIL(tool))
|
||||
return writing_utensil_act(user, tool)
|
||||
return NONE
|
||||
|
||||
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")
|
||||
playsound(loc, 'sound/items/barcodebeep.ogg', 20, FALSE)
|
||||
/// Called when user clicks on the book with a writing utensil. Attempts to vandalize the book.
|
||||
/obj/item/book/proc/writing_utensil_act(mob/living/user, obj/item/tool)
|
||||
if(!can_vandalize(user, tool))
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
else if(try_carve(attacking_item, user, modifiers))
|
||||
return
|
||||
return ..()
|
||||
var/choice = tgui_input_list(usr, "What would you like to change?", "Book Alteration", list("Title", "Contents", "Author", "Cancel"))
|
||||
if(isnull(choice))
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
if(!can_vandalize(user, tool))
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
switch(choice)
|
||||
if("Title")
|
||||
return vandalize_title(user, tool)
|
||||
if("Contents")
|
||||
return vandalize_contents(user, tool)
|
||||
if("Author")
|
||||
return vandalize_author(user, tool)
|
||||
|
||||
return NONE
|
||||
|
||||
/obj/item/book/proc/vandalize_title(mob/living/user, obj/item/tool)
|
||||
var/newtitle = reject_bad_text(tgui_input_text(user, "Write a new title", "Book Title", max_length = 30))
|
||||
if(!newtitle)
|
||||
balloon_alert(user, "invalid input!")
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
if(length_char(newtitle) > 30)
|
||||
balloon_alert(user, "too long!")
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
if(!can_vandalize(user, tool))
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
name = newtitle
|
||||
book_data.set_title(html_decode(newtitle)) //Don't want to double encode here
|
||||
playsound(src, SFX_WRITING_PEN, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, SOUND_FALLOFF_EXPONENT + 3, ignore_walls = FALSE)
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/item/book/proc/vandalize_contents(mob/living/user, obj/item/tool)
|
||||
var/content = tgui_input_text(user, "Write your book's contents (HTML NOT allowed)", "Book Contents", max_length = MAX_PAPER_LENGTH, multiline = TRUE)
|
||||
if(!content)
|
||||
balloon_alert(user, "invalid input!")
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
if(!can_vandalize(user, tool))
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
book_data.set_content(html_decode(content))
|
||||
playsound(src, SFX_WRITING_PEN, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, SOUND_FALLOFF_EXPONENT + 3, ignore_walls = FALSE)
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/obj/item/book/proc/vandalize_author(mob/living/user, obj/item/tool)
|
||||
var/author = tgui_input_text(user, "Write the author's name", "Author Name", max_length = MAX_NAME_LEN)
|
||||
if(!author)
|
||||
balloon_alert(user, "invalid input!")
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
if(!can_vandalize(user, tool))
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
book_data.set_author(html_decode(author)) //Setting this encodes, don't want to double up
|
||||
playsound(src, SFX_WRITING_PEN, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, SOUND_FALLOFF_EXPONENT + 3, ignore_walls = FALSE)
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/// Called when user clicks on the book with a carving utensil. Attempts to carve the book.
|
||||
/obj/item/book/proc/carving_act(mob/living/user, obj/item/tool)
|
||||
if(carved)
|
||||
balloon_alert(user, "already carved!")
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
balloon_alert(user, "carving out...")
|
||||
if(!do_after(user, 3 SECONDS, target = src))
|
||||
balloon_alert(user, "interrupted!")
|
||||
return ITEM_INTERACT_BLOCKING
|
||||
|
||||
balloon_alert(user, "carved out")
|
||||
playsound(src, 'sound/effects/cloth_rip.ogg', vol = 75, vary = TRUE)
|
||||
carve_out()
|
||||
return ITEM_INTERACT_SUCCESS
|
||||
|
||||
/// Handles setting everything a carved book needs.
|
||||
/obj/item/book/proc/carve_out()
|
||||
carved = TRUE
|
||||
create_storage(storage_type = carved_storage_type)
|
||||
|
||||
/// 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, list/modifiers)
|
||||
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.get_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
|
||||
|
||||
Reference in New Issue
Block a user