diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index d095491529e..be5f36f1e15 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -89861,6 +89861,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 1 }, +/obj/item/blood_filter, /turf/open/floor/plasteel/white, /area/medical/surgery) "dsO" = ( diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index f4820d5e5c3..d199a3d52fa 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -49981,6 +49981,7 @@ /obj/item/clothing/glasses/hud/health, /obj/item/clothing/glasses/hud/health, /obj/item/clothing/glasses/hud/health, +/obj/item/blood_filter, /turf/open/floor/plasteel/dark, /area/medical/storage) "ddy" = ( diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index ca515cf737d..5954c6b398b 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -49992,6 +49992,7 @@ /obj/item/storage/backpack/duffelbag/med/surgery, /obj/item/reagent_containers/glass/bottle/ethanol, /obj/item/reagent_containers/glass/bottle/ethanol, +/obj/item/blood_filter, /turf/open/floor/plasteel/dark, /area/medical/storage) "cpV" = ( diff --git a/_maps/map_files/PubbyStation/PubbyStation.dmm b/_maps/map_files/PubbyStation/PubbyStation.dmm index 87854b146fc..30fb3ad9e91 100644 --- a/_maps/map_files/PubbyStation/PubbyStation.dmm +++ b/_maps/map_files/PubbyStation/PubbyStation.dmm @@ -36167,6 +36167,7 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/item/blood_filter, /turf/open/floor/plasteel/white, /area/medical/surgery) "bMP" = ( diff --git a/code/__DEFINES/tools.dm b/code/__DEFINES/tools.dm index 6fe9b44eee0..58c503fc5c5 100644 --- a/code/__DEFINES/tools.dm +++ b/code/__DEFINES/tools.dm @@ -16,6 +16,7 @@ #define TOOL_SAW "saw" #define TOOL_BONESET "bonesetter" #define TOOL_KNIFE "knife" +#define TOOL_BLOODFILTER "bloodfilter" // If delay between the start and the end of tool operation is less than MIN_TOOL_SOUND_DELAY, // tool sound is only played when op is started. If not, it's played twice. diff --git a/code/datums/components/food/edible.dm b/code/datums/components/food/edible.dm index a38dcc04d59..460591b1192 100644 --- a/code/datums/components/food/edible.dm +++ b/code/datums/components/food/edible.dm @@ -165,9 +165,7 @@ Behavior that's still missing from this component that original food items had t return if(!CanConsume(eater, feeder)) return - var/fullness = eater.nutrition + 10 //The theoretical fullness of the person eating if they were to eat this - for(var/datum/reagent/consumable/C in eater.reagents.reagent_list) //we add the nutrition value of what we're currently digesting - fullness += C.nutriment_factor * C.volume / C.metabolization_rate + var/fullness = eater.get_fullness() + 10 //The theoretical fullness of the person eating if they were to eat this . = COMPONENT_ITEM_NO_ATTACK //Point of no return I suppose diff --git a/code/datums/materials/basemats.dm b/code/datums/materials/basemats.dm index 77b154f2017..50a8e9101ee 100644 --- a/code/datums/materials/basemats.dm +++ b/code/datums/materials/basemats.dm @@ -217,8 +217,9 @@ Unless you know what you're doing, only use the first three numbers. They're in beauty_modifier = -0.01 armor_modifiers = list(MELEE = 1.5, BULLET = 1.1, LASER = 0.3, ENERGY = 0.5, BOMB = 1, BIO = 1, RAD = 1, FIRE = 1.1, ACID = 1) -/datum/material/plastic/on_accidental_mat_consumption(mob/living/carbon/M, obj/item/S) - M.adjust_disgust(17) +/datum/material/plastic/on_accidental_mat_consumption(mob/living/carbon/eater, obj/item/food) + eater.reagents.add_reagent(/datum/reagent/plastic_polymers, rand(6, 8)) + food?.reagents?.add_reagent(/datum/reagent/plastic_polymers, food.reagents.total_volume*(2/5)) return TRUE ///Force decrease and mushy sound effect. (Not yet implemented) diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index 13875334132..3479f5c4697 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -377,6 +377,7 @@ new /obj/item/surgical_drapes(src) new /obj/item/clothing/mask/surgical(src) new /obj/item/razor(src) + new /obj/item/blood_filter(src) /obj/item/storage/backpack/duffelbag/sec name = "security duffel bag" @@ -398,6 +399,7 @@ new /obj/item/cautery(src) new /obj/item/surgical_drapes(src) new /obj/item/clothing/mask/surgical(src) + new /obj/item/blood_filter(src) /obj/item/storage/backpack/duffelbag/engineering name = "industrial duffel bag" @@ -486,6 +488,7 @@ new /obj/item/clothing/suit/straight_jacket(src) new /obj/item/clothing/mask/muzzle(src) new /obj/item/mmi/syndie(src) + new /obj/item/blood_filter(src) /obj/item/storage/backpack/duffelbag/syndie/ammo name = "ammunition duffel bag" diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index fba202d2544..fdcd2759309 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -560,18 +560,20 @@ GLOBAL_LIST_EMPTY(station_turfs) if (iscarbon(M)) var/mob/living/carbon/C = M if(C.reagents) - clear_reagents_to_vomit_pool(C,V, purge) + clear_reagents_to_vomit_pool(C, V, purge) /proc/clear_reagents_to_vomit_pool(mob/living/carbon/M, obj/effect/decal/cleanable/vomit/V, purge = FALSE) - var/chemicals_lost = M.reagents.total_volume / 10 + var/obj/item/organ/stomach/belly = M.getorganslot(ORGAN_SLOT_STOMACH) + if(!belly) + return + var/chemicals_lost = belly.reagents.total_volume * 0.1 if(purge) - chemicals_lost = (2 * M.reagents.total_volume)/3 //For detoxification surgery, we're manually pumping the stomach out of chemcials, so it's far more efficient. - M.reagents.trans_to(V, chemicals_lost, transfered_by = M) - for(var/datum/reagent/R in M.reagents.reagent_list) //clears the stomach of anything that might be digested as food - if(istype(R, /datum/reagent/consumable) || purge) - var/datum/reagent/consumable/nutri_check = R - if(nutri_check.nutriment_factor >0) - M.reagents.remove_reagent(R.type, min(R.volume, 10)) + chemicals_lost = belly.reagents.total_volume * 0.67 //For detoxification surgery, we're manually pumping the stomach out of chemcials, so it's far more efficient. + belly.reagents.trans_to(V, chemicals_lost, transfered_by = M) + //clear the stomach of anything even not food + for(var/bile in belly.reagents.reagent_list) + var/datum/reagent/reagent = bile + belly.reagents.remove_reagent(reagent.type, min(reagent.volume, 10)) //Whatever happens after high temperature fire dies out or thermite reaction works. //Should return new turf diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm index f41282af2bc..c64d6212c94 100644 --- a/code/modules/food_and_drinks/drinks/drinks.dm +++ b/code/modules/food_and_drinks/drinks/drinks.dm @@ -44,10 +44,12 @@ M.visible_message("[user] fed [M] the contents of [src].", \ "[user] fed you the contents of [src].") log_combat(user, M, "fed", reagents.log_list()) + SEND_SIGNAL(src, COMSIG_DRINK_DRANK, M, user) var/fraction = min(gulp_size/reagents.total_volume, 1) - checkLiked(fraction, M) reagents.trans_to(M, gulp_size, transfered_by = user, methods = INGEST) + checkLiked(fraction, M) + playsound(M.loc,'sound/items/drink.ogg', rand(10,50), TRUE) if(iscarbon(M)) var/mob/living/carbon/carbon_drinker = M diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm index 72e37f6079f..370b911b91d 100644 --- a/code/modules/food_and_drinks/food/snacks.dm +++ b/code/modules/food_and_drinks/food/snacks.dm @@ -109,9 +109,7 @@ All foods are distributed among various categories. Use common sense. if(!canconsume(M, user)) return FALSE - var/fullness = M.nutrition + 10 - for(var/datum/reagent/consumable/C in M.reagents.reagent_list) //we add the nutrition value of what we're currently digesting - fullness += C.nutriment_factor * C.volume / C.metabolization_rate + var/fullness = M.get_fullness() + 10 if(M == user) //If you're eating it yourself. if(junkiness && M.satiety < -150 && M.nutrition > NUTRITION_LEVEL_STARVING + 50 && !HAS_TRAIT(user, TRAIT_VORACIOUS)) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index b35d690ef3f..cdfb56181f8 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -490,23 +490,44 @@ if(!blood) adjust_nutrition(-lost_nutrition) adjustToxLoss(-3) + + var/obj/item/organ/stomach/belly = getorganslot(ORGAN_SLOT_STOMACH) for(var/i=0 to distance) if(blood) if(T) add_splatter_floor(T) if(harm) adjustBruteLoss(3) - else if(src.reagents.has_reagent(/datum/reagent/consumable/ethanol/blazaam, needs_metabolizing = TRUE)) - if(T) - T.add_vomit_floor(src, VOMIT_PURPLE) else - if(T) - T.add_vomit_floor(src, VOMIT_TOXIC, purge)//toxic barf looks different || call purge when doing detoxicfication to pump more chems out of the stomach. + if(belly?.reagents.has_reagent(/datum/reagent/consumable/ethanol/blazaam, needs_metabolizing = TRUE)) + if(T) + T.add_vomit_floor(src, VOMIT_PURPLE) + else + if(T) + T.add_vomit_floor(src, VOMIT_TOXIC, purge) //toxic barf looks different || call purge when doing detoxicfication to pump more chems out of the stomach. T = get_step(T, dir) if (T?.is_blocked_turf()) break return TRUE +/** + * Expel the reagents you just tried to ingest + * + * When you try to ingest reagents but you do not have a stomach + * you will spew the reagents on the floor. + * + * Vars: + * * bite: /atom the reagents to expel + * * amount: int The amount of reagent + */ +/mob/living/carbon/proc/expel_ingested(var/atom/bite, amount) + visible_message("[src] throws up all over [p_them()]self!", \ + "You are unable to keep the [bite] down without a stomach!") + + var/turf/floor = get_turf(src) + var/obj/effect/decal/cleanable/vomit/spew = new(floor, get_static_viruses()) + bite.reagents.trans_to(spew, amount, transfered_by = src) + /mob/living/carbon/proc/spew_organ(power = 5, amt = 1) for(var/i in 1 to amt) if(!internal_organs.len) diff --git a/code/modules/mob/living/carbon/human/species_types/flypeople.dm b/code/modules/mob/living/carbon/human/species_types/flypeople.dm index 7b2a3831aef..f9ac4269965 100644 --- a/code/modules/mob/living/carbon/human/species_types/flypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/flypeople.dm @@ -25,17 +25,7 @@ if(chem.type == /datum/reagent/toxin/pestkiller) H.adjustToxLoss(3) H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM) - return 1 - -/datum/species/fly/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H) - if(istype(chem, /datum/reagent/consumable)) - var/datum/reagent/consumable/nutri_check = chem - if(nutri_check.nutriment_factor > 0) - var/turf/pos = get_turf(H) - H.vomit(0, FALSE, FALSE, 2, TRUE) - playsound(pos, 'sound/effects/splat.ogg', 50, TRUE) - H.visible_message("[H] vomits on the floor!", \ - "You throw up on the floor!") + return TRUE ..() /datum/species/fly/check_species_weakness(obj/item/weapon, mob/living/attacker) @@ -79,6 +69,21 @@ name = odd_organ_name() icon_state = pick("brain-x-d", "liver-x", "kidneys-x", "stomach-x", "lungs-x", "random_fly_1", "random_fly_2", "random_fly_3", "random_fly_4", "random_fly_5") +/obj/item/organ/stomach/fly/on_life() + for(var/bile in reagents.reagent_list) + if(!istype(bile, /datum/reagent/consumable)) + continue + var/datum/reagent/consumable/chunk = bile + if(chunk.nutriment_factor <= 0) + continue + var/mob/living/carbon/body = owner + var/turf/pos = get_turf(owner) + body.vomit(reagents.total_volume, FALSE, FALSE, 2, TRUE) + playsound(pos, 'sound/effects/splat.ogg', 50, TRUE) + body.visible_message("[body] vomits on the floor!", \ + "You throw up on the floor!") + return ..() + /obj/item/organ/appendix/fly desc = "You have no idea what the hell this is, or how it manages to keep something alive in any capacity." diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm index b1d3c9a5951..72dca526e30 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -919,6 +919,7 @@ species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYESPRITES,HAS_BONE) inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID mutanttongue = /obj/item/organ/tongue/bone + mutantstomach = /obj/item/organ/stomach/bone sexes = FALSE fixed_mut_color = null inherent_traits = list(TRAIT_NOFLASH,TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_CHUNKYFINGERS,TRAIT_RADIMMUNE,TRAIT_GENELESS,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_FAKEDEATH) @@ -939,15 +940,6 @@ /datum/species/golem/bone/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H) . = ..() - if(chem.type == /datum/reagent/consumable/milk) - if(chem.volume > 10) - H.reagents.remove_reagent(chem.type, chem.volume - 10) - to_chat(H, "The excess milk is dripping off your bones!") - H.heal_bodypart_damage(1.5,0, 0) - for(var/i in H.all_wounds) - var/datum/wound/iter_wound = i - iter_wound.on_xadone(2) - H.reagents.remove_reagent(chem.type, chem.metabolization_rate) if(chem.type == /datum/reagent/toxin/bonehurtingjuice) H.adjustStaminaLoss(7.5, 0) H.adjustBruteLoss(0.5, 0) diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index b70c3b6c90c..64dd32f3a43 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -172,16 +172,6 @@ /datum/species/plasmaman/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H) . = ..() - if(istype(chem, /datum/reagent/consumable/milk)) - if(chem.volume > 10) - H.reagents.remove_reagent(chem.type, chem.volume - 10) - to_chat(H, "The excess milk is dripping off your bones!") - H.heal_bodypart_damage(1.5,0, 0) - H.reagents.remove_reagent(chem.type, chem.metabolization_rate) - for(var/i in H.all_wounds) - var/datum/wound/iter_wound = i - iter_wound.on_xadone(2) - return TRUE if(istype(chem, /datum/reagent/toxin/plasma)) H.reagents.remove_reagent(chem.type, chem.metabolization_rate) for(var/i in H.all_wounds) diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm index 8f23b246213..d7663e777eb 100644 --- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm +++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm @@ -10,6 +10,7 @@ TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH,TRAIT_XENO_IMMUNE,TRAIT_NOCLONELOSS) inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID mutanttongue = /obj/item/organ/tongue/bone + mutantstomach = /obj/item/organ/stomach/bone damage_overlay_type = ""//let's not show bloody wounds or burns over bones. disliked_food = NONE liked_food = GROSS | MEAT | RAW @@ -25,16 +26,6 @@ //Can still metabolize milk through meme magic /datum/species/skeleton/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H) . = ..() - if(chem.type == /datum/reagent/consumable/milk) - if(chem.volume > 10) - H.reagents.remove_reagent(chem.type, chem.volume - 10) - to_chat(H, "The excess milk is dripping off your bones!") - for(var/i in H.all_wounds) - var/datum/wound/iter_wound = i - iter_wound.on_xadone(2) - H.heal_bodypart_damage(1,1, 0) - H.reagents.remove_reagent(chem.type, chem.metabolization_rate) - return TRUE if(chem.type == /datum/reagent/toxin/bonehurtingjuice) H.adjustStaminaLoss(7.5, 0) H.adjustBruteLoss(0.5, 0) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 82fee6cbabb..66b17f7fe6d 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -702,6 +702,27 @@ All effects don't start immediately, but rather get worse over time; the rate is bodytemperature = clamp(bodytemperature + amount,min_temp,max_temp) +/////////// +//Stomach// +/////////// + +/mob/living/carbon/get_fullness() + var/fullness = nutrition + + var/obj/item/organ/stomach/belly = getorganslot(ORGAN_SLOT_STOMACH) + if(!belly) //nothing to see here if we do not have a stomach + return fullness + + for(var/bile in belly.reagents.reagent_list) + var/datum/reagent/bits = bile + if(istype(bits, /datum/reagent/consumable)) + var/datum/reagent/consumable/goodbit = bile + fullness += goodbit.nutriment_factor * goodbit.volume / goodbit.metabolization_rate + continue + fullness += 0.6 * bits.volume / bits.metabolization_rate //not food takes up space + + return fullness + ///////// //LIVER// ///////// diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index ac7d6f3bd59..e01ed2440ee 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -115,6 +115,23 @@ var/turf/location = get_turf(src) location.hotspot_expose(700, 50, 1) +/** + * Get the fullness of the mob + * + * This returns a value form 0 upwards to represent how full the mob is. + * The value is a total amount of consumable reagents in the body combined + * with the total amount of nutrition they have. + * This does not have an upper limit. + */ +/mob/living/proc/get_fullness() + var/fullness = nutrition + // we add the nutrition value of what we're currently digesting + for(var/bile in reagents.reagent_list) + var/datum/reagent/consumable/bits = bile + if(bits) + fullness += bits.nutriment_factor * bits.volume / bits.metabolization_rate + return fullness + //this updates all special effects: knockdown, druggy, stuttering, etc.. /mob/living/proc/handle_status_effects() diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm index ef4a424ee20..2c25e1e9dc2 100644 --- a/code/modules/reagents/chemistry/holder.dm +++ b/code/modules/reagents/chemistry/holder.dm @@ -209,8 +209,9 @@ * * methods - passed through to [/datum/reagents/proc/react_single] and [/datum/reagent/proc/on_transfer] * * show_message - passed through to [/datum/reagents/proc/react_single] * * round_robin - if round_robin=TRUE, so transfer 5 from 15 water, 15 sugar and 15 plasma becomes 10, 15, 15 instead of 13.3333, 13.3333 13.3333. Good if you hate floating point errors + * * ignore_stomach - when using methods INGEST will not use the stomach as the target */ -/datum/reagents/proc/trans_to(obj/target, amount = 1, multiplier = 1, preserve_data = TRUE, no_react = FALSE, mob/transfered_by, remove_blacklisted = FALSE, methods = NONE, show_message = TRUE, round_robin = FALSE) +/datum/reagents/proc/trans_to(obj/target, amount = 1, multiplier = 1, preserve_data = TRUE, no_react = FALSE, mob/transfered_by, remove_blacklisted = FALSE, methods = NONE, show_message = TRUE, round_robin = FALSE, ignore_stomach = FALSE) var/list/cached_reagents = reagent_list if(!target || !total_volume) return @@ -223,10 +224,19 @@ R = target target_atom = R.my_atom else - if(!target.reagents) + if(!ignore_stomach && (methods & INGEST) && istype(target, /mob/living/carbon)) + var/mob/living/carbon/eater = target + var/obj/item/organ/stomach/belly = eater.getorganslot(ORGAN_SLOT_STOMACH) + if(!belly) + eater.expel_ingested(my_atom, amount) + return + R = belly.reagents + target_atom = belly + else if(!target.reagents) return - R = target.reagents - target_atom = target + else + R = target.reagents + target_atom = target amount = min(min(amount, src.total_volume), R.maximum_volume-R.total_volume) var/trans_data = null diff --git a/code/modules/research/designs/autolathe_designs.dm b/code/modules/research/designs/autolathe_designs.dm index c8fa1a1dc24..483e0b020cf 100644 --- a/code/modules/research/designs/autolathe_designs.dm +++ b/code/modules/research/designs/autolathe_designs.dm @@ -495,6 +495,15 @@ build_path = /obj/item/clothing/head/foilhat category = list("hacked", "Misc") +/datum/design/blood_filter + name = "Blood Filter" + id = "blood_filter" + build_type = AUTOLATHE | PROTOLATHE + materials = list(/datum/material/iron = 4000, /datum/material/glass = 1500, /datum/material/silver = 500) + build_path = /obj/item/blood_filter + category = list("initial", "Medical", "Tool Designs") + departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE + /datum/design/scalpel name = "Scalpel" id = "scalpel" diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 9423cabdef2..2709183d363 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -56,8 +56,10 @@ starting_node = TRUE display_name = "Basic Medical Equipment" description = "Basic medical tools and equipment." - design_ids = list("cybernetic_liver", "cybernetic_heart", "cybernetic_lungs","cybernetic_stomach", "scalpel", "circular_saw", "bonesetter", "surgicaldrill", "retractor", "cautery", "hemostat", "stethoscope", - "surgical_drapes", "syringe", "plumbing_rcd", "beaker", "large_beaker", "xlarge_beaker", "dropper", "defibmountdefault", "surgical_tape", "portable_chem_mixer") + design_ids = list("cybernetic_liver", "cybernetic_heart", "cybernetic_lungs","cybernetic_stomach", "scalpel", + "blood_filter", "circular_saw", "bonesetter", "surgicaldrill", "retractor", "cautery", "hemostat", + "stethoscope", "surgical_drapes", "syringe", "plumbing_rcd", "beaker", "large_beaker", "xlarge_beaker", + "dropper", "defibmountdefault", "surgical_tape", "portable_chem_mixer") /////////////////////////Biotech///////////////////////// /datum/techweb_node/biotech diff --git a/code/modules/surgery/blood_filter.dm b/code/modules/surgery/blood_filter.dm new file mode 100644 index 00000000000..46b0c1f9194 --- /dev/null +++ b/code/modules/surgery/blood_filter.dm @@ -0,0 +1,44 @@ +/datum/surgery/blood_filter + name = "Filter blood" + steps = list(/datum/surgery_step/incise, + /datum/surgery_step/retract_skin, + /datum/surgery_step/incise, + /datum/surgery_step/filter_blood, + /datum/surgery_step/close) + + target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey) + possible_locs = list(BODY_ZONE_CHEST) + requires_bodypart_type = TRUE + ignore_clothes = FALSE + +/datum/surgery_step/filter_blood + name = "Filter blood" + implements = list(/obj/item/blood_filter = 95) + repeatable = TRUE + time = 2.5 SECONDS + +/datum/surgery/filter_blood/can_start(mob/user, mob/living/carbon/target) + if(HAS_TRAIT(target, TRAIT_HUSK)) //You can filter the blood of a dead person just not husked + return FALSE + return ..() + +/datum/surgery_step/filter_blood/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + display_results(user, target, "You begin filtering [target]'s blood...", + "[user] uses the [tool] to filtering your blood.", + "[user] uses the [tool] on [target]'s chest.") + +/datum/surgery_step/filter_blood/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) + if(target.reagents?.total_volume) + for(var/blood_chem in target.reagents.reagent_list) + var/datum/reagent/chem = blood_chem + target.reagents.remove_reagent(chem.type, min(chem.volume * 0.22, 10)) + display_results(user, target, "The [tool] pings as it finishes filtering [target]'s blood.", + "The [tool] pings as it stops pumping your blood.", + "The [tool] pings as it stops pumping.") + return ..() + +/datum/surgery_step/filter_blood/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) + display_results(user, target, "You screw up, brusing [target]'s chest!", + "[user] screws up, brusing [target]'s chest!", + "[user] screws up!") + target.adjustBruteLoss(5) diff --git a/code/modules/surgery/organs/stomach.dm b/code/modules/surgery/organs/stomach.dm index c4fadb46c4c..d517e435111 100755 --- a/code/modules/surgery/organs/stomach.dm +++ b/code/modules/surgery/organs/stomach.dm @@ -18,30 +18,40 @@ var/disgust_metabolism = 1 -/obj/item/organ/stomach/on_life() - var/mob/living/carbon/human/H = owner - var/datum/reagent/Nutri +/obj/item/organ/stomach/Initialize() + . = ..() + create_reagents(1000) - ..() - if(istype(H)) +/obj/item/organ/stomach/on_life() + . = ..() + + //Manage species digestion + if(istype(owner, /mob/living/carbon/human)) + var/mob/living/carbon/human/humi = owner if(!(organ_flags & ORGAN_FAILING)) - H.dna.species.handle_digestion(H) - handle_disgust(H) + humi.dna.species.handle_digestion(humi) + + //digest food + var/mob/living/carbon/body = owner + reagents.metabolize(body, can_overdose=TRUE) + if(body) + handle_disgust(body) if(damage < low_threshold) return - Nutri = locate(/datum/reagent/consumable/nutriment) in H.reagents.reagent_list + var/datum/reagent/nutri = locate(/datum/reagent/consumable/nutriment) in reagents.reagent_list + if(!nutri) + return - if(Nutri) - if(prob((damage/40) * Nutri.volume * Nutri.volume)) - H.vomit(damage) - to_chat(H, "Your stomach reels in pain as you're incapable of holding down all that food!") + if(prob(damage * 0.025 * nutri.volume * nutri.volume)) + body.vomit(damage) + to_chat(body, "Your stomach reels in pain as you're incapable of holding down all that food!") + return - else if(Nutri && damage > high_threshold) - if(prob((damage/10) * Nutri.volume * Nutri.volume)) - H.vomit(damage) - to_chat(H, "Your stomach reels in pain as you're incapable of holding down all that food!") + if(damage > high_threshold && prob(damage * 0.1 * nutri.volume * nutri.volume)) + body.vomit(damage) + to_chat(body, "Your stomach reels in pain as you're incapable of holding down all that food!") /obj/item/organ/stomach/get_availability(datum/species/S) return !(NOSTOMACH in S.inherent_traits) @@ -88,11 +98,42 @@ SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "disgust") ..() +/obj/item/organ/stomach/bone + desc = "You have no idea what this strange ball of bones does." + +/obj/item/organ/stomach/bone/on_life() + var/datum/reagent/consumable/milk/milk = locate(/datum/reagent/consumable/milk) in reagents.reagent_list + if(milk) + var/mob/living/carbon/body = owner + if(milk.volume > 10) + reagents.remove_reagent(milk.type, milk.volume - 10) + to_chat(owner, "The excess milk is dripping off your bones!") + body.heal_bodypart_damage(1.5,0, 0) + for(var/i in body.all_wounds) + var/datum/wound/iter_wound = i + iter_wound.on_xadone(2) + reagents.remove_reagent(milk.type, milk.metabolization_rate) + return ..() + /obj/item/organ/stomach/plasmaman name = "digestive crystal" icon_state = "stomach-p" desc = "A strange crystal that is responsible for metabolizing the unseen energy force that feeds plasmamen." +/obj/item/organ/stomach/plasmaman/on_life() + var/datum/reagent/consumable/milk/milk = locate(/datum/reagent/consumable/milk) in reagents.reagent_list + if(milk) + var/mob/living/carbon/body = owner + if(milk.volume > 10) + reagents.remove_reagent(milk.type, milk.volume - 10) + to_chat(owner, "The excess milk is dripping off your bones!") + body.heal_bodypart_damage(1.5,0, 0) + for(var/i in body.all_wounds) + var/datum/wound/iter_wound = i + iter_wound.on_xadone(2) + reagents.remove_reagent(milk.type, milk.metabolization_rate) + return ..() + /obj/item/organ/stomach/ethereal name = "biological battery" icon_state = "stomach-p" //Welp. At least it's more unique in functionaliy. diff --git a/code/modules/surgery/stomachpump.dm b/code/modules/surgery/stomachpump.dm index 89c3233720b..a07f45a9f4c 100644 --- a/code/modules/surgery/stomachpump.dm +++ b/code/modules/surgery/stomachpump.dm @@ -15,8 +15,6 @@ /datum/surgery/stomach_pump/can_start(mob/user, mob/living/carbon/target) var/obj/item/organ/stomach/S = target.getorganslot(ORGAN_SLOT_STOMACH) - if(target.stat != DEAD) //shamelessly lifted off the revival surgery but we're looking for the same critera here, a dead, non-husked, revivable patient. - return FALSE if(HAS_TRAIT(target, TRAIT_HUSK)) return FALSE if(!S) diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 6ed7f36020f..bd58c70c3f9 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -423,3 +423,18 @@ attack_verb_simple = list("correct", "properly set") tool_behaviour = TOOL_BONESET toolspeed = 1 + +/obj/item/blood_filter + name = "blood filter" + desc = "For filtering the blood." + icon = 'icons/obj/surgery.dmi' + icon_state = "bloodfilter" + lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi' + custom_materials = list(/datum/material/iron=2000, /datum/material/glass=1500, /datum/material/silver=500) + item_flags = SURGICAL_TOOL + w_class = WEIGHT_CLASS_NORMAL + attack_verb_continuous = list("pumps", "siphons") + attack_verb_simple = list("pumps", "siphons") + tool_behaviour = TOOL_BLOODFILTER + toolspeed = 1 diff --git a/icons/mob/inhands/equipment/medical_lefthand.dmi b/icons/mob/inhands/equipment/medical_lefthand.dmi index 2e05ca17cd9..a47b319c5ff 100644 Binary files a/icons/mob/inhands/equipment/medical_lefthand.dmi and b/icons/mob/inhands/equipment/medical_lefthand.dmi differ diff --git a/icons/mob/inhands/equipment/medical_righthand.dmi b/icons/mob/inhands/equipment/medical_righthand.dmi index a570a3cd189..d72231c4b94 100644 Binary files a/icons/mob/inhands/equipment/medical_righthand.dmi and b/icons/mob/inhands/equipment/medical_righthand.dmi differ diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi index 68d1bd6f35a..c681bcfd235 100755 Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 93653898e7e..6a4b636ef28 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3052,6 +3052,7 @@ #include "code\modules\station_goals\shield.dm" #include "code\modules\station_goals\station_goal.dm" #include "code\modules\surgery\amputation.dm" +#include "code\modules\surgery\blood_filter.dm" #include "code\modules\surgery\bone_mending.dm" #include "code\modules\surgery\brain_surgery.dm" #include "code\modules\surgery\burn_dressing.dm"