diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 51fc6c54f6..e50c89c0ac 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -64,6 +64,8 @@ var/force_escaped = FALSE // Set by Into The Sunset command of the shuttle manipulator + var/list/learned_recipes //List of learned recipe TYPES. + /datum/mind/New(var/key) src.key = key soulOwner = src diff --git a/code/game/objects/items/granters.dm b/code/game/objects/items/granters.dm index 21f6961e5d..4d66cd09f7 100644 --- a/code/game/objects/items/granters.dm +++ b/code/game/objects/items/granters.dm @@ -1,4 +1,3 @@ - ///books that teach things (intrinsic actions like bar flinging, spells like fireball or smoke, or martial arts)/// /obj/item/book/granter @@ -13,19 +12,52 @@ /obj/item/book/granter/proc/turn_page(mob/user) playsound(user, pick('sound/effects/pageturn1.ogg','sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg'), 30, 1) if(do_after(user,50, user)) - to_chat(user, "[pick(remarks)]") + if(remarks.len) + to_chat(user, "[pick(remarks)]") + else + to_chat(user, "You keep reading...") return TRUE return FALSE /obj/item/book/granter/proc/recoil(mob/user) //nothing so some books can just return +/obj/item/book/granter/proc/already_known(mob/user) + return FALSE + +/obj/item/book/granter/proc/on_reading_start(mob/user) + to_chat(user, "You start reading [name]...") + +/obj/item/book/granter/proc/on_reading_stopped(mob/user) + to_chat(user, "You stop reading...") + +/obj/item/book/granter/proc/on_reading_finished(mob/user) + to_chat(user, "You finish reading [name]!") + /obj/item/book/granter/proc/onlearned(mob/user) used = TRUE + /obj/item/book/granter/attack_self(mob/user) - if(reading == TRUE) + if(reading) to_chat(user, "You're already reading this!") return FALSE + if(!user.can_read(src)) + return FALSE + if(already_known(user)) + return FALSE + if(used && oneuse) + recoil(user) + else + on_reading_start(user) + reading = TRUE + for(var/i=1, i<=pages_to_mastery, i++) + if(!turn_page(user)) + on_reading_stopped() + reading = FALSE + return + if(do_after(user,50, user)) + on_reading_finished(user) + reading = FALSE return TRUE ///ACTION BUTTONS/// @@ -34,58 +66,23 @@ var/granted_action var/actionname = "catching bugs" //might not seem needed but this makes it so you can safely name action buttons toggle this or that without it fucking up the granter, also caps -/obj/item/book/granter/action/attack_self(mob/user) - . = ..() - if(!.) - return +/obj/item/book/granter/action/already_known(mob/user) if(!granted_action) - return - var/datum/action/G = new granted_action + return TRUE for(var/datum/action/A in user.actions) - if(A.type == G.type) + if(A.type == granted_action) to_chat(user, "You already know all about [actionname].") - qdel(G) - return - if(used == TRUE && oneuse == TRUE) - recoil(user) - else - to_chat(user, "You start reading about [actionname]...") - reading = TRUE - for(var/i=1, i<=pages_to_mastery, i++) - if(!turn_page(user)) - to_chat(user, "You stop reading...") - reading = FALSE - qdel(G) - return - if(do_after(user,50, user)) - to_chat(user, "You feel like you've got a good handle on [actionname]!") - G.Grant(user) - reading = FALSE + return TRUE + return FALSE -/obj/item/book/granter/action/drink_fling - granted_action = /datum/action/innate/drink_fling - name = "Tapper: This One's For You" - desc = "A seminal work on the dying art of booze sliding." - icon_state = "barbook" - actionname = "drink flinging" - oneuse = FALSE - remarks = list("The trick is keeping a low center of gravity it seems...", "The viscosity of the liquid is important...", "Accounting for crosswinds... really?", "Drag coefficients of various popular drinking glasses...", "What the heck is laminar flow and why does it matter here?", "Greasing the bar seems like it'd be cheating...", "I don't think I'll be working with superfluids...") +/obj/item/book/granter/action/on_reading_start(mob/user) + to_chat(user, "You start reading about [actionname]...") -/datum/action/innate/drink_fling - name = "Drink Flinging" - desc = "Toggles your ability to satisfyingly throw glasses without spilling them." - button_icon_state = "drinkfling_off" - check_flags = 0 - -/datum/action/innate/drink_fling/Activate() - button_icon_state = "drinkfling_on" - active = TRUE - UpdateButtonIcon() - -/datum/action/innate/drink_fling/Deactivate() - button_icon_state = "drinkfling_off" - active = FALSE - UpdateButtonIcon() +/obj/item/book/granter/action/on_reading_finished(mob/user) + to_chat(user, "You feel like you've got a good handle on [actionname]!") + var/datum/action/G = new granted_action + G.Grant(user) + onlearned(user) /obj/item/book/granter/action/origami granted_action = /datum/action/innate/origami @@ -120,38 +117,28 @@ var/spell var/spellname = "conjure bugs" -/obj/item/book/granter/spell/attack_self(mob/user) - . = ..() - if(!.) - return +/obj/item/book/granter/spell/already_known(mob/user) if(!spell) - return - var/obj/effect/proc_holder/spell/S = new spell + return TRUE for(var/obj/effect/proc_holder/spell/knownspell in user.mind.spell_list) - if(knownspell.type == S.type) + if(knownspell.type == spell) if(user.mind) if(iswizard(user)) - to_chat(user,"You're already far more versed in this spell than this flimsy howto book can provide.") + to_chat(user,"You're already far more versed in this spell than this flimsy how-to book can provide.") else to_chat(user,"You've already read this one.") - return - if(used == TRUE && oneuse == TRUE) - recoil(user) - else - to_chat(user, "You start reading about casting [spellname]...") - reading = TRUE - for(var/i=1, i<=pages_to_mastery, i++) - if(!turn_page(user)) - to_chat(user, "You stop reading...") - reading = FALSE - qdel(S) - return - if(do_after(user,50, user)) - to_chat(user, "You feel like you've experienced enough to cast [spellname]!") - user.mind.AddSpell(S) - user.log_message("learned the spell [spellname] ([S])", LOG_ATTACK, color="orange") - onlearned(user) - reading = FALSE + return TRUE + return FALSE + +/obj/item/book/granter/spell/on_reading_start(mob/user) + to_chat(user, "You start reading about casting [spellname]...") + +/obj/item/book/granter/spell/on_reading_finished(mob/user) + to_chat(user, "You feel like you've experienced enough to cast [spellname]!") + var/obj/effect/proc_holder/spell/S = new spell + user.mind.AddSpell(S) + user.log_message("learned the spell [spellname] ([S])", LOG_ATTACK, color="orange") + onlearned(user) /obj/item/book/granter/spell/recoil(mob/user) user.visible_message("[src] glows in a black light!") @@ -194,9 +181,9 @@ ..() to_chat(user,"Your stomach rumbles...") if(user.nutrition) - user.nutrition = 200 + user.set_nutrition(200) if(user.nutrition <= 0) - user.nutrition = 0 + user.set_nutrition(0) /obj/item/book/granter/spell/blind spell = /obj/effect/proc_holder/spell/targeted/trigger/blind @@ -280,7 +267,8 @@ if(ishuman(user)) to_chat(user,"HORSIE HAS RISEN") var/obj/item/clothing/magichead = new /obj/item/clothing/mask/horsehead/cursed(user.drop_location()) - user.dropItemToGround(user.wear_mask, TRUE) + if(!user.dropItemToGround(user.wear_mask)) + qdel(user.wear_mask) user.equip_to_slot_if_possible(magichead, SLOT_WEAR_MASK, TRUE, TRUE) qdel(src) else @@ -327,35 +315,25 @@ var/martialname = "bug jitsu" var/greet = "You feel like you have mastered the art in breaking code. Nice work, jackass." -/obj/item/book/granter/martial/attack_self(mob/user) - . = ..() - if(!.) - return + +/obj/item/book/granter/martial/already_known(mob/user) if(!martial) - return + return TRUE + var/datum/martial_art/MA = martial + if(user.mind.has_martialart(initial(MA.id))) + to_chat(user,"You already know [martialname]!") + return TRUE + return FALSE + +/obj/item/book/granter/martial/on_reading_start(mob/user) + to_chat(user, "You start reading about [martialname]...") + +/obj/item/book/granter/martial/on_reading_finished(mob/user) + to_chat(user, "[greet]") var/datum/martial_art/MA = new martial - if(user.mind.martial_art) - for(var/datum/martial_art/knownmartial in user.mind.martial_art) - if(knownmartial.type == MA.type) - to_chat(user,"You already know [martialname]!") - return - if(used == TRUE && oneuse == TRUE) - recoil(user) - else - to_chat(user, "You start reading about [martialname]...") - reading = TRUE - for(var/i=1, i<=pages_to_mastery, i++) - if(!turn_page(user)) - to_chat(user, "You stop reading...") - reading = FALSE - qdel(MA) - return - if(do_after(user,50, user)) - to_chat(user, "[greet]") - MA.teach(user) - user.log_message("learned the martial art [martialname] ([MA])", LOG_ATTACK, color="orange") - onlearned(user) - reading = FALSE + MA.teach(user) + user.log_message("learned the martial art [martialname] ([MA])", LOG_ATTACK, color="orange") + onlearned(user) /obj/item/book/granter/martial/cqc martial = /datum/martial_art/cqc @@ -416,3 +394,18 @@ icon_state = "blankscroll" // I did not include mushpunch's grant, it is not a book and the item does it just fine. + + +//Crafting Recipe books + +/obj/item/book/granter/crafting_recipe + var/list/crafting_recipe_types = list() + +/obj/item/book/granter/crafting_recipe/on_reading_finished(mob/user) + . = ..() + if(!user.mind) + return + for(var/crafting_recipe_type in crafting_recipe_types) + var/datum/crafting_recipe/R = crafting_recipe_type + user.mind.teach_crafting_recipe(crafting_recipe_type) +to_chat(user,"You learned how to make [initial(R.name)].") \ No newline at end of file diff --git a/code/modules/crafting/craft.dm b/code/modules/crafting/craft.dm index 3e96512bb8..0fb46c3e46 100644 --- a/code/modules/crafting/craft.dm +++ b/code/modules/crafting/craft.dm @@ -317,6 +317,8 @@ var/list/cant_craft = list() for(var/rec in GLOB.crafting_recipes) var/datum/crafting_recipe/R = rec + if(!R.always_availible && !(R.type in user?.mind?.learned_recipes)) //User doesn't actually know how to make this. + continue if((R.category != cur_category) || (R.subcategory != cur_subcategory)) continue if(check_contents(R, surroundings)) @@ -431,3 +433,10 @@ data["tool_text"] = tool_text return data + +//Mind helpers + +/datum/mind/proc/teach_crafting_recipe(R) + if(!learned_recipes) + learned_recipes = list() + learned_recipes |= R \ No newline at end of file diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index f0665682a9..3c614c6a9e 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -9,6 +9,7 @@ var/chem_catalysts[] = list() //like tools but for reagents var/category = CAT_NONE //where it shows up in the crafting UI var/subcategory = CAT_NONE + var/always_availible = TRUE //Set to FALSE if it needs to be learned first. /datum/crafting_recipe/pin_removal name = "Pin Removal"