From f3fbda739ffcacb1071358c3f0f73299788085ba Mon Sep 17 00:00:00 2001 From: MistakeNot4892 <AGMogett@gmail.com> Date: Sun, 8 May 2022 16:37:58 +1000 Subject: [PATCH] Refactoring skill book use to allow for adjacent reading. --- code/game/objects/items/books/skill_book.dm | 154 ++++++++++++++------ 1 file changed, 109 insertions(+), 45 deletions(-) diff --git a/code/game/objects/items/books/skill_book.dm b/code/game/objects/items/books/skill_book.dm index 3908408902..4923de1152 100644 --- a/code/game/objects/items/books/skill_book.dm +++ b/code/game/objects/items/books/skill_book.dm @@ -38,16 +38,16 @@ Skill books that increase your skills while you activate and hold them author = "The Oracle of Bakersroof" icon_state = "book2" force = 4 - w_class = ITEM_SIZE_LARGE //Skill books are THICC with knowledge. Up one level from regular books to prevent library-in-a-bag silliness. + w_class = ITEM_SIZE_LARGE // Skill books are THICC with knowledge. Up one level from regular books to prevent library-in-a-bag silliness. unique = TRUE material = /decl/material/solid/plastic matter = list(/decl/material/solid/wood = MATTER_AMOUNT_REINFORCEMENT) - var/decl/hierarchy/skill/skill // e.g. SKILL_LITERACY - var/skill_req = SKILL_NONE //The level the user needs in the skill to benefit from the book, e.g. SKILL_PROF - var/reading = FALSE //Tto check if the book is actively being used - var/custom = FALSE //To bypass init stuff, for player made textbooks and weird books. If true must have details manually set - var/ez_read = FALSE //Set to TRUE if you can read it without basic literacy skills + var/decl/hierarchy/skill/skill // e.g. SKILL_LITERACY + var/skill_req = SKILL_NONE // The level the user needs in the skill to benefit from the book, e.g. SKILL_PROF + var/weakref/reading // To check if the book is actively being used + var/custom = FALSE // To bypass init stuff, for player made textbooks and weird books. If true must have details manually set + var/ez_read = FALSE // Set to TRUE if you can read it without basic literacy skills var/skill_name = "missing skill name" var/progress = SKILLBOOK_PROG_FINISH // used to track the progress of making a custom book. defaults as finished so, you know, you can read the damn thing @@ -56,6 +56,8 @@ Skill books that increase your skills while you activate and hold them . = ..() + global.events_repository.register(/decl/observ/moved, src, src, .proc/check_buff) + if(!custom && skill && skill_req)// custom books should already have all they need skill_name = initial(skill.name) title = RANDOM_BOOK_TITLE(capitalize(skill_name)) @@ -82,44 +84,95 @@ Skill books that increase your skills while you activate and hold them /datum/skill_buff/skill_book limit = 1 // you can only read one book at a time nerd, therefore you can only get one buff at a time -/obj/item/book/skill/attack_self(mob/user) +/obj/item/book/skill/get_single_monetary_worth() + . = max(..(), 200) + (100 * skill_req) + +/obj/item/book/skill/proc/check_can_read(mob/user) + if(QDELETED(user)) + return FALSE + var/effective_title = length(title) ? title : "the textbook" + if(!CanPhysicallyInteract(user)) + to_chat(user, SPAN_WARNING("You can't reach [effective_title]!")) + return FALSE if(!skill || (custom && progress == SKILLBOOK_PROG_NONE)) - to_chat(user, SPAN_WARNING("The textbook is blank!")) - return + to_chat(user, SPAN_WARNING("[capitalize(effective_title)] is blank!")) + return FALSE if(custom && progress < SKILLBOOK_PROG_FINISH) - to_chat(user, SPAN_WARNING("The textbook is unfinished! You can't learn from it in this state!")) - return + to_chat(user, SPAN_WARNING("[capitalize(effective_title)] is unfinished! You can't learn from it in this state!")) + return FALSE if(!ez_read &&!user.skill_check(SKILL_LITERACY, SKILL_BASIC)) - to_chat(user, SPAN_WARNING(pick("Haha, you know you can't read. Good joke. Put [title] back.","You open up [title], but there aren't any pictures, so you close it again.","You don't know how to read! What good is this [name] to you?!"))) - return + to_chat(user, SPAN_WARNING(pick(list( + "Haha, you know you can't read. Good joke. Put [effective_title] back.", + "You open up [effective_title], but there aren't any pictures, so you close it again.", + "You don't know how to read! What good is [effective_title] to you?!" + )))) + return FALSE - if(reading) //Close book, get rid of buffs - src.unlearn(user) - to_chat(user, SPAN_NOTICE("You close the [name]. That's enough learning for now.")) - reading = FALSE - return + if(reading) + if(reading.resolve() != user) + to_chat(user, SPAN_WARNING("\The [reading.resolve()] is already reading [effective_title]!")) + else + to_chat(user, SPAN_WARNING("You are already reading [effective_title]!")) + return FALSE if(user.too_many_buffs(/datum/skill_buff/skill_book)) to_chat(user, SPAN_WARNING("You can't read two books at once!")) - return + return FALSE if(!user.skill_check(skill, skill_req)) - to_chat(user, SPAN_WARNING("[title] is too advanced for you! Try something easier, perhaps the \"For Idiots\" edition?")) - return + to_chat(user, SPAN_WARNING("[capitalize(title)] is too advanced for you! Try something easier, perhaps the \"For Idiots\" edition?")) + return FALSE + if(user.get_skill_value(skill) > skill_req) - to_chat(user, SPAN_WARNING("You already know everything [title] has to teach you!")) - return + to_chat(user, SPAN_WARNING("You already know everything [effective_title] has to teach you!")) + return FALSE - to_chat(user, SPAN_NOTICE("You open up the [name] and start reading...")) - if(user.do_skilled(4 SECONDS, SKILL_LITERACY, src, 0.75)) - var/list/buff = list() - buff[skill] = 1 - user.buff_skill(buff, buff_type = /datum/skill_buff/skill_book) - reading = TRUE - to_chat(user, SPAN_NOTICE("You find the information you need! Better keep the page open to reference it.")) - else - to_chat(user, SPAN_DANGER("Your perusal of the [name] was interrupted!")) - return + return TRUE + +/obj/item/book/skill/attack_self(mob/user) + return try_to_read(user) || ..() + +/obj/item/book/skill/verb/read_book() + set name = "Read Book" + set category = "Object" + set src in view(1) + try_to_read(usr) + +/obj/item/book/skill/proc/try_to_read(mob/user) + + if(istype(user, /mob/observer)) + to_chat(user, SPAN_WARNING("Ghosts can't read! Go away!")) + return TRUE + + if(isturf(loc)) + user.face_atom(src) + + if(user && user == reading?.resolve()) + //Close book, get rid of buffs + unlearn(user) + to_chat(user, SPAN_NOTICE("You close [title]. That's enough learning for now.")) + reading = null + STOP_PROCESSING(SSprocessing, src) + return TRUE + + if(!check_can_read(user)) + return FALSE + + to_chat(user, SPAN_NOTICE("You open up [title] and start reading...")) + if(!user.do_skilled(4 SECONDS, SKILL_LITERACY, src, 0.75)) + to_chat(user, SPAN_DANGER("Your perusal of [title] was interrupted!")) + return TRUE + + if(!check_can_read(user)) + return TRUE + + var/list/buff = list() + buff[skill] = 1 + user.buff_skill(buff, buff_type = /datum/skill_buff/skill_book) + reading = weakref(user) + to_chat(user, SPAN_NOTICE("You find the information you need! Better keep the page open to reference it.")) + START_PROCESSING(SSprocessing, src) + return TRUE // buff removal /obj/item/book/skill/proc/unlearn(var/mob/user) @@ -127,19 +180,30 @@ Skill books that increase your skills while you activate and hold them for(var/datum/skill_buff/skill_book/S in F) S.remove() -// Remove buffs when book goes away -/obj/item/book/skill/dropped(mob/user) - if(reading) - to_chat(user, SPAN_DANGER("You lose the page you were on! You can't cross-reference using the [name] like this!")) - var/mob/M = user - if(istype(M) && M.fetch_buffs_of_type(/datum/skill_buff/skill_book, 0)) - src.unlearn(user) - reading = FALSE - . = ..() +/obj/item/book/skill/Process() + if(!reading) + return PROCESS_KILL + check_buff() + +/obj/item/book/skill/proc/check_buff() + if(!reading) + return + var/mob/R = reading.resolve() + if(!istype(R) || !CanPhysicallyInteract(R)) + remove_buff() + +/obj/item/book/skill/proc/remove_buff() + var/mob/R = reading?.resolve() + reading = null + if(istype(R)) + to_chat(R, SPAN_DANGER("You lose the page you were on! You can't cross-reference using [title] like this!")) + if(R.fetch_buffs_of_type(/datum/skill_buff/skill_book, 0)) + unlearn(R) + STOP_PROCESSING(SSprocessing, src) + /obj/item/book/skill/Destroy() - var/mob/M = loc - if(istype(M) && M.fetch_buffs_of_type(/datum/skill_buff/skill_book, 0)) - src.unlearn(M) + global.events_repository.unregister(/decl/observ/moved, src, src) + remove_buff() . = ..() /obj/item/book/skill/get_codex_value()