diff --git a/code/__DEFINES/melee.dm b/code/__DEFINES/melee.dm new file mode 100644 index 0000000000..cb4a433211 --- /dev/null +++ b/code/__DEFINES/melee.dm @@ -0,0 +1,10 @@ +//Martial arts defines + +#define MARTIALART_BOXING "boxing" +#define MARTIALART_WRESTLING "wrestling" +#define MARTIALART_SLEEPINGCARP "sleeping carp" +#define MARTIALART_PSYCHOBRAWL "psychotic brawling" +#define MARTIALART_MUSHPUNCH "mushroom punch" +#define MARTIALART_KRAVMAGA "krav maga" +#define MARTIALART_CQC "CQC" +#define MARTIALART_PLASMAFIST "plasma fist" \ No newline at end of file diff --git a/code/datums/martial.dm b/code/datums/martial.dm index ae8f92a342..d119759efc 100644 --- a/code/datums/martial.dm +++ b/code/datums/martial.dm @@ -2,6 +2,7 @@ var/name = "Martial Art" var/streak = "" var/max_streak_length = 6 + var/id = "" //ID, used by mind/has_martialartcode\game\objects\items\granters.dm:345:error: user.mind.has_martialart: undefined proccode\game\objects\items\granters.dm:345:error: user.mind.has_martialart: undefined proccode\game\objects\items\granters.dm:345:error: user.mind.has_martialart: undefined proccode\game\objects\items\granters.dm:345:error: user.mind.has_martialart: undefined proccode\game\objects\items\granters.dm:345:error: user.mind.has_martialart: undefined proc var/current_target var/datum/martial_art/base // The permanent style. This will be null unless the martial art is temporary var/deflection_chance = 0 //Chance to deflect projectiles diff --git a/code/datums/martial/boxing.dm b/code/datums/martial/boxing.dm index c93fc47f2b..7399528e1c 100644 --- a/code/datums/martial/boxing.dm +++ b/code/datums/martial/boxing.dm @@ -1,5 +1,6 @@ /datum/martial_art/boxing name = "Boxing" + id = MARTIALART_BOXING /datum/martial_art/boxing/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) to_chat(A, "Can't disarm while boxing!") diff --git a/code/datums/martial/cqc.dm b/code/datums/martial/cqc.dm index 55cd4a3f7a..71545476ff 100644 --- a/code/datums/martial/cqc.dm +++ b/code/datums/martial/cqc.dm @@ -6,6 +6,7 @@ /datum/martial_art/cqc name = "CQC" + id = MARTIALART_CQC help_verb = /mob/living/carbon/human/proc/CQC_help block_chance = 75 var/just_a_cook = FALSE diff --git a/code/datums/martial/krav_maga.dm b/code/datums/martial/krav_maga.dm index 2a2e69bea5..9e40a5a3dc 100644 --- a/code/datums/martial/krav_maga.dm +++ b/code/datums/martial/krav_maga.dm @@ -1,5 +1,6 @@ /datum/martial_art/krav_maga name = "Krav Maga" + id = MARTIALART_KRAVMAGA var/datum/action/neck_chop/neckchop = new/datum/action/neck_chop() var/datum/action/leg_sweep/legsweep = new/datum/action/leg_sweep() var/datum/action/lung_punch/lungpunch = new/datum/action/lung_punch() diff --git a/code/datums/martial/mushpunch.dm b/code/datums/martial/mushpunch.dm index 33d5bb51bf..1ef7734771 100644 --- a/code/datums/martial/mushpunch.dm +++ b/code/datums/martial/mushpunch.dm @@ -1,5 +1,6 @@ /datum/martial_art/mushpunch name = "Mushroom Punch" + id = MARTIALART_MUSHPUNCH /datum/martial_art/mushpunch/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) var/atk_verb diff --git a/code/datums/martial/plasma_fist.dm b/code/datums/martial/plasma_fist.dm index f540dc0783..e38a011db0 100644 --- a/code/datums/martial/plasma_fist.dm +++ b/code/datums/martial/plasma_fist.dm @@ -4,6 +4,7 @@ /datum/martial_art/plasma_fist name = "Plasma Fist" + id = MARTIALART_PLASMAFIST help_verb = /mob/living/carbon/human/proc/plasma_fist_help diff --git a/code/datums/martial/psychotic_brawl.dm b/code/datums/martial/psychotic_brawl.dm index 1cb18f903f..8f1a33a8b3 100644 --- a/code/datums/martial/psychotic_brawl.dm +++ b/code/datums/martial/psychotic_brawl.dm @@ -1,5 +1,6 @@ /datum/martial_art/psychotic_brawling name = "Psychotic Brawling" + id = MARTIALART_PSYCHOBRAWL /datum/martial_art/psychotic_brawling/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D) return psycho_attack(A,D) diff --git a/code/datums/martial/sleeping_carp.dm b/code/datums/martial/sleeping_carp.dm index 5f19c37b99..e205d7a435 100644 --- a/code/datums/martial/sleeping_carp.dm +++ b/code/datums/martial/sleeping_carp.dm @@ -6,6 +6,7 @@ /datum/martial_art/the_sleeping_carp name = "The Sleeping Carp" + id = MARTIALART_SLEEPINGCARP deflection_chance = 100 reroute_deflection = TRUE no_guns = TRUE diff --git a/code/datums/martial/wrestling.dm b/code/datums/martial/wrestling.dm index e57edf9fb2..e07fa27ef5 100644 --- a/code/datums/martial/wrestling.dm +++ b/code/datums/martial/wrestling.dm @@ -10,6 +10,7 @@ /datum/martial_art/wrestling name = "Wrestling" + id = MARTIALART_WRESTLING var/datum/action/slam/slam = new/datum/action/slam() var/datum/action/throw_wrassle/throw_wrassle = new/datum/action/throw_wrassle() var/datum/action/kick/kick = new/datum/action/kick() diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 51fc6c54f6..8e61801e15 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 @@ -779,6 +781,11 @@ mind_initialize() //updates the mind (or creates and initializes one if one doesn't exist) mind.active = 1 //indicates that the mind is currently synced with a client +/datum/mind/proc/has_martialart(var/string) + if(martial_art && martial_art.id == string) + return martial_art + return FALSE + /mob/dead/new_player/sync_mind() return diff --git a/code/game/objects/items/granters.dm b/code/game/objects/items/granters.dm index 21f6961e5d..686c6fd511 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,50 @@ /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(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,33 +64,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/on_reading_start(mob/user) + to_chat(user, "You start reading about [actionname]...") + +/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/drink_fling granted_action = /datum/action/innate/drink_fling @@ -120,38 +140,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!") @@ -280,7 +290,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 +338,24 @@ 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 +416,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/game/objects/items/implants/implant_krav_maga.dm b/code/game/objects/items/implants/implant_krav_maga.dm index 3a751ecd0e..373658b386 100644 --- a/code/game/objects/items/implants/implant_krav_maga.dm +++ b/code/game/objects/items/implants/implant_krav_maga.dm @@ -21,7 +21,7 @@ return if(!H.mind) return - if(istype(H.mind.martial_art, /datum/martial_art/krav_maga)) + if(H.mind.has_martialart(MARTIALART_KRAVMAGA)) style.remove(H) else style.teach(H,1) 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" diff --git a/tgstation.dme b/tgstation.dme index 24477d885b..7e7b5a00c9 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -62,6 +62,7 @@ #include "code\__DEFINES\maths.dm" #include "code\__DEFINES\MC.dm" #include "code\__DEFINES\medal.dm" +#include "code\__DEFINES\melee.dm" #include "code\__DEFINES\menu.dm" #include "code\__DEFINES\misc.dm" #include "code\__DEFINES\mobs.dm"