From 27c4dff507d974cf8d9114335a5ebf13c3b0c15f Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Sat, 21 Nov 2020 21:02:54 -0700 Subject: [PATCH 1/7] ports --- code/__DEFINES/mobs/innate_abilities.dm | 29 ++ code/__DEFINES/traits.dm | 4 + code/modules/mob/innate_abilities.dm | 52 +++ .../mob/living/carbon/human/human_movement.dm | 5 - .../carbon/human/innate_abilities/blobform.dm | 111 ++++++ .../human/innate_abilities/customization.dm | 208 ++++++++++ .../innate_abilities/limb_regeneration.dm | 49 +++ .../mob/living/carbon/human/species.dm | 8 - .../carbon/human/species_types/jellypeople.dm | 372 +----------------- .../mob/living/carbon/human/update_icons.dm | 39 +- code/modules/mob/living/living.dm | 1 + code/modules/mob/living/living_mobility.dm | 3 +- code/modules/mob/living/living_movement.dm | 3 + code/modules/mob/mob_defines.dm | 10 +- tgstation.dme | 5 + 15 files changed, 499 insertions(+), 400 deletions(-) create mode 100644 code/__DEFINES/mobs/innate_abilities.dm create mode 100644 code/modules/mob/innate_abilities.dm create mode 100644 code/modules/mob/living/carbon/human/innate_abilities/blobform.dm create mode 100644 code/modules/mob/living/carbon/human/innate_abilities/customization.dm create mode 100644 code/modules/mob/living/carbon/human/innate_abilities/limb_regeneration.dm diff --git a/code/__DEFINES/mobs/innate_abilities.dm b/code/__DEFINES/mobs/innate_abilities.dm new file mode 100644 index 0000000000..563a48deec --- /dev/null +++ b/code/__DEFINES/mobs/innate_abilities.dm @@ -0,0 +1,29 @@ +// helpers + +// sources +/// Species +#define ABILITY_SOURCE_SPECIES "species" +/// Changeling +#define ABILITY_SOURCE_CHANGELING "changeling" + +// abilities +/// Full customization and transformation of mutantparts/hair/sprite accessories/etc - excludes name by default +#define INNATE_ABILITY_HUMANOID_CUSTOMIZATION "humanoid_customization" +/// Slime blobform +#define INNATE_ABILITY_SLIME_BLOBFORM "slime_blobform" +/// limb regrowth +#define INNATE_ABILITY_LIMB_REGROWTH "limb_regrowth" + +/// ability properties +// customization/body change +/// is this silent? +#define PROPERTY_CUSTOMIZATION_SILENT "silent" +// blobform +/// Blobform color +#define PROPERTY_BLOBFORM_COLOR "color" +// limb regrwoth +/// limb regrowth usage type +#define PROPERTY_LIMB_REGROWTH_USAGE_TYPE "cost" + /// blood + #define REGRWOTH_USES_BLOOD "blood" + diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 4b08dbc446..736efc01d7 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -213,6 +213,10 @@ #define TRAIT_NO_STAMINA_BUFFER_REGENERATION "block_stamina_buffer_regen" /// Prevents stamina buffer regeneration #define TRAIT_NO_STAMINA_REGENERATION "block_stamina_regen" /// Prevents stamina regeneration #define TRAIT_ARMOR_BROKEN "armor_broken" //acts as if you are wearing no clothing when taking damage, does not affect non-clothing sources of protection +/// forces update_density to make us not dense +#define TRAIT_LIVING_NO_DENSITY "living_no_density" +/// forces us to not render our overlays +#define TRAIT_HUMAN_NO_RENDER "human_no_render" // mobility flag traits // IN THE FUTURE, IT WOULD BE NICE TO DO SOMETHING SIMILAR TO https://github.com/tgstation/tgstation/pull/48923/files (ofcourse not nearly the same because I have my.. thoughts on it) diff --git a/code/modules/mob/innate_abilities.dm b/code/modules/mob/innate_abilities.dm new file mode 100644 index 0000000000..2c77d9c64c --- /dev/null +++ b/code/modules/mob/innate_abilities.dm @@ -0,0 +1,52 @@ +/** + * Sets an ability property + */ +/mob/proc/set_ability_property(ability, property, value) + LAZYINITLIST(ability_properties) + LAZYINITLIST(ability_properties[ability]) + ability_properties[ability][property] = value + +/** + * Gets an ability property + */ +/mob/proc/get_ability_property(ability, property) + return ability_properties && ability_properties[ability] && ability_properties[ability][property] + +GLOBAL_LIST_INIT(innate_ability_typepaths, all_innate_ability_typepaths) + +/proc/all_innate_ability_typepaths() + return list( + INNATE_ABILITY_HUMANOID_CUSTOMIZATION = /datum/action/innate/ability/humanoid_customization, + INNATE_ABILITY_SLIME_BLOBFORM = /datum/action/innate/ability/slime_blobform, + INNATE_ABILITY_LIMB_REGROWTH = /datum/action/innate/ability/limb_regrowth + ) + +/** + * Grants an ability from a source + */ +/mob/proc/grant_ability_from_source(list/abilities, source) + if(!islist(abilities)) + abilities = list(abilities) + for(var/ability in abilities) + LAZYINITLIST(innate_abilities) + LAZYINITLIST(innate_abilities[ability]) + innate_abilities[ability] |= source + if(ability_actions[ability]) + return + var/datum/action/innate/ability/A = ability_actions[ability] = new GLOB.innate_ability_typepaths[ability] + A.Grant(src) + +/** + * Removes an ability from a source + */ +/mob/proc/remove_ability_from_source(list/abilities, source) + if(!islist(abilities)) + abilities = list(abilities) + for(var/ability in abilities) + if(!innate_abilities || !length(innate_abilities[ability])) + return + innate_abilities[ability] -= source + if(!length(innate_abilities[ability])) + innate_abilities -= ability + qdel(ability_actions[ability]) + ability_actions -= ability diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 97c40c96d7..509633c0d5 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -100,8 +100,3 @@ if(dna.species.space_move(src)) return TRUE return ..() - -/mob/living/carbon/human/CanPass(atom/movable/mover, turf/target) - if(dna.species.species_pass_check()) - return TRUE - return ..() diff --git a/code/modules/mob/living/carbon/human/innate_abilities/blobform.dm b/code/modules/mob/living/carbon/human/innate_abilities/blobform.dm new file mode 100644 index 0000000000..df67f8b54d --- /dev/null +++ b/code/modules/mob/living/carbon/human/innate_abilities/blobform.dm @@ -0,0 +1,111 @@ + +/datum/action/innate/ability/slime_blobform + name = "Puddle Transformation" + check_flags = AB_CHECK_CONSCIOUS + button_icon_state = "slimepuddle" + icon_icon = 'icons/mob/actions/actions_slime.dmi' + background_icon_state = "bg_alien" + required_mobility_flags = MOBILITY_STAND + var/is_puddle = FALSE + var/in_transformation_duration = 12 + var/out_transformation_duration = 7 + var/puddle_into_effect = /obj/effect/temp_visual/slime_puddle + var/puddle_from_effect = /obj/effect/temp_visual/slime_puddle/reverse + var/puddle_icon = 'icons/mob/mob.dmi' + var/puddle_state = "puddle" + var/tracked_overlay + var/datum/component/squeak/squeak + var/transforming = FALSE + var/last_use + +/datum/action/innate/ability/slime_blobform/IsAvailable() + if(!transforming) + return ..() + else + return FALSE + +/datum/action/innate/ability/slime_blobform/Remove(mob/M) + if(is_puddle) + detransform() + return ..() + +/datum/action/innate/ability/slime_blobform/Activate() + var/mob/living/carbon/human/H = owner + //if they have anything stuck to their hands, we immediately say 'no' and return + for(var/obj/item/I in H.held_items) + if(HAS_TRAIT(I, TRAIT_NODROP)) + to_chat(owner, "There's something stuck to your hand, stopping you from transforming!") + return + if(IsAvailable()) + transforming = TRUE + UpdateButtonIcon() + var/mutcolor = get_ability_property(INNATE_ABILITY_SLIME_BLOBFORM, PROPERTY_BLOFMROM_COLOR) || ("#" + H.dna.features["mcolor"]) + if(!is_puddle) + if(CHECK_MOBILITY(H, MOBILITY_USE)) //if we can use items, we can turn into a puddle + is_puddle = TRUE //so we know which transformation to use when its used + owner.cut_overlays() //we dont show our normal sprite, we show a puddle sprite + var/obj/effect/puddle_effect = new puddle_into_effect(get_turf(owner), owner.dir) + puddle_effect.color = mutcolor + H.Stun(in_transformation_duration, ignore_canstun = TRUE) //cant move while transforming + + //series of traits that make up the puddle behaviour + ADD_TRAIT(H, TRAIT_PARALYSIS_L_ARM, SLIMEPUDDLE_TRAIT) + ADD_TRAIT(H, TRAIT_PARALYSIS_R_ARM, SLIMEPUDDLE_TRAIT) + ADD_TRAIT(H, TRAIT_MOBILITY_NOPICKUP, SLIMEPUDDLE_TRAIT) + ADD_TRAIT(H, TRAIT_MOBILITY_NOUSE, SLIMEPUDDLE_TRAIT) + ADD_TRAIT(H, TRAIT_SPRINT_LOCKED, SLIMEPUDDLE_TRAIT) + ADD_TRAIT(H, TRAIT_COMBAT_MODE_LOCKED, SLIMEPUDDLE_TRAIT) + ADD_TRAIT(H, TRAIT_MOBILITY_NOREST, SLIMEPUDDLE_TRAIT) + ADD_TRAIT(H, TRAIT_ARMOR_BROKEN, SLIMEPUDDLE_TRAIT) + H.update_disabled_bodyparts(silent = TRUE) //silently update arms to be paralysed + + H.add_movespeed_modifier(/datum/movespeed_modifier/slime_puddle) + + H.layer -= 1 //go one layer down so people go over you + ENABLE_BITFIELD(H.pass_flags, PASSMOB) //this actually lets people pass over you + squeak = H.AddComponent(/datum/component/squeak, custom_sounds = list('sound/effects/blobattack.ogg')) //blorble noise when people step on you + + //if the user is a changeling, retract their sting + H.unset_sting() + + sleep(in_transformation_duration) //wait for animation to end + + //set the puddle overlay up + var/mutable_appearance/puddle_overlay = mutable_appearance(icon = puddle_icon, icon_state = puddle_state) + puddle_overlay.color = mutcolor + tracked_overlay = puddle_overlay + owner.add_overlay(puddle_overlay) + + transforming = FALSE + UpdateButtonIcon() + else + detransform() + else + to_chat(owner, "You need to be standing up to do this!") //just assume they're a slime because it's such a weird edgecase to have it and not be one (it shouldn't even be possible) + +/datum/action/innate/ability/slime_blobform/proc/detransform() + var/mob/living/carbon/human/H = owner + //like the above, but reverse everything done! + H.cut_overlay(tracked_overlay) + var/obj/effect/puddle_effect = new puddle_from_effect(get_turf(owner), owner.dir) + puddle_effect.color = mutcolor + H.Stun(out_transformation_duration, ignore_canstun = TRUE) + sleep(out_transformation_duration) + REMOVE_TRAIT(H, TRAIT_PARALYSIS_L_ARM, SLIMEPUDDLE_TRAIT) + REMOVE_TRAIT(H, TRAIT_PARALYSIS_R_ARM, SLIMEPUDDLE_TRAIT) + REMOVE_TRAIT(H, TRAIT_MOBILITY_NOPICKUP, SLIMEPUDDLE_TRAIT) + REMOVE_TRAIT(H, TRAIT_MOBILITY_NOUSE, SLIMEPUDDLE_TRAIT) + REMOVE_TRAIT(H, TRAIT_SPRINT_LOCKED, SLIMEPUDDLE_TRAIT) + REMOVE_TRAIT(H, TRAIT_COMBAT_MODE_LOCKED, SLIMEPUDDLE_TRAIT) + REMOVE_TRAIT(H, TRAIT_MOBILITY_NOREST, SLIMEPUDDLE_TRAIT) + REMOVE_TRAIT(H, TRAIT_ARMOR_BROKEN, SLIMEPUDDLE_TRAIT) + H.update_disabled_bodyparts(silent = TRUE) + H.remove_movespeed_modifier(/datum/movespeed_modifier/slime_puddle) + H.layer += 1 //go one layer back above! + DISABLE_BITFIELD(H.pass_flags, PASSMOB) + is_puddle = FALSE + if(squeak) + squeak.RemoveComponent() + owner.regenerate_icons() + transforming = FALSE + UpdateButtonIcon() diff --git a/code/modules/mob/living/carbon/human/innate_abilities/customization.dm b/code/modules/mob/living/carbon/human/innate_abilities/customization.dm new file mode 100644 index 0000000000..e1af0f53e2 --- /dev/null +++ b/code/modules/mob/living/carbon/human/innate_abilities/customization.dm @@ -0,0 +1,208 @@ +/datum/action/innate/ability/humanoid_customization + name = "Alter Form" + check_flags = AB_CHECK_CONSCIOUS + button_icon_state = "alter_form" //placeholder + icon_icon = 'modular_citadel/icons/mob/actions/actions_slime.dmi' + background_icon_state = "bg_alien" + +/datum/action/innate/ability/humanoid_customization/Activate() + if(owner.get_ability_property(INNATE_ABILITY_HUMANOID_CUSTOMIZATION, ABILITY_CUSTOMIZATION_SILENT)) + owner.visible_message("[owner] gains a look of \ + concentration while standing perfectly still.\ + Their body seems to shift and starts getting more goo-like.", + "You focus intently on altering your body while \ + standing perfectly still...") + change_form() + +/////// +/////// NOTICE: This currently doens't support skin tone - if anyone wants to add this to non slimes, it's up to YOU to do this. +////// (someone should also add genital color switching, more mutant color selection) +///// maybe just make this entire thing tgui based. maybe. +/////// + +/datum/action/innate/slime_change/proc/change_form() + var/mob/living/carbon/human/H = owner + var/select_alteration = input(owner, "Select what part of your form to alter", "Form Alteration", "cancel") in list("Body Color","Hair Style", "Genitals", "Tail", "Snout", "Markings", "Ears", "Taur body", "Penis", "Vagina", "Penis Length", "Breast Size", "Breast Shape", "Cancel") + + if(select_alteration == "Body Color") + var/new_color = input(owner, "Choose your skin color:", "Race change","#"+H.dna.features["mcolor"]) as color|null + if(new_color) + var/temp_hsv = RGBtoHSV(new_color) + if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3]) // mutantcolors must be bright + H.dna.features["mcolor"] = sanitize_hexcolor(new_color, 6) + H.update_body() + H.update_hair() + else + to_chat(H, "Invalid color. Your color is not bright enough.") + else if(select_alteration == "Hair Style") + if(H.gender == MALE) + var/new_style = input(owner, "Select a facial hair style", "Hair Alterations") as null|anything in GLOB.facial_hair_styles_list + if(new_style) + H.facial_hair_style = new_style + else + H.facial_hair_style = "Shaved" + //handle normal hair + var/new_style = input(owner, "Select a hair style", "Hair Alterations") as null|anything in GLOB.hair_styles_list + if(new_style) + H.hair_style = new_style + H.update_hair() + else if (select_alteration == "Genitals") + var/operation = input("Select organ operation.", "Organ Manipulation", "cancel") in list("add sexual organ", "remove sexual organ", "cancel") + switch(operation) + if("add sexual organ") + var/new_organ = input("Select sexual organ:", "Organ Manipulation") as null|anything in GLOB.genitals_list + if(!new_organ) + return + H.give_genital(GLOB.genitals_list[new_organ]) + + if("remove sexual organ") + var/list/organs = list() + for(var/obj/item/organ/genital/X in H.internal_organs) + var/obj/item/organ/I = X + organs["[I.name] ([I.type])"] = I + var/obj/item/O = input("Select sexual organ:", "Organ Manipulation", null) as null|anything in organs + var/obj/item/organ/genital/G = organs[O] + if(!G) + return + G.forceMove(get_turf(H)) + qdel(G) + H.update_genitals() + + else if (select_alteration == "Ears") + var/list/snowflake_ears_list = list("Normal" = null) + for(var/path in GLOB.mam_ears_list) + var/datum/sprite_accessory/ears/mam_ears/instance = GLOB.mam_ears_list[path] + if(istype(instance, /datum/sprite_accessory)) + var/datum/sprite_accessory/S = instance + if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(H.client.ckey))) + snowflake_ears_list[S.name] = path + var/new_ears + new_ears = input(owner, "Choose your character's ears:", "Ear Alteration") as null|anything in snowflake_ears_list + if(new_ears) + H.dna.features["mam_ears"] = new_ears + H.update_body() + + else if (select_alteration == "Snout") + var/list/snowflake_snouts_list = list("Normal" = null) + for(var/path in GLOB.mam_snouts_list) + var/datum/sprite_accessory/snouts/mam_snouts/instance = GLOB.mam_snouts_list[path] + if(istype(instance, /datum/sprite_accessory)) + var/datum/sprite_accessory/S = instance + if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(H.client.ckey))) + snowflake_snouts_list[S.name] = path + var/new_snout + new_snout = input(owner, "Choose your character's face:", "Face Alteration") as null|anything in snowflake_snouts_list + if(new_snout) + H.dna.features["mam_snouts"] = new_snout + H.update_body() + + else if (select_alteration == "Markings") + var/list/snowflake_markings_list = list("None") + for(var/path in GLOB.mam_body_markings_list) + var/datum/sprite_accessory/mam_body_markings/instance = GLOB.mam_body_markings_list[path] + if(istype(instance, /datum/sprite_accessory)) + var/datum/sprite_accessory/S = instance + if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(H.client.ckey))) + snowflake_markings_list[S.name] = path + var/new_mam_body_markings + new_mam_body_markings = input(H, "Choose your character's body markings:", "Marking Alteration") as null|anything in snowflake_markings_list + if(new_mam_body_markings) + H.dna.features["mam_body_markings"] = new_mam_body_markings + for(var/X in H.bodyparts) //propagates the markings changes + var/obj/item/bodypart/BP = X + BP.update_limb(FALSE, H) + H.update_body() + + else if (select_alteration == "Tail") + var/list/snowflake_tails_list = list("Normal" = null) + for(var/path in GLOB.mam_tails_list) + var/datum/sprite_accessory/tails/mam_tails/instance = GLOB.mam_tails_list[path] + if(istype(instance, /datum/sprite_accessory)) + var/datum/sprite_accessory/S = instance + if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(H.client.ckey))) + snowflake_tails_list[S.name] = path + var/new_tail + new_tail = input(owner, "Choose your character's Tail(s):", "Tail Alteration") as null|anything in snowflake_tails_list + if(new_tail) + H.dna.features["mam_tail"] = new_tail + if(new_tail != "None") + H.dna.features["taur"] = "None" + H.update_body() + + else if (select_alteration == "Taur body") + var/list/snowflake_taur_list = list("Normal" = null) + for(var/path in GLOB.taur_list) + var/datum/sprite_accessory/taur/instance = GLOB.taur_list[path] + if(istype(instance, /datum/sprite_accessory)) + var/datum/sprite_accessory/S = instance + if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(H.client.ckey))) + snowflake_taur_list[S.name] = path + var/new_taur + new_taur = input(owner, "Choose your character's tauric body:", "Tauric Alteration") as null|anything in snowflake_taur_list + if(new_taur) + H.dna.features["taur"] = new_taur + if(new_taur != "None") + H.dna.features["mam_tail"] = "None" + H.update_body() + + else if (select_alteration == "Penis") + for(var/obj/item/organ/genital/penis/X in H.internal_organs) + qdel(X) + var/new_shape + new_shape = input(owner, "Choose your character's dong", "Genital Alteration") as null|anything in GLOB.cock_shapes_list + if(new_shape) + H.dna.features["cock_shape"] = new_shape + H.update_genitals() + H.give_genital(/obj/item/organ/genital/testicles) + H.give_genital(/obj/item/organ/genital/penis) + H.apply_overlay() + + + else if (select_alteration == "Vagina") + for(var/obj/item/organ/genital/vagina/X in H.internal_organs) + qdel(X) + var/new_shape + new_shape = input(owner, "Choose your character's pussy", "Genital Alteration") as null|anything in GLOB.vagina_shapes_list + if(new_shape) + H.dna.features["vag_shape"] = new_shape + H.update_genitals() + H.give_genital(/obj/item/organ/genital/womb) + H.give_genital(/obj/item/organ/genital/vagina) + H.apply_overlay() + + else if (select_alteration == "Penis Length") + for(var/obj/item/organ/genital/penis/X in H.internal_organs) + qdel(X) + var/min_D = CONFIG_GET(number/penis_min_inches_prefs) + var/max_D = CONFIG_GET(number/penis_max_inches_prefs) + var/new_length = input(owner, "Penis length in inches:\n([min_D]-[max_D])", "Genital Alteration") as num|null + if(new_length) + H.dna.features["cock_length"] = clamp(round(new_length), min_D, max_D) + H.update_genitals() + H.apply_overlay() + H.give_genital(/obj/item/organ/genital/testicles) + H.give_genital(/obj/item/organ/genital/penis) + + else if (select_alteration == "Breast Size") + for(var/obj/item/organ/genital/breasts/X in H.internal_organs) + qdel(X) + var/new_size = input(owner, "Breast Size", "Genital Alteration") as null|anything in CONFIG_GET(keyed_list/breasts_cups_prefs) + if(new_size) + H.dna.features["breasts_size"] = new_size + H.update_genitals() + H.apply_overlay() + H.give_genital(/obj/item/organ/genital/breasts) + + else if (select_alteration == "Breast Shape") + for(var/obj/item/organ/genital/breasts/X in H.internal_organs) + qdel(X) + var/new_shape + new_shape = input(owner, "Breast Shape", "Genital Alteration") as null|anything in GLOB.breasts_shapes_list + if(new_shape) + H.dna.features["breasts_shape"] = new_shape + H.update_genitals() + H.apply_overlay() + H.give_genital(/obj/item/organ/genital/breasts) + + else + return diff --git a/code/modules/mob/living/carbon/human/innate_abilities/limb_regeneration.dm b/code/modules/mob/living/carbon/human/innate_abilities/limb_regeneration.dm new file mode 100644 index 0000000000..ce36397c91 --- /dev/null +++ b/code/modules/mob/living/carbon/human/innate_abilities/limb_regeneration.dm @@ -0,0 +1,49 @@ + +/datum/action/innate/ability/limb_regrowth + name = "Regenerate Limbs" + check_flags = AB_CHECK_CONSCIOUS + button_icon_state = "slimeheal" + icon_icon = 'icons/mob/actions/actions_slime.dmi' + background_icon_state = "bg_alien" + required_mobility_flags = NONE + +/datum/action/innate/ability/limb_regrowth/IsAvailable(silent = FALSE) + if(..()) + var/mob/living/carbon/human/H = owner + var/list/limbs_to_heal = H.get_missing_limbs() + if(limbs_to_heal.len < 1) + return 0 + var/mode = H.get_ability_property(INNATE_ABILITY_LIMB_REGROWTH, PROPERTY_LIMB_REGROWTH_USAGE_TYPE) + switch(mode) + if(REGROWTH_USES_BLOOD) + if(H.blood_volume >= (BLOOD_VOLUME_OKAY*H.blood_ratio)+40) + return TRUE + else + return FALSE + return 0 + +/datum/action/innate/ability/limb_regrowth/Activate() + var/mob/living/carbon/human/H = owner + var/list/limbs_to_heal = H.get_missing_limbs() + if(limbs_to_heal.len < 1) + to_chat(H, "You feel intact enough as it is.") + return + to_chat(H, "You focus intently on your missing [limbs_to_heal.len >= 2 ? "limbs" : "limb"]...") + var/mode = H.get_ability_property(INNATE_ABILITY_LIMB_REGROWTH, PROPERTY_LIMB_REGROWTH_USAGE_TYPE) + switch(mode) + if(REGROWTH_USES_BLOOD) + if(H.blood_volume >= 40*limbs_to_heal.len+(BLOOD_VOLUME_OKAY*H.blood_ratio)) + H.regenerate_limbs() + H.blood_volume -= 40*limbs_to_heal.len + to_chat(H, "...and after a moment you finish reforming!") + return + else if(H.blood_volume >= 40)//We can partially heal some limbs + while(H.blood_volume >= (BLOOD_VOLUME_OKAY*H.blood_ratio)+40) + var/healed_limb = pick(limbs_to_heal) + H.regenerate_limb(healed_limb) + limbs_to_heal -= healed_limb + H.blood_volume -= 40 + to_chat(H, "...but there is not enough of you to fix everything! You must attain more mass to heal completely!") + return + to_chat(H, "...but there is not enough of you to go around! You must attain more mass to heal!") + diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 604babbf75..963ea2a387 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1969,14 +1969,6 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(HAS_BONE in species_traits) . |= BIO_JUST_BONE -//a check for if you should render any overlays or not -/datum/species/proc/should_render(mob/living/carbon/human/H) - return TRUE - -//a check for if you want to forcibly make CanPass return TRUE for the mob with this species -/datum/species/proc/species_pass_check() - return FALSE - ///////////// //BREATHING// ///////////// 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 ecac5fda10..c369625dc6 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -46,18 +46,17 @@ if(slime_puddle) slime_puddle.Remove(C) C.faction -= "slime" + if(ishuman(C)) + var/mob/living/carbon/human/H = C + H.remove_ability_from_source(list(INNATE_ABILITY_SLIME_BLOBFORM, INNATE_ABILITY_LIMB_REGROWTH, INNATE_ABILITY_HUMANOID_CUSTOMIZATION), ABILITY_SOURCE_SPECIES) ..() C.faction -= "slime" /datum/species/jelly/on_species_gain(mob/living/carbon/C, datum/species/old_species) ..() if(ishuman(C)) - regenerate_limbs = new - regenerate_limbs.Grant(C) - slime_change = new - slime_change.Grant(C) - slime_puddle = new - slime_puddle.Grant(C) + var/mob/living/carbon/human/H = C + H.grant_ability_from_source(list(INNATE_ABILITY_SLIME_BLOBFORM, INNATE_ABILITY_LIMB_REGROWTH, INNATE_ABILITY_HUMANOID_CUSTOMIZATION), ABILITY_SOURCE_SPECIES) C.faction |= "slime" /datum/species/jelly/handle_body(mob/living/carbon/human/H) @@ -65,18 +64,6 @@ //update blood color to body color exotic_blood_color = "#" + H.dna.features["mcolor"] -/datum/species/jelly/should_render() - if(slime_puddle && slime_puddle.is_puddle) - return FALSE - else - return ..() - -/datum/species/jelly/species_pass_check() - if(slime_puddle && slime_puddle.is_puddle) - return TRUE - else - return ..() - /datum/species/jelly/spec_life(mob/living/carbon/human/H) if(H.stat == DEAD || HAS_TRAIT(H, TRAIT_NOMARROW)) //can't farm slime jelly from a dead slime/jelly person indefinitely, and no regeneration for blooduskers return @@ -111,47 +98,6 @@ qdel(consumed_limb) H.blood_volume += 20 -/datum/action/innate/regenerate_limbs - name = "Regenerate Limbs" - check_flags = AB_CHECK_CONSCIOUS - button_icon_state = "slimeheal" - icon_icon = 'icons/mob/actions/actions_slime.dmi' - background_icon_state = "bg_alien" - required_mobility_flags = NONE - -/datum/action/innate/regenerate_limbs/IsAvailable(silent = FALSE) - if(..()) - var/mob/living/carbon/human/H = owner - var/list/limbs_to_heal = H.get_missing_limbs() - if(limbs_to_heal.len < 1) - return 0 - if(H.blood_volume >= (BLOOD_VOLUME_OKAY*H.blood_ratio)+40) - return 1 - return 0 - -/datum/action/innate/regenerate_limbs/Activate() - var/mob/living/carbon/human/H = owner - var/list/limbs_to_heal = H.get_missing_limbs() - if(limbs_to_heal.len < 1) - to_chat(H, "You feel intact enough as it is.") - return - to_chat(H, "You focus intently on your missing [limbs_to_heal.len >= 2 ? "limbs" : "limb"]...") - if(H.blood_volume >= 40*limbs_to_heal.len+(BLOOD_VOLUME_OKAY*H.blood_ratio)) - H.regenerate_limbs() - H.blood_volume -= 40*limbs_to_heal.len - to_chat(H, "...and after a moment you finish reforming!") - return - else if(H.blood_volume >= 40)//We can partially heal some limbs - while(H.blood_volume >= (BLOOD_VOLUME_OKAY*H.blood_ratio)+40) - var/healed_limb = pick(limbs_to_heal) - H.regenerate_limb(healed_limb) - limbs_to_heal -= healed_limb - H.blood_volume -= 40 - to_chat(H, "...but there is not enough of you to fix everything! You must attain more mass to heal completely!") - return - to_chat(H, "...but there is not enough of you to go around! You must attain more mass to heal!") - - ////////////////////////////////////////////////////////SLIMEPEOPLE/////////////////////////////////////////////////////////////////// //Slime people are able to split like slimes, retaining a single mind that can swap between bodies at will, even after death. @@ -482,314 +428,6 @@ allowed_limb_ids = list(SPECIES_SLIME,SPECIES_STARGAZER,SPECIES_SLIME_LUMI) -/datum/action/innate/slime_change - name = "Alter Form" - check_flags = AB_CHECK_CONSCIOUS - button_icon_state = "alter_form" //placeholder - icon_icon = 'modular_citadel/icons/mob/actions/actions_slime.dmi' - background_icon_state = "bg_alien" - -/datum/action/innate/slime_change/Activate() - var/mob/living/carbon/human/H = owner - if(!isjellyperson(H)) - return - else - H.visible_message("[owner] gains a look of \ - concentration while standing perfectly still.\ - Their body seems to shift and starts getting more goo-like.", - "You focus intently on altering your body while \ - standing perfectly still...") - change_form() - -/datum/action/innate/slime_change/proc/change_form() - var/mob/living/carbon/human/H = owner - var/select_alteration = input(owner, "Select what part of your form to alter", "Form Alteration", "cancel") in list("Body Color","Hair Style", "Genitals", "Tail", "Snout", "Markings", "Ears", "Taur body", "Penis", "Vagina", "Penis Length", "Breast Size", "Breast Shape", "Cancel") - - if(select_alteration == "Body Color") - var/new_color = input(owner, "Choose your skin color:", "Race change","#"+H.dna.features["mcolor"]) as color|null - if(new_color) - var/temp_hsv = RGBtoHSV(new_color) - if(ReadHSV(temp_hsv)[3] >= ReadHSV(MINIMUM_MUTANT_COLOR)[3]) // mutantcolors must be bright - H.dna.features["mcolor"] = sanitize_hexcolor(new_color, 6) - H.update_body() - H.update_hair() - else - to_chat(H, "Invalid color. Your color is not bright enough.") - else if(select_alteration == "Hair Style") - if(H.gender == MALE) - var/new_style = input(owner, "Select a facial hair style", "Hair Alterations") as null|anything in GLOB.facial_hair_styles_list - if(new_style) - H.facial_hair_style = new_style - else - H.facial_hair_style = "Shaved" - //handle normal hair - var/new_style = input(owner, "Select a hair style", "Hair Alterations") as null|anything in GLOB.hair_styles_list - if(new_style) - H.hair_style = new_style - H.update_hair() - else if (select_alteration == "Genitals") - var/operation = input("Select organ operation.", "Organ Manipulation", "cancel") in list("add sexual organ", "remove sexual organ", "cancel") - switch(operation) - if("add sexual organ") - var/new_organ = input("Select sexual organ:", "Organ Manipulation") as null|anything in GLOB.genitals_list - if(!new_organ) - return - H.give_genital(GLOB.genitals_list[new_organ]) - - if("remove sexual organ") - var/list/organs = list() - for(var/obj/item/organ/genital/X in H.internal_organs) - var/obj/item/organ/I = X - organs["[I.name] ([I.type])"] = I - var/obj/item/O = input("Select sexual organ:", "Organ Manipulation", null) as null|anything in organs - var/obj/item/organ/genital/G = organs[O] - if(!G) - return - G.forceMove(get_turf(H)) - qdel(G) - H.update_genitals() - - else if (select_alteration == "Ears") - var/list/snowflake_ears_list = list("Normal" = null) - for(var/path in GLOB.mam_ears_list) - var/datum/sprite_accessory/ears/mam_ears/instance = GLOB.mam_ears_list[path] - if(istype(instance, /datum/sprite_accessory)) - var/datum/sprite_accessory/S = instance - if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(H.client.ckey))) - snowflake_ears_list[S.name] = path - var/new_ears - new_ears = input(owner, "Choose your character's ears:", "Ear Alteration") as null|anything in snowflake_ears_list - if(new_ears) - H.dna.features["mam_ears"] = new_ears - H.update_body() - - else if (select_alteration == "Snout") - var/list/snowflake_snouts_list = list("Normal" = null) - for(var/path in GLOB.mam_snouts_list) - var/datum/sprite_accessory/snouts/mam_snouts/instance = GLOB.mam_snouts_list[path] - if(istype(instance, /datum/sprite_accessory)) - var/datum/sprite_accessory/S = instance - if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(H.client.ckey))) - snowflake_snouts_list[S.name] = path - var/new_snout - new_snout = input(owner, "Choose your character's face:", "Face Alteration") as null|anything in snowflake_snouts_list - if(new_snout) - H.dna.features["mam_snouts"] = new_snout - H.update_body() - - else if (select_alteration == "Markings") - var/list/snowflake_markings_list = list("None") - for(var/path in GLOB.mam_body_markings_list) - var/datum/sprite_accessory/mam_body_markings/instance = GLOB.mam_body_markings_list[path] - if(istype(instance, /datum/sprite_accessory)) - var/datum/sprite_accessory/S = instance - if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(H.client.ckey))) - snowflake_markings_list[S.name] = path - var/new_mam_body_markings - new_mam_body_markings = input(H, "Choose your character's body markings:", "Marking Alteration") as null|anything in snowflake_markings_list - if(new_mam_body_markings) - H.dna.features["mam_body_markings"] = new_mam_body_markings - for(var/X in H.bodyparts) //propagates the markings changes - var/obj/item/bodypart/BP = X - BP.update_limb(FALSE, H) - H.update_body() - - else if (select_alteration == "Tail") - var/list/snowflake_tails_list = list("Normal" = null) - for(var/path in GLOB.mam_tails_list) - var/datum/sprite_accessory/tails/mam_tails/instance = GLOB.mam_tails_list[path] - if(istype(instance, /datum/sprite_accessory)) - var/datum/sprite_accessory/S = instance - if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(H.client.ckey))) - snowflake_tails_list[S.name] = path - var/new_tail - new_tail = input(owner, "Choose your character's Tail(s):", "Tail Alteration") as null|anything in snowflake_tails_list - if(new_tail) - H.dna.features["mam_tail"] = new_tail - if(new_tail != "None") - H.dna.features["taur"] = "None" - H.update_body() - - else if (select_alteration == "Taur body") - var/list/snowflake_taur_list = list("Normal" = null) - for(var/path in GLOB.taur_list) - var/datum/sprite_accessory/taur/instance = GLOB.taur_list[path] - if(istype(instance, /datum/sprite_accessory)) - var/datum/sprite_accessory/S = instance - if((!S.ckeys_allowed) || (S.ckeys_allowed.Find(H.client.ckey))) - snowflake_taur_list[S.name] = path - var/new_taur - new_taur = input(owner, "Choose your character's tauric body:", "Tauric Alteration") as null|anything in snowflake_taur_list - if(new_taur) - H.dna.features["taur"] = new_taur - if(new_taur != "None") - H.dna.features["mam_tail"] = "None" - H.update_body() - - else if (select_alteration == "Penis") - for(var/obj/item/organ/genital/penis/X in H.internal_organs) - qdel(X) - var/new_shape - new_shape = input(owner, "Choose your character's dong", "Genital Alteration") as null|anything in GLOB.cock_shapes_list - if(new_shape) - H.dna.features["cock_shape"] = new_shape - H.update_genitals() - H.give_genital(/obj/item/organ/genital/testicles) - H.give_genital(/obj/item/organ/genital/penis) - H.apply_overlay() - - - else if (select_alteration == "Vagina") - for(var/obj/item/organ/genital/vagina/X in H.internal_organs) - qdel(X) - var/new_shape - new_shape = input(owner, "Choose your character's pussy", "Genital Alteration") as null|anything in GLOB.vagina_shapes_list - if(new_shape) - H.dna.features["vag_shape"] = new_shape - H.update_genitals() - H.give_genital(/obj/item/organ/genital/womb) - H.give_genital(/obj/item/organ/genital/vagina) - H.apply_overlay() - - else if (select_alteration == "Penis Length") - for(var/obj/item/organ/genital/penis/X in H.internal_organs) - qdel(X) - var/min_D = CONFIG_GET(number/penis_min_inches_prefs) - var/max_D = CONFIG_GET(number/penis_max_inches_prefs) - var/new_length = input(owner, "Penis length in inches:\n([min_D]-[max_D])", "Genital Alteration") as num|null - if(new_length) - H.dna.features["cock_length"] = clamp(round(new_length), min_D, max_D) - H.update_genitals() - H.apply_overlay() - H.give_genital(/obj/item/organ/genital/testicles) - H.give_genital(/obj/item/organ/genital/penis) - - else if (select_alteration == "Breast Size") - for(var/obj/item/organ/genital/breasts/X in H.internal_organs) - qdel(X) - var/new_size = input(owner, "Breast Size", "Genital Alteration") as null|anything in CONFIG_GET(keyed_list/breasts_cups_prefs) - if(new_size) - H.dna.features["breasts_size"] = new_size - H.update_genitals() - H.apply_overlay() - H.give_genital(/obj/item/organ/genital/breasts) - - else if (select_alteration == "Breast Shape") - for(var/obj/item/organ/genital/breasts/X in H.internal_organs) - qdel(X) - var/new_shape - new_shape = input(owner, "Breast Shape", "Genital Alteration") as null|anything in GLOB.breasts_shapes_list - if(new_shape) - H.dna.features["breasts_shape"] = new_shape - H.update_genitals() - H.apply_overlay() - H.give_genital(/obj/item/organ/genital/breasts) - - else - return - -/datum/action/innate/slime_puddle - name = "Puddle Transformation" - check_flags = AB_CHECK_CONSCIOUS - button_icon_state = "slimepuddle" - icon_icon = 'icons/mob/actions/actions_slime.dmi' - background_icon_state = "bg_alien" - required_mobility_flags = MOBILITY_STAND - var/is_puddle = FALSE - var/in_transformation_duration = 12 - var/out_transformation_duration = 7 - var/puddle_into_effect = /obj/effect/temp_visual/slime_puddle - var/puddle_from_effect = /obj/effect/temp_visual/slime_puddle/reverse - var/puddle_icon = 'icons/mob/mob.dmi' - var/puddle_state = "puddle" - var/tracked_overlay - var/datum/component/squeak/squeak - var/transforming = FALSE - var/last_use - -/datum/action/innate/slime_puddle/IsAvailable() - if(!transforming) - return ..() - else - return FALSE - -/datum/action/innate/slime_puddle/Activate() - var/mob/living/carbon/human/H = owner - //if they have anything stuck to their hands, we immediately say 'no' and return - for(var/obj/item/I in H.held_items) - if(HAS_TRAIT(I, TRAIT_NODROP)) - to_chat(owner, "There's something stuck to your hand, stopping you from transforming!") - return - if(isjellyperson(owner) && IsAvailable()) - transforming = TRUE - UpdateButtonIcon() - var/mutcolor = "#" + H.dna.features["mcolor"] - if(!is_puddle) - if(CHECK_MOBILITY(H, MOBILITY_USE)) //if we can use items, we can turn into a puddle - is_puddle = TRUE //so we know which transformation to use when its used - owner.cut_overlays() //we dont show our normal sprite, we show a puddle sprite - var/obj/effect/puddle_effect = new puddle_into_effect(get_turf(owner), owner.dir) - puddle_effect.color = mutcolor - H.Stun(in_transformation_duration, ignore_canstun = TRUE) //cant move while transforming - - //series of traits that make up the puddle behaviour - ADD_TRAIT(H, TRAIT_PARALYSIS_L_ARM, SLIMEPUDDLE_TRAIT) - ADD_TRAIT(H, TRAIT_PARALYSIS_R_ARM, SLIMEPUDDLE_TRAIT) - ADD_TRAIT(H, TRAIT_MOBILITY_NOPICKUP, SLIMEPUDDLE_TRAIT) - ADD_TRAIT(H, TRAIT_MOBILITY_NOUSE, SLIMEPUDDLE_TRAIT) - ADD_TRAIT(H, TRAIT_SPRINT_LOCKED, SLIMEPUDDLE_TRAIT) - ADD_TRAIT(H, TRAIT_COMBAT_MODE_LOCKED, SLIMEPUDDLE_TRAIT) - ADD_TRAIT(H, TRAIT_MOBILITY_NOREST, SLIMEPUDDLE_TRAIT) - ADD_TRAIT(H, TRAIT_ARMOR_BROKEN, SLIMEPUDDLE_TRAIT) - H.update_disabled_bodyparts(silent = TRUE) //silently update arms to be paralysed - - H.add_movespeed_modifier(/datum/movespeed_modifier/slime_puddle) - - H.layer -= 1 //go one layer down so people go over you - ENABLE_BITFIELD(H.pass_flags, PASSMOB) //this actually lets people pass over you - squeak = H.AddComponent(/datum/component/squeak, custom_sounds = list('sound/effects/blobattack.ogg')) //blorble noise when people step on you - - //if the user is a changeling, retract their sting - H.unset_sting() - - sleep(in_transformation_duration) //wait for animation to end - - //set the puddle overlay up - var/mutable_appearance/puddle_overlay = mutable_appearance(icon = puddle_icon, icon_state = puddle_state) - puddle_overlay.color = mutcolor - tracked_overlay = puddle_overlay - owner.add_overlay(puddle_overlay) - - transforming = FALSE - UpdateButtonIcon() - else - //like the above, but reverse everything done! - owner.cut_overlay(tracked_overlay) - var/obj/effect/puddle_effect = new puddle_from_effect(get_turf(owner), owner.dir) - puddle_effect.color = mutcolor - H.Stun(out_transformation_duration, ignore_canstun = TRUE) - sleep(out_transformation_duration) - REMOVE_TRAIT(H, TRAIT_PARALYSIS_L_ARM, SLIMEPUDDLE_TRAIT) - REMOVE_TRAIT(H, TRAIT_PARALYSIS_R_ARM, SLIMEPUDDLE_TRAIT) - REMOVE_TRAIT(H, TRAIT_MOBILITY_NOPICKUP, SLIMEPUDDLE_TRAIT) - REMOVE_TRAIT(H, TRAIT_MOBILITY_NOUSE, SLIMEPUDDLE_TRAIT) - REMOVE_TRAIT(H, TRAIT_SPRINT_LOCKED, SLIMEPUDDLE_TRAIT) - REMOVE_TRAIT(H, TRAIT_COMBAT_MODE_LOCKED, SLIMEPUDDLE_TRAIT) - REMOVE_TRAIT(H, TRAIT_MOBILITY_NOREST, SLIMEPUDDLE_TRAIT) - REMOVE_TRAIT(H, TRAIT_ARMOR_BROKEN, SLIMEPUDDLE_TRAIT) - H.update_disabled_bodyparts(silent = TRUE) - H.remove_movespeed_modifier(/datum/movespeed_modifier/slime_puddle) - H.layer += 1 //go one layer back above! - DISABLE_BITFIELD(H.pass_flags, PASSMOB) - is_puddle = FALSE - if(squeak) - squeak.RemoveComponent() - owner.regenerate_icons() - transforming = FALSE - UpdateButtonIcon() - else - to_chat(owner, "You need to be standing up to do this!") //just assume they're a slime because it's such a weird edgecase to have it and not be one (it shouldn't even be possible) - ///////////////////////////////////LUMINESCENTS////////////////////////////////////////// //Luminescents are able to consume and use slime extracts, without them decaying. diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 7d7d420128..f96974f09e 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -48,18 +48,22 @@ There are several things that need to be remembered: */ +/mob/living/carbon/human/ComponentInitialize() + . = ..() + RegisterSignal(src, SIGNAL_TRAIT(TRAIT_HUMAN_NO_RENDER), /mob.proc/regenerate_icons) + //HAIR OVERLAY /mob/living/carbon/human/update_hair() - if(dna.species.should_render()) + if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) dna.species.handle_hair(src) //used when putting/removing clothes that hide certain mutant body parts to just update those and not update the whole body. /mob/living/carbon/human/proc/update_mutant_bodyparts() - if(dna.species.should_render()) + if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) dna.species.handle_mutant_bodyparts(src) /mob/living/carbon/human/update_body(update_genitals = FALSE) - if(dna.species.should_render()) + if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(BODY_LAYER) dna.species.handle_body(src) ..() @@ -69,11 +73,10 @@ There are several things that need to be remembered: /mob/living/carbon/human/update_fire() ..((fire_stacks > 3) ? "Standing" : "Generic_mob_burning") - /* --------------------------------------- */ //For legacy support. /mob/living/carbon/human/regenerate_icons() - if(dna.species.should_render()) + if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) if(!..()) icon_render_key = null //invalidate bodyparts cache update_body(TRUE) @@ -102,7 +105,7 @@ There are several things that need to be remembered: //vvvvvv UPDATE_INV PROCS vvvvvv /mob/living/carbon/human/update_inv_w_uniform() - if(dna.species.should_render()) + if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(UNIFORM_LAYER) if(client && hud_used) @@ -154,7 +157,7 @@ There are several things that need to be remembered: update_mutant_bodyparts() /mob/living/carbon/human/update_inv_wear_id() - if(dna.species.should_render()) + if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(ID_LAYER) if(client && hud_used) @@ -179,7 +182,7 @@ There are several things that need to be remembered: /mob/living/carbon/human/update_inv_gloves() - if(dna.species.should_render()) + if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(GLOVES_LAYER) if(client && hud_used && hud_used.inv_slots[SLOT_GLOVES]) @@ -213,7 +216,7 @@ There are several things that need to be remembered: /mob/living/carbon/human/update_inv_glasses() - if(dna.species.should_render()) + if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(GLASSES_LAYER) if(!get_bodypart(BODY_ZONE_HEAD)) //decapitated @@ -240,7 +243,7 @@ There are several things that need to be remembered: apply_overlay(GLASSES_LAYER) /mob/living/carbon/human/update_inv_ears() - if(dna.species.should_render()) + if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(EARS_LAYER) if(!get_bodypart(BODY_ZONE_HEAD)) //decapitated @@ -266,7 +269,7 @@ There are several things that need to be remembered: apply_overlay(EARS_LAYER) /mob/living/carbon/human/update_inv_shoes() - if(dna.species.should_render()) + if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(SHOES_LAYER) if(get_num_legs(FALSE) <2) @@ -304,7 +307,7 @@ There are several things that need to be remembered: apply_overlay(SHOES_LAYER) /mob/living/carbon/human/update_inv_s_store() - if(dna.species.should_render()) + if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(SUIT_STORE_LAYER) if(client && hud_used) @@ -328,7 +331,7 @@ There are several things that need to be remembered: apply_overlay(SUIT_STORE_LAYER) /mob/living/carbon/human/update_inv_head() - if(dna.species.should_render()) + if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(HEAD_LAYER) if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated @@ -368,7 +371,7 @@ There are several things that need to be remembered: update_mutant_bodyparts() /mob/living/carbon/human/update_inv_belt() - if(dna.species.should_render()) + if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(BELT_LAYER) if(client && hud_used) @@ -390,7 +393,7 @@ There are several things that need to be remembered: apply_overlay(BELT_LAYER) /mob/living/carbon/human/update_inv_wear_suit() - if(dna.species.should_render()) + if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(SUIT_LAYER) if(client && hud_used) @@ -477,7 +480,7 @@ There are several things that need to be remembered: /mob/living/carbon/human/update_inv_wear_mask() - if(dna.species.should_render()) + if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) remove_overlay(FACEMASK_LAYER) if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated @@ -518,7 +521,7 @@ There are several things that need to be remembered: update_mutant_bodyparts() //e.g. upgate needed because mask now hides lizard snout /mob/living/carbon/human/update_inv_back() - if(dna.species.should_render()) + if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) ..() var/mutable_appearance/back_overlay = overlays_standing[BACK_LAYER] if(back_overlay) @@ -741,7 +744,7 @@ use_mob_overlay_icon: if FALSE, it will always use the default_icon_file even if if(!dna.species) return - if(dna.species.should_render()) + if(!HAS_TRAIT(src, TRAIT_HUMAN_NO_RENDER)) return var/obj/item/bodypart/HD = get_bodypart("head") diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index da03c4b533..8a03960eb8 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -34,6 +34,7 @@ ranged_ability.remove_ranged_ability(src) if(buckled) buckled.unbuckle_mob(src,force=1) + QDEL_LIST_ASSOC_VAL(ability_actions) remove_from_all_data_huds() GLOB.mob_living_list -= src diff --git a/code/modules/mob/living/living_mobility.dm b/code/modules/mob/living/living_mobility.dm index 8c6cf9d207..62c23cca9b 100644 --- a/code/modules/mob/living/living_mobility.dm +++ b/code/modules/mob/living/living_mobility.dm @@ -6,6 +6,7 @@ RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOPICKUP), .proc/update_mobility) RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOUSE), .proc/update_mobility) RegisterSignal(src, SIGNAL_TRAIT(TRAIT_MOBILITY_NOREST), .proc/update_mobility) + RegisterSignal(src, SIGNAL_TRAIT(TRAIT_LIVING_NO_DENSITY), .proc/update_density) //Stuff like mobility flag updates, resting updates, etc. @@ -148,7 +149,7 @@ L.update_pull_movespeed() //Handle lying down, voluntary or involuntary - density = !lying + update_density() if(lying) set_resting(TRUE, TRUE, FALSE) if(layer == initial(layer)) //to avoid special cases like hiding larvas. diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm index 75d712afb9..0cdfe9dbf2 100644 --- a/code/modules/mob/living/living_movement.dm +++ b/code/modules/mob/living/living_movement.dm @@ -17,6 +17,9 @@ pixel_x = get_standard_pixel_x_offset(lying) pixel_y = get_standard_pixel_y_offset(lying) +/mob/living/proc/update_density() + density = !lying && !HAS_TRAIT(src, TRAIT_LIVING_NO_DENSITY) + /mob/living/CanPass(atom/movable/mover, turf/target) if((mover.pass_flags & PASSMOB)) return TRUE diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 8c6b722140..dc81b3cfbf 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -11,7 +11,7 @@ blocks_emissive = EMISSIVE_BLOCK_GENERIC vis_flags = VIS_INHERIT_PLANE //when this be added to vis_contents of something it inherit something.plane, important for visualisation of mob in openspace. - + attack_hand_is_action = TRUE attack_hand_unwieldlyness = CLICK_CD_MELEE attack_hand_speed = 0 @@ -169,3 +169,11 @@ var/typing_indicator_timerid /// Current state of our typing indicator. Used for cut overlay, DO NOT RUNTIME ASSIGN OTHER THAN FROM SHOW/CLEAR. Used to absolutely ensure we do not get stuck overlays. var/mutable_appearance/typing_indicator_current + + /// Ability system based on action buttons. Can be ported to base /mob or /mob/living later if needed, easily - the procs are currently on living/carbon/human/innate_abilities.dm + /// datum traits-style lazylist of abilities + var/list/innate_abilities + /// ability = action button instance. + var/list/ability_actions + /// ability = list(data). see __DEFINES/mobs/innate_abilities.dm + var/list/ability_properties diff --git a/tgstation.dme b/tgstation.dme index 55b7dee5d9..5c3f1d5a4f 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -145,6 +145,7 @@ #include "code\__DEFINES\dcs\signals.dm" #include "code\__DEFINES\mapping\maploader.dm" #include "code\__DEFINES\material\worth.dm" +#include "code\__DEFINES\mobs\innate_abilities.dm" #include "code\__DEFINES\mobs\slowdowns.dm" #include "code\__DEFINES\research\anomalies.dm" #include "code\__DEFINES\research\stock_parts.dm" @@ -2402,6 +2403,7 @@ #include "code\modules\mob\clickdelay.dm" #include "code\modules\mob\death.dm" #include "code\modules\mob\emote.dm" +#include "code\modules\mob\innate_abilities.dm" #include "code\modules\mob\inventory.dm" #include "code\modules\mob\login.dm" #include "code\modules\mob\logout.dm" @@ -2555,6 +2557,9 @@ #include "code\modules\mob\living\carbon\human\status_procs.dm" #include "code\modules\mob\living\carbon\human\typing_indicator.dm" #include "code\modules\mob\living\carbon\human\update_icons.dm" +#include "code\modules\mob\living\carbon\human\innate_abilities\blobform.dm" +#include "code\modules\mob\living\carbon\human\innate_abilities\customization.dm" +#include "code\modules\mob\living\carbon\human\innate_abilities\limb_regeneration.dm" #include "code\modules\mob\living\carbon\human\species_types\abductor.dm" #include "code\modules\mob\living\carbon\human\species_types\android.dm" #include "code\modules\mob\living\carbon\human\species_types\angel.dm" From 86b584fab5591d9e65908ea85fa90bac64d1d773 Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Sat, 21 Nov 2020 21:08:55 -0700 Subject: [PATCH 2/7] typos --- code/__DEFINES/mobs/innate_abilities.dm | 2 +- code/modules/mob/innate_abilities.dm | 2 +- .../carbon/human/innate_abilities/blobform.dm | 6 +++--- .../carbon/human/innate_abilities/customization.dm | 4 ++-- .../carbon/human/species_types/jellypeople.dm | 13 ------------- 5 files changed, 7 insertions(+), 20 deletions(-) diff --git a/code/__DEFINES/mobs/innate_abilities.dm b/code/__DEFINES/mobs/innate_abilities.dm index 563a48deec..d2d3dbbc67 100644 --- a/code/__DEFINES/mobs/innate_abilities.dm +++ b/code/__DEFINES/mobs/innate_abilities.dm @@ -25,5 +25,5 @@ /// limb regrowth usage type #define PROPERTY_LIMB_REGROWTH_USAGE_TYPE "cost" /// blood - #define REGRWOTH_USES_BLOOD "blood" + #define REGROWTH_USES_BLOOD "blood" diff --git a/code/modules/mob/innate_abilities.dm b/code/modules/mob/innate_abilities.dm index 2c77d9c64c..df80cea98c 100644 --- a/code/modules/mob/innate_abilities.dm +++ b/code/modules/mob/innate_abilities.dm @@ -12,7 +12,7 @@ /mob/proc/get_ability_property(ability, property) return ability_properties && ability_properties[ability] && ability_properties[ability][property] -GLOBAL_LIST_INIT(innate_ability_typepaths, all_innate_ability_typepaths) +GLOBAL_LIST_INIT(innate_ability_typepaths, all_innate_ability_typepaths()) /proc/all_innate_ability_typepaths() return list( diff --git a/code/modules/mob/living/carbon/human/innate_abilities/blobform.dm b/code/modules/mob/living/carbon/human/innate_abilities/blobform.dm index df67f8b54d..101e19f9aa 100644 --- a/code/modules/mob/living/carbon/human/innate_abilities/blobform.dm +++ b/code/modules/mob/living/carbon/human/innate_abilities/blobform.dm @@ -13,7 +13,7 @@ var/puddle_from_effect = /obj/effect/temp_visual/slime_puddle/reverse var/puddle_icon = 'icons/mob/mob.dmi' var/puddle_state = "puddle" - var/tracked_overlay + var/mutable_appearance/tracked_overlay var/datum/component/squeak/squeak var/transforming = FALSE var/last_use @@ -39,7 +39,7 @@ if(IsAvailable()) transforming = TRUE UpdateButtonIcon() - var/mutcolor = get_ability_property(INNATE_ABILITY_SLIME_BLOBFORM, PROPERTY_BLOFMROM_COLOR) || ("#" + H.dna.features["mcolor"]) + var/mutcolor = owner.get_ability_property(INNATE_ABILITY_SLIME_BLOBFORM, PROPERTY_BLOBFORM_COLOR) || ("#" + H.dna.features["mcolor"]) if(!is_puddle) if(CHECK_MOBILITY(H, MOBILITY_USE)) //if we can use items, we can turn into a puddle is_puddle = TRUE //so we know which transformation to use when its used @@ -88,7 +88,7 @@ //like the above, but reverse everything done! H.cut_overlay(tracked_overlay) var/obj/effect/puddle_effect = new puddle_from_effect(get_turf(owner), owner.dir) - puddle_effect.color = mutcolor + puddle_effect.color = tracked_overlay.color H.Stun(out_transformation_duration, ignore_canstun = TRUE) sleep(out_transformation_duration) REMOVE_TRAIT(H, TRAIT_PARALYSIS_L_ARM, SLIMEPUDDLE_TRAIT) diff --git a/code/modules/mob/living/carbon/human/innate_abilities/customization.dm b/code/modules/mob/living/carbon/human/innate_abilities/customization.dm index e1af0f53e2..363f6ecbb2 100644 --- a/code/modules/mob/living/carbon/human/innate_abilities/customization.dm +++ b/code/modules/mob/living/carbon/human/innate_abilities/customization.dm @@ -6,7 +6,7 @@ background_icon_state = "bg_alien" /datum/action/innate/ability/humanoid_customization/Activate() - if(owner.get_ability_property(INNATE_ABILITY_HUMANOID_CUSTOMIZATION, ABILITY_CUSTOMIZATION_SILENT)) + if(owner.get_ability_property(INNATE_ABILITY_HUMANOID_CUSTOMIZATION, PROPERTY_CUSTOMIZATION_SILENT)) owner.visible_message("[owner] gains a look of \ concentration while standing perfectly still.\ Their body seems to shift and starts getting more goo-like.", @@ -20,7 +20,7 @@ ///// maybe just make this entire thing tgui based. maybe. /////// -/datum/action/innate/slime_change/proc/change_form() +/datum/action/innate/ability/humanoid_customization/proc/change_form() var/mob/living/carbon/human/H = owner var/select_alteration = input(owner, "Select what part of your form to alter", "Form Alteration", "cancel") in list("Body Color","Hair Style", "Genitals", "Tail", "Snout", "Markings", "Ears", "Taur body", "Penis", "Vagina", "Penis Length", "Breast Size", "Breast Shape", "Cancel") 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 c369625dc6..3ead134ce4 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -15,9 +15,6 @@ exotic_bloodtype = "GEL" exotic_blood_color = "BLOOD_COLOR_SLIME" damage_overlay_type = "" - var/datum/action/innate/regenerate_limbs/regenerate_limbs - var/datum/action/innate/slime_change/slime_change - var/datum/action/innate/slime_puddle/slime_puddle liked_food = TOXIC | MEAT disliked_food = null toxic_food = ANTITOXIC @@ -37,14 +34,6 @@ icon_state = "brain-slime" /datum/species/jelly/on_species_loss(mob/living/carbon/C) - if(slime_puddle && slime_puddle.is_puddle) - slime_puddle.Activate() - if(regenerate_limbs) - regenerate_limbs.Remove(C) - if(slime_change) - slime_change.Remove(C) - if(slime_puddle) - slime_puddle.Remove(C) C.faction -= "slime" if(ishuman(C)) var/mob/living/carbon/human/H = C @@ -81,8 +70,6 @@ to_chat(H, "You feel drained!") if(H.blood_volume < (BLOOD_VOLUME_BAD*H.blood_ratio)) Cannibalize_Body(H) - if(regenerate_limbs) - regenerate_limbs.UpdateButtonIcon() /datum/species/jelly/proc/Cannibalize_Body(mob/living/carbon/human/H) var/list/limbs_to_consume = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_R_LEG, BODY_ZONE_L_LEG) - H.get_missing_limbs() From 5a127f6cb5e1a38aac9b980dc45c2638af7be4ac Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Sat, 21 Nov 2020 23:32:10 -0700 Subject: [PATCH 3/7] sigh --- code/modules/mining/mine_items.dm | 2 +- code/modules/mob/innate_abilities.dm | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 6fea45d491..6eaaa8887f 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -79,7 +79,7 @@ no_destination_swap = TRUE var/static/list/dumb_rev_heads = list() - /obj/machinery/computer/shuttle/mining/common +/obj/machinery/computer/shuttle/mining/common name = "lavaland shuttle console" desc = "Used to call and send the lavaland shuttle." req_access = list() diff --git a/code/modules/mob/innate_abilities.dm b/code/modules/mob/innate_abilities.dm index df80cea98c..5808b2079b 100644 --- a/code/modules/mob/innate_abilities.dm +++ b/code/modules/mob/innate_abilities.dm @@ -27,13 +27,17 @@ GLOBAL_LIST_INIT(innate_ability_typepaths, all_innate_ability_typepaths()) /mob/proc/grant_ability_from_source(list/abilities, source) if(!islist(abilities)) abilities = list(abilities) + LAZYINITLIST(ability_actions) + LAZYINITLIST(innate_abilities) + to_chat(world, "DEBUG: granting list [english_list(abilities)]") for(var/ability in abilities) - LAZYINITLIST(innate_abilities) LAZYINITLIST(innate_abilities[ability]) innate_abilities[ability] |= source + to_chat(world, "DEBG: granting [ability]") if(ability_actions[ability]) - return - var/datum/action/innate/ability/A = ability_actions[ability] = new GLOB.innate_ability_typepaths[ability] + continue + var/datum/action/innate/ability/A = new GLOB.innate_ability_typepaths[ability] + ability_actions[ability] = A A.Grant(src) /** @@ -42,9 +46,11 @@ GLOBAL_LIST_INIT(innate_ability_typepaths, all_innate_ability_typepaths()) /mob/proc/remove_ability_from_source(list/abilities, source) if(!islist(abilities)) abilities = list(abilities) + if(!length(innate_abilities)) + return for(var/ability in abilities) - if(!innate_abilities || !length(innate_abilities[ability])) - return + if(!length(innate_abilities[ability])) + continue innate_abilities[ability] -= source if(!length(innate_abilities[ability])) innate_abilities -= ability From 31fa58a9e958d52de10bdabf422bdcd3f0509a4b Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Sun, 22 Nov 2020 02:48:37 -0700 Subject: [PATCH 4/7] fix --- code/modules/mob/innate_abilities.dm | 5 ++--- .../mob/living/carbon/human/innate_abilities/blobform.dm | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/code/modules/mob/innate_abilities.dm b/code/modules/mob/innate_abilities.dm index 5808b2079b..aa2a924abe 100644 --- a/code/modules/mob/innate_abilities.dm +++ b/code/modules/mob/innate_abilities.dm @@ -29,14 +29,13 @@ GLOBAL_LIST_INIT(innate_ability_typepaths, all_innate_ability_typepaths()) abilities = list(abilities) LAZYINITLIST(ability_actions) LAZYINITLIST(innate_abilities) - to_chat(world, "DEBUG: granting list [english_list(abilities)]") for(var/ability in abilities) LAZYINITLIST(innate_abilities[ability]) innate_abilities[ability] |= source - to_chat(world, "DEBG: granting [ability]") if(ability_actions[ability]) continue - var/datum/action/innate/ability/A = new GLOB.innate_ability_typepaths[ability] + var/path = GLOB.innate_ability_typepaths[ability] + var/datum/action/innate/ability/A = new path ability_actions[ability] = A A.Grant(src) diff --git a/code/modules/mob/living/carbon/human/innate_abilities/blobform.dm b/code/modules/mob/living/carbon/human/innate_abilities/blobform.dm index 101e19f9aa..e0da0c92e9 100644 --- a/code/modules/mob/living/carbon/human/innate_abilities/blobform.dm +++ b/code/modules/mob/living/carbon/human/innate_abilities/blobform.dm @@ -43,6 +43,7 @@ if(!is_puddle) if(CHECK_MOBILITY(H, MOBILITY_USE)) //if we can use items, we can turn into a puddle is_puddle = TRUE //so we know which transformation to use when its used + ADD_TRIAT(H, TRAIT_HUMAN_NO_RENDER, SLIMEPUDDLE_TRAIT) owner.cut_overlays() //we dont show our normal sprite, we show a puddle sprite var/obj/effect/puddle_effect = new puddle_into_effect(get_turf(owner), owner.dir) puddle_effect.color = mutcolor @@ -99,6 +100,7 @@ REMOVE_TRAIT(H, TRAIT_COMBAT_MODE_LOCKED, SLIMEPUDDLE_TRAIT) REMOVE_TRAIT(H, TRAIT_MOBILITY_NOREST, SLIMEPUDDLE_TRAIT) REMOVE_TRAIT(H, TRAIT_ARMOR_BROKEN, SLIMEPUDDLE_TRAIT) + REMOVE_TRAIT(H, TRAIT_HUMAN_NO_RENDER, SLIME_PUDDLE_TRAIT) H.update_disabled_bodyparts(silent = TRUE) H.remove_movespeed_modifier(/datum/movespeed_modifier/slime_puddle) H.layer += 1 //go one layer back above! @@ -106,6 +108,5 @@ is_puddle = FALSE if(squeak) squeak.RemoveComponent() - owner.regenerate_icons() transforming = FALSE UpdateButtonIcon() From 0554ccbba471083fc4ad6e73536492f0439a8559 Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Sun, 22 Nov 2020 13:32:48 -0700 Subject: [PATCH 5/7] fix --- .../mob/living/carbon/human/innate_abilities/blobform.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/carbon/human/innate_abilities/blobform.dm b/code/modules/mob/living/carbon/human/innate_abilities/blobform.dm index e0da0c92e9..5d2693915d 100644 --- a/code/modules/mob/living/carbon/human/innate_abilities/blobform.dm +++ b/code/modules/mob/living/carbon/human/innate_abilities/blobform.dm @@ -43,7 +43,7 @@ if(!is_puddle) if(CHECK_MOBILITY(H, MOBILITY_USE)) //if we can use items, we can turn into a puddle is_puddle = TRUE //so we know which transformation to use when its used - ADD_TRIAT(H, TRAIT_HUMAN_NO_RENDER, SLIMEPUDDLE_TRAIT) + ADD_TRAIT(H, TRAIT_HUMAN_NO_RENDER, SLIMEPUDDLE_TRAIT) owner.cut_overlays() //we dont show our normal sprite, we show a puddle sprite var/obj/effect/puddle_effect = new puddle_into_effect(get_turf(owner), owner.dir) puddle_effect.color = mutcolor @@ -100,7 +100,7 @@ REMOVE_TRAIT(H, TRAIT_COMBAT_MODE_LOCKED, SLIMEPUDDLE_TRAIT) REMOVE_TRAIT(H, TRAIT_MOBILITY_NOREST, SLIMEPUDDLE_TRAIT) REMOVE_TRAIT(H, TRAIT_ARMOR_BROKEN, SLIMEPUDDLE_TRAIT) - REMOVE_TRAIT(H, TRAIT_HUMAN_NO_RENDER, SLIME_PUDDLE_TRAIT) + REMOVE_TRAIT(H, TRAIT_HUMAN_NO_RENDER, SLIMEPUDDLE_TRAIT) H.update_disabled_bodyparts(silent = TRUE) H.remove_movespeed_modifier(/datum/movespeed_modifier/slime_puddle) H.layer += 1 //go one layer back above! From e7c02de01ead391898886cba5168ff35b35d1ba5 Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Thu, 26 Nov 2020 23:16:25 -0700 Subject: [PATCH 6/7] k --- .../modules/mob/living/carbon/human/species_types/jellypeople.dm | 1 + 1 file changed, 1 insertion(+) 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 3ead134ce4..2d00dfca94 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -46,6 +46,7 @@ if(ishuman(C)) var/mob/living/carbon/human/H = C H.grant_ability_from_source(list(INNATE_ABILITY_SLIME_BLOBFORM, INNATE_ABILITY_LIMB_REGROWTH, INNATE_ABILITY_HUMANOID_CUSTOMIZATION), ABILITY_SOURCE_SPECIES) + H.set_ability_property(INNATE_ABILITY_LIMB_REGROWTH, PROPERTY_LIMB_REGROWTH_USAGE_TYPE, REGRWOTH_USES_BLOOD) C.faction |= "slime" /datum/species/jelly/handle_body(mob/living/carbon/human/H) From 0d6986d3a25b1a00e3f2ae4d52aaf8d78f91e91d Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Fri, 27 Nov 2020 02:25:41 -0700 Subject: [PATCH 7/7] Update jellypeople.dm --- .../mob/living/carbon/human/species_types/jellypeople.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 2d00dfca94..988bf81f57 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -46,7 +46,7 @@ if(ishuman(C)) var/mob/living/carbon/human/H = C H.grant_ability_from_source(list(INNATE_ABILITY_SLIME_BLOBFORM, INNATE_ABILITY_LIMB_REGROWTH, INNATE_ABILITY_HUMANOID_CUSTOMIZATION), ABILITY_SOURCE_SPECIES) - H.set_ability_property(INNATE_ABILITY_LIMB_REGROWTH, PROPERTY_LIMB_REGROWTH_USAGE_TYPE, REGRWOTH_USES_BLOOD) + H.set_ability_property(INNATE_ABILITY_LIMB_REGROWTH, PROPERTY_LIMB_REGROWTH_USAGE_TYPE, REGROWTH_USES_BLOOD) C.faction |= "slime" /datum/species/jelly/handle_body(mob/living/carbon/human/H)