diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index f57c3b707d7..ebef6ea78e8 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -242,6 +242,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai /// This allows a person who has antimagic to cast spells without getting blocked #define TRAIT_ANTIMAGIC_NO_SELFBLOCK "anti_magic_no_selfblock" #define TRAIT_DEPRESSION "depression" +#define TRAIT_BLOOD_DEFICIENCY "blood_deficiency" #define TRAIT_JOLLY "jolly" #define TRAIT_NOCRITDAMAGE "no_crit" diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm index 6bfdfe68180..d40be5d92af 100644 --- a/code/_globalvars/traits.dm +++ b/code/_globalvars/traits.dm @@ -77,6 +77,7 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_ANTIMAGIC" = TRAIT_ANTIMAGIC, "TRAIT_HOLY" = TRAIT_HOLY, "TRAIT_DEPRESSION" = TRAIT_DEPRESSION, + "TRAIT_BLOOD_DEFICIENCY" = TRAIT_BLOOD_DEFICIENCY, "TRAIT_JOLLY" = TRAIT_JOLLY, "TRAIT_NOCRITDAMAGE" = TRAIT_NOCRITDAMAGE, "TRAIT_NO_SLIP_WATER" = TRAIT_NO_SLIP_WATER, diff --git a/code/datums/quirks/negative_quirks.dm b/code/datums/quirks/negative_quirks.dm index 0830e619ebc..7db1624a477 100644 --- a/code/datums/quirks/negative_quirks.dm +++ b/code/datums/quirks/negative_quirks.dm @@ -56,15 +56,30 @@ desc = "Your body can't produce enough blood to sustain itself." icon = "tint" value = -8 + mob_trait = TRAIT_BLOOD_DEFICIENCY gain_text = span_danger("You feel your vigor slowly fading away.") lose_text = span_notice("You feel vigorous again.") medical_record_text = "Patient requires regular treatment for blood loss due to low production of blood." hardcore_value = 8 - quirk_flags = QUIRK_HUMAN_ONLY|QUIRK_PROCESSES + quirk_flags = QUIRK_HUMAN_ONLY mail_goodies = list(/obj/item/reagent_containers/blood/o_minus) // universal blood type that is safe for all var/min_blood = BLOOD_VOLUME_SAFE - 25 // just barely survivable without treatment -/datum/quirk/blooddeficiency/process(delta_time) +/datum/quirk/blooddeficiency/post_add() + if(!ishuman(quirk_holder)) + return + + // for making sure the roundstart species has the right blood pack sent to them + var/mob/living/carbon/human/carbon_target = quirk_holder + carbon_target.dna.species.update_quirk_mail_goodies(carbon_target, src) + +/** + * Makes the mob lose blood from having the blood deficiency quirk, if possible + * + * Arguments: + * * delta_time + */ +/datum/quirk/blooddeficiency/proc/lose_blood(delta_time) if(quirk_holder.stat == DEAD) return diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm index 2d55f2dfb24..0f84252b265 100644 --- a/code/modules/mob/living/blood.dm +++ b/code/modules/mob/living/blood.dm @@ -14,7 +14,7 @@ return //Blood regeneration if there is some space - if(blood_volume < blood_volume_normal && !HAS_TRAIT(src, TRAIT_NOHUNGER)) //SKYRAT EDIT CHANGE + if(blood_volume < BLOOD_VOLUME_NORMAL && !HAS_TRAIT(src, TRAIT_NOHUNGER)) var/nutrition_ratio = 0 switch(nutrition) if(0 to NUTRITION_LEVEL_STARVING) @@ -30,7 +30,13 @@ if(satiety > 80) nutrition_ratio *= 1.25 adjust_nutrition(-nutrition_ratio * HUNGER_FACTOR * delta_time) - blood_volume = min(blood_volume + (BLOOD_REGEN_FACTOR * nutrition_ratio * delta_time), blood_volume_normal) //SKYRAT EDIT CHANGE + blood_volume = min(blood_volume + (BLOOD_REGEN_FACTOR * nutrition_ratio * delta_time), BLOOD_VOLUME_NORMAL) + + // we call lose_blood() here rather than quirk/process() to make sure that the blood loss happens in sync with life() + if(HAS_TRAIT(src, TRAIT_BLOOD_DEFICIENCY)) + var/datum/quirk/blooddeficiency/blooddeficiency = get_quirk(/datum/quirk/blooddeficiency) + if(!isnull(blooddeficiency)) + blooddeficiency.lose_blood(delta_time) //Effects of bloodloss var/word = pick("dizzy","woozy","faint") @@ -46,9 +52,9 @@ if(BLOOD_VOLUME_OKAY to BLOOD_VOLUME_SAFE) if(DT_PROB(2.5, delta_time)) to_chat(src, span_warning("You feel [word].")) - adjustOxyLoss(round(0.005 * (blood_volume_normal - blood_volume) * delta_time, 1)) //SKYRAT EDIT CHANGE - Oversized quirk + adjustOxyLoss(round(0.005 * (BLOOD_VOLUME_NORMAL - blood_volume) * delta_time, 1)) if(BLOOD_VOLUME_BAD to BLOOD_VOLUME_OKAY) - adjustOxyLoss(round(0.01 * (blood_volume_normal - blood_volume) * delta_time, 1)) //SKYRAT EDIT CHANGE - Oversized quirk + adjustOxyLoss(round(0.01 * (BLOOD_VOLUME_NORMAL - blood_volume) * delta_time, 1)) if(DT_PROB(2.5, delta_time)) set_eye_blur_if_lower(12 SECONDS) to_chat(src, span_warning("You feel very [word].")) @@ -323,7 +329,6 @@ var/obj/effect/decal/cleanable/blood/drip/drop = locate() in T if(drop) if(drop.drips < 5) - T.pollute_turf(/datum/pollutant/metallic_scent, 5) //SKYRAT EDIT ADDITION drop.drips++ drop.add_overlay(pick(drop.random_icon_states)) drop.transfer_mob_blood_dna(src) @@ -332,16 +337,10 @@ temp_blood_DNA = GET_ATOM_BLOOD_DNA(drop) //we transfer the dna from the drip to the splatter qdel(drop)//the drip is replaced by a bigger splatter else - T.pollute_turf(/datum/pollutant/metallic_scent, 5) //SKYRAT EDIT ADDITION drop = new(T, get_static_viruses()) drop.transfer_mob_blood_dna(src) return - //SKYRAT EDIT ADDITION - // Create a bit of metallic pollution, as that's how blood smells - T.pollute_turf(/datum/pollutant/metallic_scent, 30) - //SKYRAT EDIT END - // Find a blood decal or create a new one. var/obj/effect/decal/cleanable/blood/B = locate() in T if(!B) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index dabf04a2dbf..48121e09bc0 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -552,6 +552,44 @@ GLOBAL_LIST_EMPTY(features_by_species) SEND_SIGNAL(C, COMSIG_SPECIES_LOSS, src) +/** + * Proc called when mail goodies need to be updated for this species. + * + * Updates the mail goodies if that is required. e.g. for the blood deficiency quirk, which sends bloodbags to quirk holders, update the sent bloodpack to match the species' exotic blood. + * This is currently only used for the blood deficiency quirk but more can be added as needed. + * Arguments: + * * mob/living/carbon/human/recipient - the mob receiving the mail goodies + */ +/datum/species/proc/update_mail_goodies(mob/living/carbon/human/recipient) + update_quirk_mail_goodies(recipient, recipient.get_quirk(/datum/quirk/blooddeficiency)) + +/** + * Updates the mail goodies of a specific quirk. + * + * Updates the mail goodies belonging to a specific quirk. + * Add implementation as needed for each individual species. The base species proc should give the species the 'default' version of whatever mail goodies are required. + * Arguments: + * * mob/living/carbon/human/recipient - the mob receiving the mail goodies + * * datum/quirk/quirk - the quirk to update the mail goodies of. Use get_quirk(datum/quirk/some_quirk) to get the actual mob's quirk to pass. + * * list/mail_goodies - a list of mail goodies. Generally speaking you should not be using this argument on the initial function call. You should instead add to the species' implementation of this proc. + */ +/datum/species/proc/update_quirk_mail_goodies(mob/living/carbon/human/recipient, datum/quirk/quirk, list/mail_goodies) + if(isnull(quirk)) + return + if(length(mail_goodies)) + quirk.mail_goodies = mail_goodies + return + if(istype(quirk, /datum/quirk/blooddeficiency)) + if(HAS_TRAIT(recipient, TRAIT_NOBLOOD) && isnull(recipient.dna.species.exotic_blood)) // no blood packs should be sent in this case (like if a mob transforms into a plasmaman) + quirk.mail_goodies = list() + return + + // The default case if no species implementation exists. Set quirk's mail_goodies to initial. + var/datum/quirk/readable_quirk = new quirk.type + quirk.mail_goodies = readable_quirk.mail_goodies + qdel(readable_quirk) // We have to do it this way because initial will not work on lists in this version of DM + return + /** * Handles the body of a human * @@ -1033,6 +1071,7 @@ GLOBAL_LIST_EMPTY(features_by_species) * NOTE: If you return TRUE, that reagent will not be removed liike normal! You must handle it manually. */ /datum/species/proc/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H, delta_time, times_fired) + SHOULD_CALL_PARENT(TRUE) if(chem.type == exotic_blood) H.blood_volume = min(H.blood_volume + round(chem.volume, 0.1), BLOOD_VOLUME_MAXIMUM) H.reagents.del_reagent(chem.type) diff --git a/code/modules/mob/living/carbon/human/species_types/ethereal.dm b/code/modules/mob/living/carbon/human/species_types/ethereal.dm index becb099d4b0..212f0f8d1e5 100644 --- a/code/modules/mob/living/carbon/human/species_types/ethereal.dm +++ b/code/modules/mob/living/carbon/human/species_types/ethereal.dm @@ -69,11 +69,11 @@ return ..() -/datum/species/ethereal/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load) +/datum/species/ethereal/on_species_gain(mob/living/carbon/new_ethereal, datum/species/old_species, pref_load) . = ..() - if(!ishuman(C)) + if(!ishuman(new_ethereal)) return - var/mob/living/carbon/human/ethereal = C + var/mob/living/carbon/human/ethereal = new_ethereal default_color = ethereal.dna.features["ethcolor"] r1 = GETREDPART(default_color) g1 = GETGREENPART(default_color) @@ -83,22 +83,29 @@ RegisterSignal(ethereal, COMSIG_LIGHT_EATER_ACT, PROC_REF(on_light_eater)) ethereal_light = ethereal.mob_light() spec_updatehealth(ethereal) - C.set_safe_hunger_level() + new_ethereal.set_safe_hunger_level() + update_mail_goodies(ethereal) - var/obj/item/organ/internal/heart/ethereal/ethereal_heart = C.getorganslot(ORGAN_SLOT_HEART) + var/obj/item/organ/internal/heart/ethereal/ethereal_heart = new_ethereal.getorganslot(ORGAN_SLOT_HEART) ethereal_heart.ethereal_color = default_color - for(var/obj/item/bodypart/limb as anything in C.bodyparts) + for(var/obj/item/bodypart/limb as anything in new_ethereal.bodyparts) if(limb.limb_id == SPECIES_ETHEREAL) limb.update_limb(is_creating = TRUE) -/datum/species/ethereal/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load) - UnregisterSignal(C, COMSIG_ATOM_EMAG_ACT) - UnregisterSignal(C, COMSIG_ATOM_EMP_ACT) - UnregisterSignal(C, COMSIG_LIGHT_EATER_ACT) +/datum/species/ethereal/on_species_loss(mob/living/carbon/human/former_ethereal, datum/species/new_species, pref_load) + UnregisterSignal(former_ethereal, COMSIG_ATOM_EMAG_ACT) + UnregisterSignal(former_ethereal, COMSIG_ATOM_EMP_ACT) + UnregisterSignal(former_ethereal, COMSIG_LIGHT_EATER_ACT) QDEL_NULL(ethereal_light) return ..() +/datum/species/ethereal/update_quirk_mail_goodies(mob/living/carbon/human/recipient, datum/quirk/quirk, list/mail_goodies = list()) + if(istype(quirk, /datum/quirk/blooddeficiency)) + mail_goodies += list( + /obj/item/reagent_containers/blood/ethereal + ) + return ..() /datum/species/ethereal/random_name(gender,unique,lastname) if(unique) 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 6024b3d6721..31c7893c93b 100644 --- a/code/modules/mob/living/carbon/human/species_types/flypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/flypeople.dm @@ -44,7 +44,7 @@ H.adjustToxLoss(3 * REAGENTS_EFFECT_MULTIPLIER * delta_time) H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM * delta_time) return TRUE - ..() + return ..() /datum/species/fly/check_species_weakness(obj/item/weapon, mob/living/attacker) if(istype(weapon, /obj/item/melee/flyswatter)) 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 65252ee2bf6..6d8e67bddd2 100644 --- a/code/modules/mob/living/carbon/human/species_types/golems.dm +++ b/code/modules/mob/living/carbon/human/species_types/golems.dm @@ -362,6 +362,7 @@ H.adjustToxLoss(3 * REAGENTS_EFFECT_MULTIPLIER * delta_time) H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM * delta_time) return TRUE + return ..() //Radioactive puncher, hits for burn but only as hard as human, slightly more durable against brute but less against everything else /datum/species/golem/uranium @@ -740,6 +741,7 @@ return ..() /datum/species/golem/runic/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H, delta_time, times_fired) + . = ..() if(istype(chem, /datum/reagent/water/holywater)) H.adjustFireLoss(4 * REAGENTS_EFFECT_MULTIPLIER * delta_time) H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM * delta_time) diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm index dc1bd2aa219..f1eadf01b3f 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -2,6 +2,8 @@ #define JELLY_REGEN_RATE 1.5 ///The rate at which slimes regenerate their jelly when they completely run out of it and start taking damage, usually after having cannibalized all their limbs already #define JELLY_REGEN_RATE_EMPTY 2.5 +///The blood volume at which slimes begin to start losing nutrition -- so that IV drips can work for blood deficient slimes +#define BLOOD_VOLUME_LOSE_NUTRITION 550 /datum/species/jelly // Entirely alien beings that seem to be made entirely out of gel. They have three eyes and a skeleton visible within them. @@ -45,27 +47,36 @@ BODY_ZONE_CHEST = /obj/item/bodypart/chest/jelly, ) -/datum/species/jelly/on_species_loss(mob/living/carbon/old_jellyperson) - if(regenerate_limbs) - regenerate_limbs.Remove(old_jellyperson) - //SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION - if(alter_form) - alter_form.Remove(old_jellyperson) - //SKYRAT EDIT ADDITION END - old_jellyperson.RemoveElement(/datum/element/soft_landing) - ..() - -/datum/species/jelly/on_species_gain(mob/living/carbon/new_jellyperson, datum/species/old_species) - ..() +/datum/species/jelly/on_species_gain(mob/living/carbon/new_jellyperson, datum/species/old_species, pref_load) + . = ..() if(ishuman(new_jellyperson)) regenerate_limbs = new regenerate_limbs.Grant(new_jellyperson) + update_mail_goodies(new_jellyperson) //SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION alter_form = new alter_form.Grant(new_jellyperson) //SKYRAT EDIT ADDITION END new_jellyperson.AddElement(/datum/element/soft_landing) +/datum/species/jelly/on_species_loss(mob/living/carbon/former_jellyperson, datum/species/new_species, pref_load) + if(regenerate_limbs) + regenerate_limbs.Remove(former_jellyperson) + //SKYRAT EDIT ADDITION BEGIN - CUSTOMIZATION + if(alter_form) + alter_form.Remove(former_jellyperson) + //SKYRAT EDIT ADDITION END + former_jellyperson.RemoveElement(/datum/element/soft_landing) + + return ..() + +/datum/species/jelly/update_quirk_mail_goodies(mob/living/carbon/human/recipient, datum/quirk/quirk, list/mail_goodies = list()) + if(istype(quirk, /datum/quirk/blooddeficiency)) + mail_goodies += list( + /obj/item/reagent_containers/blood/toxin + ) + return ..() + /datum/species/jelly/spec_life(mob/living/carbon/human/H, delta_time, times_fired) if(H.stat == DEAD) //can't farm slime jelly from a dead slime/jelly person indefinitely return @@ -78,7 +89,14 @@ if(H.blood_volume < BLOOD_VOLUME_NORMAL) if(H.nutrition >= NUTRITION_LEVEL_STARVING) H.blood_volume += JELLY_REGEN_RATE * delta_time - H.adjust_nutrition(-1.25 * delta_time) + if(H.blood_volume <= BLOOD_VOLUME_LOSE_NUTRITION) // don't lose nutrition if we are above a certain threshold, otherwise slimes on IV drips will still lose nutrition + H.adjust_nutrition(-1.25 * delta_time) + + // we call lose_blood() here rather than quirk/process() to make sure that the blood loss happens in sync with life() + if(HAS_TRAIT(H, TRAIT_BLOOD_DEFICIENCY)) + var/datum/quirk/blooddeficiency/blooddeficiency = H.get_quirk(/datum/quirk/blooddeficiency) + if(!isnull(blooddeficiency)) + blooddeficiency.lose_blood(delta_time) if(H.blood_volume < BLOOD_VOLUME_OKAY) if(DT_PROB(2.5, delta_time)) @@ -236,7 +254,8 @@ else if(H.nutrition >= NUTRITION_LEVEL_WELL_FED) H.blood_volume += 1.5 * delta_time - H.adjust_nutrition(-1.25 * delta_time) + if(H.blood_volume <= BLOOD_VOLUME_LOSE_NUTRITION) + H.adjust_nutrition(-1.25 * delta_time) ..() @@ -803,6 +822,7 @@ return FALSE return TRUE - + #undef JELLY_REGEN_RATE #undef JELLY_REGEN_RATE_EMPTY +#undef BLOOD_VOLUME_LOSE_NUTRITION diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm index 6d664a9e832..50201045501 100644 --- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm @@ -53,6 +53,18 @@ BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/lizard, ) +/datum/species/lizard/on_species_gain(mob/living/carbon/new_lizard, datum/species/old_species, pref_load) + . = ..() + if(ishuman(new_lizard)) + update_mail_goodies(new_lizard) + +/datum/species/lizard/update_quirk_mail_goodies(mob/living/carbon/human/recipient, datum/quirk/quirk, list/mail_goodies = list()) + if(istype(quirk, /datum/quirk/blooddeficiency)) + mail_goodies += list( + /obj/item/reagent_containers/blood/lizard + ) + return ..() + /// Lizards are cold blooded and do not stabilize body temperature naturally /datum/species/lizard/body_temperature_core(mob/living/carbon/human/humi, delta_time, times_fired) return @@ -181,19 +193,19 @@ Lizard subspecies: SILVER SCALED ///See above var/old_eye_color_right -/datum/species/lizard/silverscale/on_species_gain(mob/living/carbon/C, datum/species/old_species) - var/mob/living/carbon/human/new_silverscale = C - old_mutcolor = C.dna.features["mcolor"] - old_eye_color_left = new_silverscale.eye_color_left - old_eye_color_right = new_silverscale.eye_color_right +/datum/species/lizard/silverscale/on_species_gain(mob/living/carbon/new_silverscale, datum/species/old_species, pref_load) + var/mob/living/carbon/human/silverscale = new_silverscale + old_mutcolor = new_silverscale.dna.features["mcolor"] + old_eye_color_left = silverscale.eye_color_left + old_eye_color_right = silverscale.eye_color_right new_silverscale.dna.features["mcolor"] = "#eeeeee" - new_silverscale.eye_color_left = "#0000a0" - new_silverscale.eye_color_right = "#0000a0" + silverscale.eye_color_left = "#0000a0" + silverscale.eye_color_right = "#0000a0" ..() - new_silverscale.add_filter("silver_glint", 2, list("type" = "outline", "color" = "#ffffff63", "size" = 2)) + silverscale.add_filter("silver_glint", 2, list("type" = "outline", "color" = "#ffffff63", "size" = 2)) -/datum/species/lizard/silverscale/on_species_loss(mob/living/carbon/C) - var/mob/living/carbon/human/was_silverscale = C +/datum/species/lizard/silverscale/on_species_loss(mob/living/carbon/old_silverscale, datum/species/new_species, pref_load) + var/mob/living/carbon/human/was_silverscale = old_silverscale was_silverscale.dna.features["mcolor"] = old_mutcolor was_silverscale.eye_color_left = old_eye_color_left was_silverscale.eye_color_right = old_eye_color_right diff --git a/code/modules/mob/living/carbon/human/species_types/mushpeople.dm b/code/modules/mob/living/carbon/human/species_types/mushpeople.dm index a8520733a3a..bff251b5fb5 100644 --- a/code/modules/mob/living/carbon/human/species_types/mushpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/mushpeople.dm @@ -64,6 +64,7 @@ H.adjustToxLoss(3 * REAGENTS_EFFECT_MULTIPLIER * delta_time) H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM * delta_time) return TRUE + return ..() /datum/species/mush/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour, force_update = FALSE) //SKYRAT EDIT - ORIGINAL: /datum/species/mush/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour) (one parameter added) forced_colour = FALSE diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm index dea4a2eb672..99271c01aae 100644 --- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm @@ -37,6 +37,18 @@ ass_image = 'icons/ass/asspodperson.png' +/datum/species/pod/on_species_gain(mob/living/carbon/new_podperson, datum/species/old_species, pref_load) + . = ..() + if(ishuman(new_podperson)) + update_mail_goodies(new_podperson) + +/datum/species/pod/update_quirk_mail_goodies(mob/living/carbon/human/recipient, datum/quirk/quirk, list/mail_goodies = list()) + if(istype(quirk, /datum/quirk/blooddeficiency)) + mail_goodies += list( + /obj/item/reagent_containers/blood/podperson + ) + return ..() + /datum/species/pod/spec_life(mob/living/carbon/human/H, delta_time, times_fired) if(H.stat == DEAD) return @@ -63,6 +75,7 @@ H.adjustToxLoss(3 * REAGENTS_EFFECT_MULTIPLIER * delta_time) H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM * delta_time) return TRUE + return ..() // SKYRAT EDIT ADDITION /datum/species/pod/get_species_description() diff --git a/code/modules/mob/living/carbon/human/species_types/snail.dm b/code/modules/mob/living/carbon/human/species_types/snail.dm index 56530d9a02c..51a050309d5 100644 --- a/code/modules/mob/living/carbon/human/species_types/snail.dm +++ b/code/modules/mob/living/carbon/human/species_types/snail.dm @@ -43,30 +43,40 @@ ) /datum/species/snail/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H, delta_time, times_fired) + . = ..() if(istype(chem,/datum/reagent/consumable/salt)) H.adjustFireLoss(2 * REAGENTS_EFFECT_MULTIPLIER * delta_time) playsound(H, 'sound/weapons/sear.ogg', 30, TRUE) H.reagents.remove_reagent(chem.type, REAGENTS_METABOLISM * delta_time) return TRUE -/datum/species/snail/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load) +/datum/species/snail/on_species_gain(mob/living/carbon/new_snailperson, datum/species/old_species, pref_load) . = ..() - var/obj/item/storage/backpack/bag = C.get_item_by_slot(ITEM_SLOT_BACK) + var/obj/item/storage/backpack/bag = new_snailperson.get_item_by_slot(ITEM_SLOT_BACK) if(!istype(bag, /obj/item/storage/backpack/snail)) - if(C.dropItemToGround(bag)) //returns TRUE even if its null - C.equip_to_slot_or_del(new /obj/item/storage/backpack/snail(C), ITEM_SLOT_BACK) - C.AddElement(/datum/element/snailcrawl) - C.update_icons() //SKYRAT EDIT: Roundstart Snails + if(new_snailperson.dropItemToGround(bag)) //returns TRUE even if its null + new_snailperson.equip_to_slot_or_del(new /obj/item/storage/backpack/snail(new_snailperson), ITEM_SLOT_BACK) + new_snailperson.AddElement(/datum/element/snailcrawl) + new_snailperson.update_icons() //SKYRAT EDIT: Roundstart Snails + if(ishuman(new_snailperson)) + update_mail_goodies(new_snailperson) -/datum/species/snail/on_species_loss(mob/living/carbon/C) +/datum/species/snail/on_species_loss(mob/living/carbon/former_snailperson, datum/species/new_species, pref_load) . = ..() - C.RemoveElement(/datum/element/snailcrawl) - var/obj/item/storage/backpack/bag = C.get_item_by_slot(ITEM_SLOT_BACK) + former_snailperson.RemoveElement(/datum/element/snailcrawl) + var/obj/item/storage/backpack/bag = former_snailperson.get_item_by_slot(ITEM_SLOT_BACK) if(istype(bag, /obj/item/storage/backpack/snail)) bag.emptyStorage() - C.temporarilyRemoveItemFromInventory(bag, TRUE) + former_snailperson.temporarilyRemoveItemFromInventory(bag, TRUE) qdel(bag) +/datum/species/snail/update_quirk_mail_goodies(mob/living/carbon/human/recipient, datum/quirk/quirk, list/mail_goodies = list()) + if(istype(quirk, /datum/quirk/blooddeficiency)) + mail_goodies += list( + /obj/item/reagent_containers/blood/snail + ) + return ..() + /obj/item/storage/backpack/snail name = "snail shell" desc = "Worn by snails as armor and storage compartment." diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index 08b64ff7be9..c9cc61fa1cd 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -517,6 +517,20 @@ return TRUE return FALSE +/** + * Getter function for a mob's quirk + * + * Arguments: + * * quirktype - the type of the quirk to acquire e.g. /datum/quirk/some_quirk + * + * Returns the mob's quirk datum if the mob this is called on has the quirk, null on failure + */ +/mob/living/proc/get_quirk(quirktype) + for(var/datum/quirk/quirk in quirks) + if(quirk.type == quirktype) + return quirk + return null + /mob/living/proc/cure_husk(source) REMOVE_TRAIT(src, TRAIT_HUSK, source) if(!HAS_TRAIT(src, TRAIT_HUSK)) diff --git a/code/modules/reagents/reagent_containers/blood_pack.dm b/code/modules/reagents/reagent_containers/blood_pack.dm index f0e8b915bce..89b9e7c748c 100644 --- a/code/modules/reagents/reagent_containers/blood_pack.dm +++ b/code/modules/reagents/reagent_containers/blood_pack.dm @@ -9,7 +9,7 @@ var/labelled = FALSE fill_icon_thresholds = list(10, 20, 30, 40, 50, 60, 70, 80, 90, 100) -/obj/item/reagent_containers/blood/Initialize(mapload) +/obj/item/reagent_containers/blood/Initialize(mapload, vol) . = ..() if(blood_type != null) reagents.add_reagent(unique_blood ? unique_blood : /datum/reagent/blood, 200, list("viruses"=null,"blood_DNA"=null,"blood_type"=blood_type,"resistances"=null,"trace_chem"=null)) @@ -22,6 +22,12 @@ blood_type = new_reagent.data["blood_type"] else if(holder.has_reagent(/datum/reagent/consumable/liquidelectricity)) blood_type = "LE" + else if(holder.has_reagent(/datum/reagent/lube)) + blood_type = "S" + else if(holder.has_reagent(/datum/reagent/water)) + blood_type = "H2O" + else if(holder.has_reagent(/datum/reagent/toxin/slimejelly)) + blood_type = "TOX" else blood_type = null return ..() @@ -35,7 +41,7 @@ /obj/item/reagent_containers/blood/random icon_state = "random_bloodpack" -/obj/item/reagent_containers/blood/random/Initialize(mapload) +/obj/item/reagent_containers/blood/random/Initialize(mapload, vol) icon_state = "bloodpack" blood_type = pick("A+", "A-", "B+", "B-", "O+", "O-", "L") return ..() @@ -65,6 +71,31 @@ blood_type = "LE" unique_blood = /datum/reagent/consumable/liquidelectricity +/obj/item/reagent_containers/blood/snail + blood_type = "S" + unique_blood = /datum/reagent/lube + +/obj/item/reagent_containers/blood/snail/examine() + . = ..() + . += span_notice("It's a bit slimy... The label indicates that this is meant for snails.") + +/obj/item/reagent_containers/blood/podperson + blood_type = "H2O" + unique_blood = /datum/reagent/water + +/obj/item/reagent_containers/blood/podperson/examine() + . = ..() + . += span_notice("This appears to be some very overpriced water.") + +// for slimepeople +/obj/item/reagent_containers/blood/toxin + blood_type = "TOX" + unique_blood = /datum/reagent/toxin/slimejelly + +/obj/item/reagent_containers/blood/toxin/examine() + . = ..() + . += span_notice("There is a toxin warning on the label. This is for slimepeople.") + /obj/item/reagent_containers/blood/universal blood_type = "U" diff --git a/modular_skyrat/modules/assault_operatives/code/interrogator.dm b/modular_skyrat/modules/assault_operatives/code/interrogator.dm index f6b6d985c34..6b59191a29b 100644 --- a/modular_skyrat/modules/assault_operatives/code/interrogator.dm +++ b/modular_skyrat/modules/assault_operatives/code/interrogator.dm @@ -75,7 +75,7 @@ if(!locked) open_machine() -/obj/machinery/interrogator/open_machine() +/obj/machinery/interrogator/open_machine(drop = TRUE, density_to_set = FALSE) . = ..() human_occupant = null diff --git a/modular_skyrat/modules/cryosleep/code/cryopod.dm b/modular_skyrat/modules/cryosleep/code/cryopod.dm index 9577c7d2695..e052e816839 100644 --- a/modular_skyrat/modules/cryosleep/code/cryopod.dm +++ b/modular_skyrat/modules/cryosleep/code/cryopod.dm @@ -207,7 +207,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/computer/cryopod, 32) return control_computer_weakref != null -/obj/machinery/cryopod/close_machine(atom/movable/target) +/obj/machinery/cryopod/close_machine(atom/movable/target, density_to_set = TRUE) if(!control_computer_weakref) find_control_computer(TRUE) if((isnull(target) || isliving(target)) && state_open && !panel_open) @@ -227,7 +227,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/computer/cryopod, 32) COOLDOWN_START(src, despawn_world_time, time_till_despawn) -/obj/machinery/cryopod/open_machine() +/obj/machinery/cryopod/open_machine(drop = TRUE, density_to_set = FALSE) ..() set_density(TRUE) name = initial(name) @@ -532,7 +532,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/cryopod/prison, 18) // Simple way to make it always non-dense. return ..(FALSE) -/obj/machinery/cryopod/prison/close_machine(atom/movable/target) +/obj/machinery/cryopod/prison/close_machine(atom/movable/target, density_to_set = TRUE) . = ..() // Flick the pod for a second when user enters flick("prisonpod-open", src) diff --git a/modular_skyrat/modules/self_actualization_device/code/self_actualization_device.dm b/modular_skyrat/modules/self_actualization_device/code/self_actualization_device.dm index 75be23dd642..9121f093b22 100644 --- a/modular_skyrat/modules/self_actualization_device/code/self_actualization_device.dm +++ b/modular_skyrat/modules/self_actualization_device/code/self_actualization_device.dm @@ -55,7 +55,7 @@ . = ..() update_appearance() -/obj/machinery/self_actualization_device/close_machine(mob/user) +/obj/machinery/self_actualization_device/close_machine(atom/movable/target, density_to_set = TRUE) ..() playsound(src, 'sound/machines/click.ogg', 50) if(!occupant) diff --git a/modular_skyrat/modules/stasisrework/code/stasissleeper.dm b/modular_skyrat/modules/stasisrework/code/stasissleeper.dm index df55b820180..ffeb12dc56e 100644 --- a/modular_skyrat/modules/stasisrework/code/stasissleeper.dm +++ b/modular_skyrat/modules/stasisrework/code/stasissleeper.dm @@ -24,7 +24,7 @@ . += span_notice("A light blinking on the side indicates that it is [occupant ? "occupied" : "vacant"].") . += span_notice("It has a screen on the side displaying the vitals of the occupant. Interact to read it.") -/obj/machinery/stasissleeper/open_machine() +/obj/machinery/stasissleeper/open_machine(drop = TRUE, density_to_set = FALSE) if(!state_open && !panel_open) if(occupant) thaw_them(occupant) @@ -33,11 +33,11 @@ flick("[initial(icon_state)]-anim", src) ..() -/obj/machinery/stasissleeper/close_machine(mob/user) - if((isnull(user) || istype(user)) && state_open && !panel_open) +/obj/machinery/stasissleeper/close_machine(atom/movable/target, density_to_set = TRUE) + if((isnull(target) || istype(target)) && state_open && !panel_open) playsound(src, 'sound/machines/click.ogg', 60, TRUE) flick("[initial(icon_state)]-anim", src) - ..(user) + ..(target) var/mob/living/mob_occupant = occupant if(occupant) play_power_sound()