diff --git a/code/__DEFINES/botany.dm b/code/__DEFINES/botany.dm index d1c41e94f95..cedc7ac66e7 100644 --- a/code/__DEFINES/botany.dm +++ b/code/__DEFINES/botany.dm @@ -33,12 +33,6 @@ /// Minumum plant health required for gene shears. #define GENE_SHEAR_MIN_HEALTH 15 -/// -- Plant analyzer scanning modes. -- -/// Stats mode - displays a plant's growth statistics (potency, yield, traits, etc.). -#define PLANT_SCANMODE_STATS 0 -/// Chemical mode - displays a plant's reagents (either reagent genes or chemical contents). -#define PLANT_SCANMODE_CHEMICALS 1 - /// -- Flags for seeds. -- /// Allows a plant to wild mutate (mutate on haravest) at a certain instability. #define MUTATE_EARLY (1<<0) diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 33b412a8ded..c7005d73f92 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -39,7 +39,7 @@ attackby_result = target.attackby(src, user, params) if (SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) return TRUE - if (SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + if (SECONDARY_ATTACK_CONTINUE_CHAIN) // Normal behavior else CRASH("attackby_secondary must return an SECONDARY_ATTACK_* define, please consult code/__DEFINES/combat.dm") diff --git a/code/game/objects/effects/glowshroom.dm b/code/game/objects/effects/glowshroom.dm index 76a9360f91f..beb6ee94fed 100644 --- a/code/game/objects/effects/glowshroom.dm +++ b/code/game/objects/effects/glowshroom.dm @@ -250,11 +250,3 @@ I.desc = "Looks like this was \an [src] some time ago." qdel(src) return TRUE - -/obj/structure/glowshroom/attackby(obj/item/I, mob/living/user, params) - if (istype(I, /obj/item/plant_analyzer)) - var/obj/item/plant_analyzer/plant_analyzer = I - to_chat(user, plant_analyzer.scan_plant(myseed)) - return - - return ..() // Attack normally diff --git a/code/modules/hydroponics/grafts.dm b/code/modules/hydroponics/grafts.dm index 527f9d04d9d..f6da90053c0 100644 --- a/code/modules/hydroponics/grafts.dm +++ b/code/modules/hydroponics/grafts.dm @@ -48,9 +48,3 @@ /obj/item/graft/Destroy() QDEL_NULL(stored_trait) return ..() - -/obj/item/graft/attackby(obj/item/I, mob/living/user, params) - if(istype(I, /obj/item/plant_analyzer) && !user.combat_mode) - var/obj/item/plant_analyzer/plant_analyzer = I - to_chat(user, plant_analyzer.get_graft_text(src)) - return ..() diff --git a/code/modules/hydroponics/grown.dm b/code/modules/hydroponics/grown.dm index e69969de0fd..f5874059f2f 100644 --- a/code/modules/hydroponics/grown.dm +++ b/code/modules/hydroponics/grown.dm @@ -70,12 +70,6 @@ /obj/item/food/grown/proc/make_dryable() AddElement(/datum/element/dryable, type) -/obj/item/food/grown/attackby(obj/item/O, mob/user, params) - ..() - if (istype(O, /obj/item/plant_analyzer)) - var/obj/item/plant_analyzer/plant_analyzer = O - to_chat(user, plant_analyzer.scan_plant(src)) - /obj/item/food/grown/MakeLeaveTrash() if(trash_type) AddElement(/datum/element/food_trash, trash_type, FOOD_TRASH_OPENABLE, /obj/item/food/grown/.proc/generate_trash) diff --git a/code/modules/hydroponics/growninedible.dm b/code/modules/hydroponics/growninedible.dm index 62baeb2a3d1..fa384fb82d4 100644 --- a/code/modules/hydroponics/growninedible.dm +++ b/code/modules/hydroponics/growninedible.dm @@ -32,13 +32,6 @@ transform *= TRANSFORM_USING_VARIABLE(seed.potency, 100) + 0.5 add_juice() -/obj/item/grown/attackby(obj/item/O, mob/user, params) - ..() - if (istype(O, /obj/item/plant_analyzer)) - var/obj/item/plant_analyzer/plant_analyzer = O - to_chat(user, plant_analyzer.scan_plant(src)) - return - /obj/item/grown/proc/add_juice() if(reagents) return TRUE diff --git a/code/modules/hydroponics/hydroitemdefines.dm b/code/modules/hydroponics/hydroitemdefines.dm index 7ce96cd6198..40ee8e067c0 100644 --- a/code/modules/hydroponics/hydroitemdefines.dm +++ b/code/modules/hydroponics/hydroitemdefines.dm @@ -1,4 +1,3 @@ - // Plant analyzer /obj/item/plant_analyzer name = "plant analyzer" @@ -12,86 +11,213 @@ w_class = WEIGHT_CLASS_TINY slot_flags = ITEM_SLOT_BELT custom_materials = list(/datum/material/iron=30, /datum/material/glass=20) - var/scan_mode = PLANT_SCANMODE_STATS /obj/item/plant_analyzer/examine() . = ..() - . += "Activate it in your hand to change \the [src] between a growth statistics mode and a chemical reagents mode." + . += "Left click a plant to scan its growth stats, and right click to scan its chemical reagent stats." -/obj/item/plant_analyzer/attack_self(mob/user) +/// When we attack something, first - try to scan something we hit with left click. Left-clicking uses scans for stats +/obj/item/plant_analyzer/pre_attack(atom/target, mob/living/user) . = ..() - scan_mode = !scan_mode - to_chat(user, "You switch [src] to [scan_mode == PLANT_SCANMODE_CHEMICALS ? "scan for chemical reagents and traits" : "scan for plant growth statistics"].") - -/obj/item/plant_analyzer/attack(mob/living/M, mob/living/carbon/human/user) - //Checks if target is a podman - if(ispodperson(M)) - user.visible_message("[user] analyzes [M]'s vitals.", \ - "You analyze [M]'s vitals.") - if(scan_mode == PLANT_SCANMODE_STATS) - healthscan(user, M, advanced = TRUE) - else - chemscan(user, M) - add_fingerprint(user) + if(user.combat_mode) return - return ..() + + return do_plant_stats_scan(target, user) + +/// Same as above, but with right click. Right-clicking scans for chemicals. +/obj/item/plant_analyzer/pre_attack_secondary(atom/target, mob/living/user) + if(user.combat_mode) + return SECONDARY_ATTACK_CONTINUE_CHAIN + + return do_plant_chem_scan(target, user) ? SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN : SECONDARY_ATTACK_CONTINUE_CHAIN + +/* + * Scan the target on plant scan mode. This prints traits and stats to the user. + * + * scan_target - the atom we're scanning + * user - the user doing the scanning. + * + * returns FALSE if it's not an object or item that does something when we scan it. + * returns TRUE if we can scan the object, and outputs the message to the USER. + */ +/obj/item/plant_analyzer/proc/do_plant_stats_scan(atom/scan_target, mob/user) + if(istype(scan_target, /obj/machinery/hydroponics)) + to_chat(user, scan_tray_stats(scan_target)) + return TRUE + if(istype(scan_target, /obj/structure/glowshroom)) + var/obj/structure/glowshroom/shroom_plant = scan_target + to_chat(user, scan_plant_stats(shroom_plant.myseed)) + return TRUE + if(istype(scan_target, /obj/item/graft)) + to_chat(user, get_graft_text(scan_target)) + return TRUE + if(isitem(scan_target)) + var/obj/item/scanned_object = scan_target + if(scanned_object.get_plant_seed() || istype(scanned_object, /obj/item/seeds)) + to_chat(user, scan_plant_stats(scanned_object)) + return TRUE + if(ispodperson(scan_target)) + pod_person_health_scan(scan_target, user) + return TRUE + + return FALSE + +/* + * Scan the target on chemical scan mode. This prints chemical genes and reagents to the user. + * + * scan_target - the atom we're scanning + * user - the user doing the scanning. + * + * returns FALSE if it's not an object or item that does something when we scan it. + * returns TRUE if we can scan the object, and outputs the message to the USER. + */ +/obj/item/plant_analyzer/proc/do_plant_chem_scan(atom/scan_target, mob/user) + if(istype(scan_target, /obj/machinery/hydroponics)) + to_chat(user, scan_tray_chems(scan_target)) + return TRUE + if(istype(scan_target, /obj/structure/glowshroom)) + var/obj/structure/glowshroom/shroom_plant = scan_target + to_chat(user, scan_plant_chems(shroom_plant.myseed)) + return TRUE + if(istype(scan_target, /obj/item/graft)) + to_chat(user, get_graft_text(scan_target)) + return TRUE + if(isitem(scan_target)) + var/obj/item/scanned_object = scan_target + if(scanned_object.get_plant_seed() || istype(scanned_object, /obj/item/seeds)) + to_chat(user, scan_plant_chems(scanned_object)) + return TRUE + if(ispodperson(scan_target)) + pod_person_chem_scan(scan_target, user) + return TRUE + + return FALSE + +/* + * Scan a podperson's health with the plant analyzer. No wound scanning, though. + * + * scanned_mob - the podperson being scanned + * user - the person doing the scanning + */ +/obj/item/plant_analyzer/proc/pod_person_health_scan(mob/living/carbon/human/scanned_mob, mob/living/carbon/human/user) + user.visible_message("[user] analyzes [scanned_mob]'s vitals.", \ + "You analyze [scanned_mob]'s vitals.") + + healthscan(user, scanned_mob, advanced = TRUE) + add_fingerprint(user) + +/* + * Scan a podperson's chemical contents with the plant analyzer. + * + * scanned_mob - the podperson being scanned + * user - the person doing the scanning + */ +/obj/item/plant_analyzer/proc/pod_person_chem_scan(mob/living/carbon/human/scanned_mob, mob/living/carbon/human/user) + user.visible_message("[user] analyzes [scanned_mob]'s bloodstream.", \ + "You analyze [scanned_mob]'s bloodstream.") + chemscan(user, scanned_mob) + add_fingerprint(user) /** - * This proc is called when we scan a hydroponics tray or soil. + * This proc is called when we scan a hydroponics tray or soil on left click (stats mode) * It formats the plant name, it's age, the plant's stats, and the tray's stats. * * - scanned_tray - the tray or soil we are scanning. * * Returns the formatted message as text. */ -/obj/item/plant_analyzer/proc/scan_tray(obj/machinery/hydroponics/scanned_tray) +/obj/item/plant_analyzer/proc/scan_tray_stats(obj/machinery/hydroponics/scanned_tray) var/returned_message = "*---------*\n" if(scanned_tray.myseed) returned_message += "*** [scanned_tray.myseed.plantname] ***\n" returned_message += "- Plant Age: [scanned_tray.age]\n" - returned_message += scan_plant(scanned_tray.myseed) + returned_message += scan_plant_stats(scanned_tray.myseed) else returned_message += "No plant found.\n" - returned_message += "- Weed level: [scanned_tray.weedlevel] / [MAX_TRAY_WEEDS]\n" + returned_message += "" + returned_message += "- Weed level: [scanned_tray.weedlevel] / [MAX_TRAY_WEEDS]\n" returned_message += "- Pest level: [scanned_tray.pestlevel] / [MAX_TRAY_PESTS]\n" returned_message += "- Toxicity level: [scanned_tray.toxic] / [MAX_TRAY_TOXINS]\n" returned_message += "- Water level: [scanned_tray.waterlevel] / [scanned_tray.maxwater]\n" returned_message += "- Nutrition level: [scanned_tray.reagents.total_volume] / [scanned_tray.maxnutri]\n" if(scanned_tray.yieldmod != 1) returned_message += "- Yield modifier on harvest: [scanned_tray.yieldmod]x\n" - returned_message += "*---------*" + returned_message += "*---------*" return returned_message /** - * This proc is called when a seed or any grown plant is scanned. - * It formats the plant name as well as either its traits or its chemical contents. + * This proc is called when we scan a hydroponics tray or soil on right click (chemicals mode) + * It formats the plant name and age, as well as the plant's chemical genes and the tray's contents. + * + * - scanned_tray - the tray or soil we are scanning. + * + * Returns the formatted message as text. + */ +/obj/item/plant_analyzer/proc/scan_tray_chems(obj/machinery/hydroponics/scanned_tray) + var/returned_message = "*---------*\n" + if(scanned_tray.myseed) + returned_message += "*** [scanned_tray.myseed.plantname] ***\n" + returned_message += "- Plant Age: [scanned_tray.age]\n" + returned_message += scan_plant_chems(scanned_tray.myseed) + else + returned_message += "No plant found.\n" + + returned_message += "" + + returned_message += "- Tray contains:\n" + if(scanned_tray.reagents.reagent_list.len) + for(var/datum/reagent/reagent_id in scanned_tray.reagents.reagent_list) + returned_message += "- [reagent_id.volume] / [scanned_tray.maxnutri] units of [reagent_id]\n" + else + returned_message += "No reagents found.\n" + + returned_message += "*---------*" + return returned_message + +/** + * This proc is called when a seed or any grown plant is scanned on left click (stats mode). + * It formats the plant name as well as either its traits and stats. * * - scanned_object - the source objecte for what we are scanning. This can be a grown food, a grown inedible, or a seed. * * Returns the formatted output as text. */ -/obj/item/plant_analyzer/proc/scan_plant(obj/item/scanned_object) +/obj/item/plant_analyzer/proc/scan_plant_stats(obj/item/scanned_object) var/returned_message = "*---------*\nThis is \a [scanned_object].\n" var/obj/item/seeds/our_seed = scanned_object if(!istype(our_seed)) //if we weren't passed a seed, we were passed a plant with a seed - var/obj/item/grown/scanned_plant = scanned_object - our_seed = scanned_plant.seed + our_seed = scanned_object.get_plant_seed() - switch(scan_mode) - if(PLANT_SCANMODE_STATS) - if(our_seed && istype(our_seed)) - returned_message += get_analyzer_text_traits(our_seed) - else - returned_message += "*---------*\nNo genes found.\n*---------*" - if(PLANT_SCANMODE_CHEMICALS) - if(scanned_object.reagents) //we have reagents contents - returned_message += get_analyzer_text_chem_contents(scanned_object) - else if (our_seed.reagents_add?.len) //we have a seed with reagent genes - returned_message += get_analyzer_text_chem_genes(our_seed) - else - returned_message += "*---------*\nNo reagents found.\n*---------*" + if(our_seed && istype(our_seed)) + returned_message += get_analyzer_text_traits(our_seed) + else + returned_message += "*---------*\nNo genes found.\n*---------*" + + returned_message += "\n" + return returned_message + +/** + * This proc is called when a seed or any grown plant is scanned on right click (chemical mode). + * It formats the plant name as well as its chemical contents. + * + * - scanned_object - the source objecte for what we are scanning. This can be a grown food, a grown inedible, or a seed. + * + * Returns the formatted output as text. + */ +/obj/item/plant_analyzer/proc/scan_plant_chems(obj/item/scanned_object) + var/returned_message = "*---------*\nThis is \a [scanned_object].\n" + var/obj/item/seeds/our_seed = scanned_object + if(!istype(our_seed)) //if we weren't passed a seed, we were passed a plant with a seed + our_seed = scanned_object.get_plant_seed() + + if(scanned_object.reagents) //we have reagents contents + returned_message += get_analyzer_text_chem_contents(scanned_object) + else if (our_seed.reagents_add?.len) //we have a seed with reagent genes + returned_message += get_analyzer_text_chem_genes(our_seed) + else + returned_message += "*---------*\nNo reagents found.\n*---------*" returned_message += "\n" return returned_message diff --git a/code/modules/hydroponics/hydroponics.dm b/code/modules/hydroponics/hydroponics.dm index be938ea3a18..a3e7cba10b9 100644 --- a/code/modules/hydroponics/hydroponics.dm +++ b/code/modules/hydroponics/hydroponics.dm @@ -586,11 +586,6 @@ to_chat(user, "[src] already has seeds in it!") return - else if(istype(O, /obj/item/plant_analyzer)) - var/obj/item/plant_analyzer/plant_analyzer = O - to_chat(user, plant_analyzer.scan_tray(src)) - return - else if(istype(O, /obj/item/cultivator)) if(weedlevel > 0) user.visible_message("[user] uproots the weeds.", "You remove the weeds from [src].") diff --git a/code/modules/hydroponics/seeds.dm b/code/modules/hydroponics/seeds.dm index bd2f9e9e265..d72edc502cc 100644 --- a/code/modules/hydroponics/seeds.dm +++ b/code/modules/hydroponics/seeds.dm @@ -503,11 +503,6 @@ return /obj/item/seeds/attackby(obj/item/O, mob/user, params) - if (istype(O, /obj/item/plant_analyzer)) - var/obj/item/plant_analyzer/plant_analyzer = O - to_chat(user, plant_analyzer.scan_plant(src)) - return - if(istype(O, /obj/item/pen)) var/choice = input("What would you like to change?") in list("Plant Name", "Seed Description", "Product Description", "Cancel") if(!user.canUseTopic(src, BE_CLOSE))