diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 0c651d4a541..198d6d8bf2b 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -119,6 +119,8 @@ #define SPECIES_LIZARD_SILVER "silverscale" #define SPECIES_NIGHTMARE "nightmare" #define SPECIES_MONKEY "monkey" +#define SPECIES_MONKEY_FREAK "monkey_freak" +#define SPECIES_MONKEY_HUMAN_LEGGED "monkey_human_legged" #define SPECIES_MOTH "moth" #define SPECIES_MUSHROOM "mush" #define SPECIES_PLASMAMAN "plasmaman" @@ -126,6 +128,7 @@ #define SPECIES_SHADOW "shadow" #define SPECIES_SKELETON "skeleton" #define SPECIES_SNAIL "snail" +#define SPECIES_TALLBOY "tallboy" #define SPECIES_VAMPIRE "vampire" #define SPECIES_ZOMBIE "zombie" #define SPECIES_ZOMBIE_INFECTIOUS "memezombie" diff --git a/code/game/machinery/dna_infuser/infuser_entries.dm b/code/game/machinery/dna_infuser/infuser_entries.dm deleted file mode 100644 index 72de6965022..00000000000 --- a/code/game/machinery/dna_infuser/infuser_entries.dm +++ /dev/null @@ -1,181 +0,0 @@ -/// A list of all infuser entries -GLOBAL_LIST_INIT(infuser_entries, prepare_entries()) - -/// just clarifying that no threshold does some special stuff, since only meme mutants have it -#define NO_THRESHOLD "" - -/proc/prepare_entries() - var/list/entries = list() - //regardless of names we want the failed mutant case to show first - var/prepended - for(var/datum/infuser_entry/entry_type as anything in typesof(/datum/infuser_entry)) - var/datum/infuser_entry/entry = new entry_type() - if(entry.type == /datum/infuser_entry) - prepended = entry - continue - entries += entry - var/list/sorted = sort_names(entries) - sorted.Insert(1, prepended) - return sorted - -/datum/infuser_entry - //info for the book - - /// name of the mutant you become - var/name = "Rejected" - /// what you have to infuse to become it - var/infuse_mob_name = "rejected creature" - /// general desc - var/desc = "For whatever reason, when the body rejects DNA, the DNA goes sour, ending up as some kind of fly-like DNA jumble." - /// desc of what passing the threshold gets you. if this is empty, there is no threshold, so this is also really a tally of whether this is a "meme" mutant or not - var/threshold_desc = "the DNA mess takes over, and you become a full-fledged flyperson." - /// various little bits - var/list/qualities = list( - "buzzy-like speech", - "vomit drinking", - "unidentifiable organs", - "this is a bad idea", - ) - - //info for the machine - - /// ...THINGS, mobs or items, the machine will infuse to make output organs - var/list/input_obj_or_mob = list( - ///rejected creatures, of course, are anything not covered by other recipes. This is a special case - ) - /// organs that the machine could spit out in relation - var/list/output_organs = list( - /obj/item/organ/internal/appendix/fly, - /obj/item/organ/internal/eyes/fly, - /obj/item/organ/internal/heart/fly, - /obj/item/organ/internal/lungs/fly, - /obj/item/organ/internal/stomach/fly, - /obj/item/organ/internal/tongue/fly, - ) - ///message the target gets while being infused - var/infusion_desc = "fly-like" - -/datum/infuser_entry/rat - name = "Rat" - infuse_mob_name = "rodent" - desc = "Frail, small, positively cheesed to face the world. Easy to stuff yourself full of rat DNA, but perhaps not the best choice?" - threshold_desc = "you become lithe enough to crawl through ventilation." - qualities = list( - "cheesy lines", - "will eat anything", - "wants to eat anything, constantly", - "frail but quick", - ) - input_obj_or_mob = list( - /obj/item/food/deadmouse, - ) - output_organs = list( - /obj/item/organ/internal/eyes/night_vision/rat, - /obj/item/organ/internal/heart/rat, - /obj/item/organ/internal/stomach/rat, - /obj/item/organ/internal/tongue/rat, - ) - infusion_desc = "skittish" - -/datum/infuser_entry/carp - name = "Carp" - infuse_mob_name = "space-cyprinidae" - desc = "Carp-mutants are very well-prepared for long term deep space exploration. In fact, they can't stand not doing it!" - threshold_desc = "you learn how to propel yourself through space. Like a fish!" - qualities = list( - "big jaws, big teeth", - "swim through space, no problem", - "face every problem when you go back on station", - "always wants to travel", - ) - input_obj_or_mob = list( - /mob/living/basic/carp, - ) - output_organs = list( - /obj/item/organ/internal/brain/carp, - /obj/item/organ/internal/heart/carp, - /obj/item/organ/internal/lungs/carp, - /obj/item/organ/internal/tongue/carp, - ) - infusion_desc = "nomadic" - -// just some meme entries, these basically encourage killing staff pets but do not play with the organ bonus system - -/datum/infuser_entry/felinid - name = "Cat" - infuse_mob_name = "feline" - desc = "EVERYONE CALM DOWN! I'm not implying anything with this entry. Are we really so surprised that felinids are humans with mixed feline DNA?" - threshold_desc = NO_THRESHOLD - qualities = list( - "oh, let me guess, you're a big fan of those japanese tourist bots", - ) - input_obj_or_mob = list( - /mob/living/simple_animal/pet/cat, - ) - output_organs = list( - /obj/item/organ/internal/ears/cat, - /obj/item/organ/external/tail/cat, - ) - infusion_desc = "domestic" - -/datum/infuser_entry/vulpini - name = "Fox" - infuse_mob_name = "vulpini" - desc = "Foxes are now quite rare because of the \"fox ears\" craze back in 2555. I mean, also because we're spacefarers who destroyed foxes' natural habitats ages ago, but that applies to most animals." - threshold_desc = NO_THRESHOLD - qualities = list( - "oh come on really", - "you bring SHAME to all geneticists", - "i hope it was worth it", - ) - input_obj_or_mob = list( - /mob/living/simple_animal/pet/fox, - ) - output_organs = list( - /obj/item/organ/internal/ears/fox, - ) - infusion_desc = "inexcusable" - -/datum/infuser_entry/goliath - name = "Goliath" - infuse_mob_name = "Goliath" - desc = "The guy who said 'Whoever fights monsters should see to it that in the process he does not become a monster' clearly didn't see what a goliath miner can do!" - threshold_desc = "You can walk on lava!" - qualities = list( - "can breath both the station and lavaland air but can't deal with pure O2", - "immune to ashstorms", - "eyes that can see in the dark", - "a tendril hand can easily dig through basalt and obliterate hostile fauna, won't be fitting on gloves any time soon tho...", - ) - input_obj_or_mob = list( - /mob/living/simple_animal/hostile/asteroid/goliath, - ) - output_organs = list( - /obj/item/organ/internal/brain/goliath, - /obj/item/organ/internal/eyes/night_vision/goliath, - /obj/item/organ/internal/heart/goliath, - /obj/item/organ/internal/lungs/lavaland/goliath, - ) - infusion_desc = "armored tendril-like" - -/datum/infuser_entry/mothroach - name = "Mothroach" - infuse_mob_name = "Mothroach" - desc = "So first they mixed moth and roach DNA to make mothroaches, and now we mix mothroach DNA with humanoids to make mothmen hybrids?" - threshold_desc = NO_THRESHOLD - qualities = list( - "eyes weak to bright lights", - "you flutter when you talk", - "wings that can't even carry your body weight", - "i hope it was worth it", - ) - input_obj_or_mob = list( - /mob/living/basic/mothroach, - ) - output_organs = list( - /obj/item/organ/external/antennae, - /obj/item/organ/external/wings/moth, - /obj/item/organ/internal/eyes/moth, - /obj/item/organ/internal/tongue/moth, - ) - infusion_desc = "fluffy" diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 25ab43a4dd0..f34f557c3a3 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -117,6 +117,9 @@ /// Only load in visual organs var/visual_only_organs = FALSE + /// Stores the result of our last known top_offset generation for optimisation purposes when drawing limb icons. + var/last_top_offset + COOLDOWN_DECLARE(bleeding_message_cd) diff --git a/code/modules/mob/living/carbon/carbon_update_icons.dm b/code/modules/mob/living/carbon/carbon_update_icons.dm index 830434351b7..c08665f0f34 100644 --- a/code/modules/mob/living/carbon/carbon_update_icons.dm +++ b/code/modules/mob/living/carbon/carbon_update_icons.dm @@ -484,7 +484,7 @@ var/old_key = icon_render_keys?[limb.body_zone] //Checks the mob's icon render key list for the bodypart icon_render_keys[limb.body_zone] = (limb.is_husked) ? limb.generate_husk_key().Join() : limb.generate_icon_key().Join() //Generates a key for the current bodypart - if(icon_render_keys[limb.body_zone] != old_key) //If the keys match, that means the limb doesn't need to be redrawn + if(icon_render_keys[limb.body_zone] != old_key || get_top_offset() != last_top_offset) //If the keys match, that means the limb doesn't need to be redrawn needs_update += limb var/list/missing_bodyparts = get_missing_limbs() @@ -499,12 +499,18 @@ //GENERATE NEW LIMBS var/list/new_limbs = list() for(var/obj/item/bodypart/limb as anything in bodyparts) - if(limb in needs_update) //Checks to see if the limb needs to be redrawn + if(limb in needs_update) var/bodypart_icon = limb.get_limb_icon() + if(!istype(limb, /obj/item/bodypart/leg)) + var/top_offset = get_top_offset() + for(var/image/image as anything in bodypart_icon) + image.pixel_y += top_offset new_limbs += bodypart_icon limb_icon_cache[icon_render_keys[limb.body_zone]] = bodypart_icon //Caches the icon with the bodypart key, as it is new else new_limbs += limb_icon_cache[icon_render_keys[limb.body_zone]] //Pulls existing sprites from the cache + last_top_offset = get_top_offset() + remove_overlay(BODYPARTS_LAYER) @@ -513,6 +519,18 @@ apply_overlay(BODYPARTS_LAYER) +/// This looks at the chest and legs of the mob and decides how much our chest, arms, and head should be adjusted. This is useful for limbs that are larger or smaller than the scope of normal human height while keeping the feet anchored to the bottom of the tile +/mob/living/carbon/proc/get_top_offset() + var/from_chest + var/from_leg + for(var/obj/item/bodypart/leg/leg_checked in bodyparts) + if(leg_checked.top_offset > from_leg || isnull(from_leg)) // We find the tallest leg available + from_leg = leg_checked.top_offset + if(isnull(from_leg)) + from_leg = 0 // If we have no legs, we set this to zero to avoid any math issues that might stem from it being NULL + for(var/obj/item/bodypart/chest/chest_checked in bodyparts) // Take the height from the chest + from_chest = chest_checked.top_offset + return (from_chest + from_leg) // The total hight of the chest and legs together ///////////////////////// // Limb Icon Cache 2.0 // diff --git a/code/modules/mob/living/carbon/human/human_update_icons.dm b/code/modules/mob/living/carbon/human/human_update_icons.dm index 7ad23b7d679..0b2bb3014da 100644 --- a/code/modules/mob/living/carbon/human/human_update_icons.dm +++ b/code/modules/mob/living/carbon/human/human_update_icons.dm @@ -871,6 +871,9 @@ mutant_styles: The mutant style - taur bodytype, STYLE_TESHARI, etc. // SKYRAT E .[2] = offsets["y"] else .[2] = worn_y_offset + if(ishuman(loc) && slot_flags != ITEM_SLOT_FEET) /// we adjust the human body for high given by body parts, execpt shoes, because they are always on the bottom + var/mob/living/carbon/human/human_holder = loc + .[2] += human_holder.get_top_offset() //Can't think of a better way to do this, sadly /mob/proc/get_item_offsets_for_index(i) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 18d77697d0e..adcc8121477 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -560,6 +560,7 @@ GLOBAL_LIST_EMPTY(features_by_species) /* /datum/species/proc/handle_body(mob/living/carbon/human/species_human) species_human.remove_overlay(BODY_LAYER) + var/height_offset = species_human.get_top_offset() // From high changed by varying limb height if(HAS_TRAIT(species_human, TRAIT_INVISIBLE_MAN)) return handle_mutant_bodyparts(species_human) var/list/standing = list() @@ -574,6 +575,7 @@ GLOBAL_LIST_EMPTY(features_by_species) if(OFFSET_FACE in species_human.dna.species.offset_features) lip_overlay.pixel_x += species_human.dna.species.offset_features[OFFSET_FACE][1] lip_overlay.pixel_y += species_human.dna.species.offset_features[OFFSET_FACE][2] + lip_overlay.pixel_y += height_offset standing += lip_overlay // eyes @@ -589,6 +591,7 @@ GLOBAL_LIST_EMPTY(features_by_species) if(OFFSET_FACE in species_human.dna.species.offset_features) add_pixel_x = species_human.dna.species.offset_features[OFFSET_FACE][1] add_pixel_y = species_human.dna.species.offset_features[OFFSET_FACE][2] + add_pixel_y += height_offset if(!eye_organ) no_eyeslay = mutable_appearance('icons/mob/species/human/human_face.dmi', "eyes_missing", -BODY_LAYER) @@ -599,7 +602,8 @@ GLOBAL_LIST_EMPTY(features_by_species) eye_organ.refresh(call_update = FALSE) if(!no_eyeslay) - for(var/eye_overlay in eye_organ.generate_body_overlay(species_human)) + for(var/mutable_appearance/eye_overlay in eye_organ.generate_body_overlay(species_human)) + eye_overlay.pixel_y += height_offset standing += eye_overlay // organic body markings @@ -614,18 +618,22 @@ GLOBAL_LIST_EMPTY(features_by_species) if(!HAS_TRAIT(species_human, TRAIT_HUSK)) if(noggin && (IS_ORGANIC_LIMB(noggin))) var/mutable_appearance/markings_head_overlay = mutable_appearance(markings.icon, "[markings.icon_state]_head", -BODY_LAYER) + markings_head_overlay.pixel_y += height_offset standing += markings_head_overlay if(chest && (IS_ORGANIC_LIMB(chest))) var/mutable_appearance/markings_chest_overlay = mutable_appearance(markings.icon, "[markings.icon_state]_chest", -BODY_LAYER) + markings_chest_overlay.pixel_y += height_offset standing += markings_chest_overlay if(right_arm && (IS_ORGANIC_LIMB(right_arm))) var/mutable_appearance/markings_r_arm_overlay = mutable_appearance(markings.icon, "[markings.icon_state]_r_arm", -BODY_LAYER) + markings_r_arm_overlay.pixel_y += height_offset standing += markings_r_arm_overlay if(left_arm && (IS_ORGANIC_LIMB(left_arm))) var/mutable_appearance/markings_l_arm_overlay = mutable_appearance(markings.icon, "[markings.icon_state]_l_arm", -BODY_LAYER) + markings_l_arm_overlay.pixel_y += height_offset standing += markings_l_arm_overlay if(right_leg && (IS_ORGANIC_LIMB(right_leg))) @@ -648,15 +656,19 @@ GLOBAL_LIST_EMPTY(features_by_species) underwear_overlay = mutable_appearance(underwear.icon, underwear.icon_state, -BODY_LAYER) if(!underwear.use_static) underwear_overlay.color = species_human.underwear_color + underwear_overlay.pixel_y += height_offset standing += underwear_overlay if(species_human.undershirt) var/datum/sprite_accessory/undershirt/undershirt = GLOB.undershirt_list[species_human.undershirt] if(undershirt) + var/mutable_appearance/working_shirt if(species_human.dna.species.sexes && species_human.physique == FEMALE) - standing += wear_female_version(undershirt.icon_state, undershirt.icon, BODY_LAYER) + working_shirt = wear_female_version(undershirt.icon_state, undershirt.icon, BODY_LAYER) else - standing += mutable_appearance(undershirt.icon, undershirt.icon_state, -BODY_LAYER) + working_shirt = mutable_appearance(undershirt.icon, undershirt.icon_state, -BODY_LAYER) + working_shirt.pixel_y += height_offset + standing += working_shirt if(species_human.socks && species_human.num_legs >= 2 && !(src.bodytype & BODYTYPE_DIGITIGRADE)) var/datum/sprite_accessory/socks/socks = GLOB.socks_list[species_human.socks] diff --git a/code/modules/mob/living/carbon/human/species_types/abominations.dm b/code/modules/mob/living/carbon/human/species_types/abominations.dm new file mode 100644 index 00000000000..a308f5c962e --- /dev/null +++ b/code/modules/mob/living/carbon/human/species_types/abominations.dm @@ -0,0 +1,43 @@ +/// These won't appear normally in games, they are meant to for debuging the adjustment of limbs based on the height of a humans bodyparts. +/datum/species/human/tallboy + name = "\improper Tall Boy" + id = SPECIES_TALLBOY + bodypart_overrides = list( + BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left, + BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right, + BODY_ZONE_HEAD = /obj/item/bodypart/head, + BODY_ZONE_L_LEG = /obj/item/bodypart/leg/left/tallboy, + BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/tallboy, + BODY_ZONE_CHEST = /obj/item/bodypart/chest, + ) + +/datum/species/monkey/human_legged + id = SPECIES_MONKEY_HUMAN_LEGGED + bodypart_overrides = list( + BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/monkey, + BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right/monkey, + BODY_ZONE_HEAD = /obj/item/bodypart/head/monkey, + BODY_ZONE_L_LEG = /obj/item/bodypart/leg/left, + BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right, + BODY_ZONE_CHEST = /obj/item/bodypart/chest/monkey, + ) + +/datum/species/monkey/monkey_freak + id = SPECIES_MONKEY_FREAK + bodypart_overrides = list( + BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left, + BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right, + BODY_ZONE_HEAD = /obj/item/bodypart/head/monkey, + BODY_ZONE_L_LEG = /obj/item/bodypart/leg/left/monkey, + BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/monkey, + BODY_ZONE_CHEST = /obj/item/bodypart/chest, + ) + +/mob/living/carbon/human/species/monkey/humand_legged + race = /datum/species/monkey/human_legged + +/mob/living/carbon/human/species/monkey/monkey_freak + race = /datum/species/monkey/monkey_freak + +/mob/living/carbon/human/species/tallboy + race = /datum/species/human/tallboy diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm index 8136d55a7e2..1cb700ed7d9 100644 --- a/code/modules/mob/living/carbon/human/species_types/humans.dm +++ b/code/modules/mob/living/carbon/human/species_types/humans.dm @@ -92,3 +92,4 @@ )) return to_add + diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index 0d09a5ac06c..473a21fcad3 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -184,6 +184,8 @@ var/unarmed_damage_high = 1 ///Damage at which attacks from this bodypart will stun var/unarmed_stun_threshold = 2 + /// How many pixels this bodypart will offset the top half of the mob, used for abnormally sized torsos and legs + var/top_offset = 0 /// Traits that are given to the holder of the part. If you want an effect that changes this, don't add directly to this. Use the add_bodypart_trait() proc var/list/bodypart_traits = list() diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm index c098a6aae1c..8181efdeee3 100644 --- a/code/modules/surgery/bodyparts/head.dm +++ b/code/modules/surgery/bodyparts/head.dm @@ -319,6 +319,9 @@ /obj/item/bodypart/head/monkey icon = 'icons/mob/species/monkey/bodyparts.dmi' + icon_static = 'icons/mob/species/monkey/bodyparts.dmi' + icon_husk = 'icons/mob/species/monkey/bodyparts.dmi' + husk_type = "monkey" icon_state = "default_monkey_head" limb_id = SPECIES_MONKEY bodytype = BODYTYPE_MONKEY | BODYTYPE_ORGANIC diff --git a/code/modules/surgery/bodyparts/parts.dm b/code/modules/surgery/bodyparts/parts.dm index 23cceea1dc1..297a179f190 100644 --- a/code/modules/surgery/bodyparts/parts.dm +++ b/code/modules/surgery/bodyparts/parts.dm @@ -36,13 +36,16 @@ /obj/item/bodypart/chest/monkey icon = 'icons/mob/species/monkey/bodyparts.dmi' icon_static = 'icons/mob/species/monkey/bodyparts.dmi' + icon_husk = 'icons/mob/species/monkey/bodyparts.dmi' + husk_type = "monkey" + top_offset = -5 icon_state = "default_monkey_chest" limb_id = SPECIES_MONKEY should_draw_greyscale = FALSE is_dimorphic = FALSE wound_resistance = -10 bodytype = BODYTYPE_MONKEY | BODYTYPE_ORGANIC - acceptable_bodytype = BODYTYPE_MONKEY + acceptable_bodytype = BODYTYPE_HUMANOID dmg_overlay_type = SPECIES_MONKEY /obj/item/bodypart/chest/alien @@ -162,6 +165,8 @@ /obj/item/bodypart/arm/left/monkey icon = 'icons/mob/species/monkey/bodyparts.dmi' icon_static = 'icons/mob/species/monkey/bodyparts.dmi' + icon_husk = 'icons/mob/species/monkey/bodyparts.dmi' + husk_type = "monkey" icon_state = "default_monkey_l_arm" limb_id = SPECIES_MONKEY should_draw_greyscale = FALSE @@ -263,6 +268,8 @@ /obj/item/bodypart/arm/right/monkey icon = 'icons/mob/species/monkey/bodyparts.dmi' icon_static = 'icons/mob/species/monkey/bodyparts.dmi' + icon_husk = 'icons/mob/species/monkey/bodyparts.dmi' + husk_type = "monkey" icon_state = "default_monkey_r_arm" limb_id = SPECIES_MONKEY bodytype = BODYTYPE_MONKEY | BODYTYPE_ORGANIC @@ -370,6 +377,9 @@ /obj/item/bodypart/leg/left/monkey icon = 'icons/mob/species/monkey/bodyparts.dmi' icon_static = 'icons/mob/species/monkey/bodyparts.dmi' + icon_husk = 'icons/mob/species/monkey/bodyparts.dmi' + husk_type = "monkey" + top_offset = -3 icon_state = "default_monkey_l_leg" limb_id = SPECIES_MONKEY should_draw_greyscale = FALSE @@ -461,6 +471,9 @@ /obj/item/bodypart/leg/right/monkey icon = 'icons/mob/species/monkey/bodyparts.dmi' icon_static = 'icons/mob/species/monkey/bodyparts.dmi' + icon_husk = 'icons/mob/species/monkey/bodyparts.dmi' + husk_type = "monkey" + top_offset = -3 icon_state = "default_monkey_r_leg" limb_id = SPECIES_MONKEY should_draw_greyscale = FALSE @@ -484,3 +497,15 @@ can_be_disabled = FALSE max_damage = 100 should_draw_greyscale = FALSE + +/obj/item/bodypart/leg/right/tallboy + limb_id = SPECIES_TALLBOY + top_offset = 23 + unarmed_damage_low = 30 + unarmed_damage_low = 50 + +/obj/item/bodypart/leg/left/tallboy + limb_id = SPECIES_TALLBOY + top_offset = 23 + unarmed_damage_low = 30 + unarmed_damage_low = 50 diff --git a/code/modules/unit_tests/limbsanity.dm b/code/modules/unit_tests/limbsanity.dm index d7acfeedf4a..9988c7471e2 100644 --- a/code/modules/unit_tests/limbsanity.dm +++ b/code/modules/unit_tests/limbsanity.dm @@ -10,3 +10,29 @@ TEST_FAIL("[path] does not have a valid icon for female variants") else if(!icon_exists(UNLINT(part.should_draw_greyscale ? part.icon_greyscale : part.icon_static), "[part.limb_id]_[part.body_zone]")) TEST_FAIL("[path] does not have a valid icon") + +/// Tests the height adjustment system which dynamically changes how much the chest, head, and arms of a carbon are adjusted upwards or downwards based on the length of their legs and chest. +/datum/unit_test/limb_height_adjustment + +/datum/unit_test/limb_height_adjustment/Run() + var/mob/living/carbon/human/john_doe = allocate(/mob/living/carbon/human/consistent) + var/mob/living/carbon/human/species/monkey/monkey = allocate(/mob/living/carbon/human/species/monkey) + var/mob/living/carbon/human/tallboy = allocate(/mob/living/carbon/human/consistent) + + tallboy.set_species(/datum/species/human/tallboy) + TEST_ASSERT_EQUAL(john_doe.get_top_offset(), 0, "John Doe found to have a top offset other than zero.") + TEST_ASSERT_EQUAL(monkey.get_top_offset(), -8, "Monkey found to have a top offset other than -8.") + TEST_ASSERT_EQUAL(tallboy.get_top_offset(), 23, "Tallboy human varient found to have a top offset other than 23.") + + + var/obj/item/bodypart/leg/left/monkey/left_monky_leg = allocate(/obj/item/bodypart/leg/left/monkey) + var/obj/item/bodypart/leg/right/monkey/right_monky_leg = allocate(/obj/item/bodypart/leg/right/monkey) + + left_monky_leg.replace_limb(john_doe, TRUE) + + TEST_ASSERT_EQUAL(john_doe.get_top_offset(), 0, "John Doe has a top offset other than 0 with one human leg and one monkey leg.") + + right_monky_leg.replace_limb(john_doe, TRUE) + + TEST_ASSERT_EQUAL(john_doe.get_top_offset(), -3, "John Doe has a top offset other than -3 with two monkey legs.") + diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_human_tallboy.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_human_tallboy.png new file mode 100644 index 00000000000..262353dc0a9 Binary files /dev/null and b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_human_tallboy.png differ diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_monkey.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_monkey.png index 77ddef22ec8..e0d02f4302f 100644 Binary files a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_monkey.png and b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_monkey.png differ diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_monkey_human_legged.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_monkey_human_legged.png new file mode 100644 index 00000000000..285c0a660ca Binary files /dev/null and b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_monkey_human_legged.png differ diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_monkey_monkey_freak.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_monkey_monkey_freak.png new file mode 100644 index 00000000000..6377e62e9d9 Binary files /dev/null and b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_monkey_monkey_freak.png differ diff --git a/icons/mob/effects/dam_mob.dmi b/icons/mob/effects/dam_mob.dmi index fe92746b43e..6390a1b34d6 100644 Binary files a/icons/mob/effects/dam_mob.dmi and b/icons/mob/effects/dam_mob.dmi differ diff --git a/icons/mob/effects/onfire.dmi b/icons/mob/effects/onfire.dmi index 09ffc089c78..0ef0b16c011 100644 Binary files a/icons/mob/effects/onfire.dmi and b/icons/mob/effects/onfire.dmi differ diff --git a/icons/mob/species/human/bodyparts.dmi b/icons/mob/species/human/bodyparts.dmi index 642489e4787..ec53e63d367 100644 Binary files a/icons/mob/species/human/bodyparts.dmi and b/icons/mob/species/human/bodyparts.dmi differ diff --git a/icons/mob/species/human/bodyparts_greyscale.dmi b/icons/mob/species/human/bodyparts_greyscale.dmi index b1cc6133e13..fff4624f193 100644 Binary files a/icons/mob/species/human/bodyparts_greyscale.dmi and b/icons/mob/species/human/bodyparts_greyscale.dmi differ diff --git a/icons/mob/species/monkey/bodyparts.dmi b/icons/mob/species/monkey/bodyparts.dmi index 7b10838c313..689ef5e63d7 100644 Binary files a/icons/mob/species/monkey/bodyparts.dmi and b/icons/mob/species/monkey/bodyparts.dmi differ diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm index e7a62e5865a..e2cf08d93c4 100644 --- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm +++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species.dm @@ -348,7 +348,7 @@ GLOBAL_LIST_EMPTY(customizable_races) /datum/species/proc/handle_body(mob/living/carbon/human/species_human) species_human.remove_overlay(BODY_LAYER) - + var/height_offset = species_human.get_top_offset() // From high changed by varying limb height var/list/standing = list() var/obj/item/bodypart/head/HD = species_human.get_bodypart(BODY_ZONE_HEAD) @@ -361,6 +361,7 @@ GLOBAL_LIST_EMPTY(customizable_races) if(OFFSET_FACE in species_human.dna.species.offset_features) lip_overlay.pixel_x += species_human.dna.species.offset_features[OFFSET_FACE][1] lip_overlay.pixel_y += species_human.dna.species.offset_features[OFFSET_FACE][2] + lip_overlay.pixel_y += height_offset standing += lip_overlay // eyes @@ -378,6 +379,8 @@ GLOBAL_LIST_EMPTY(customizable_races) add_pixel_x = species_human.dna.species.offset_features[OFFSET_FACE][1] add_pixel_y = species_human.dna.species.offset_features[OFFSET_FACE][2] + add_pixel_y += height_offset + if(!eye_organ) no_eyeslay = mutable_appearance('icons/mob/species/human/human_face.dmi', "eyes_missing", -BODY_LAYER) no_eyeslay.pixel_x += add_pixel_x @@ -387,7 +390,8 @@ GLOBAL_LIST_EMPTY(customizable_races) eye_organ.refresh(call_update = FALSE) if(!no_eyeslay) - for(var/eye_overlay in eye_organ.generate_body_overlay(species_human)) + for(var/mutable_appearance/eye_overlay in eye_organ.generate_body_overlay(species_human)) + eye_overlay.pixel_y += height_offset standing += eye_overlay if(eye_organ.is_emissive) var/mutable_appearance/eye_emissive = emissive_appearance_copy(eye_overlay, species_human) diff --git a/tgstation.dme b/tgstation.dme index e21f3282bbb..8af9056ee5e 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -3969,6 +3969,7 @@ #include "code\modules\mob\living\carbon\human\suicides.dm" #include "code\modules\mob\living\carbon\human\monkey\monkey.dm" #include "code\modules\mob\living\carbon\human\species_types\abductors.dm" +#include "code\modules\mob\living\carbon\human\species_types\abominations.dm" #include "code\modules\mob\living\carbon\human\species_types\android.dm" #include "code\modules\mob\living\carbon\human\species_types\dullahan.dm" #include "code\modules\mob\living\carbon\human\species_types\ethereal.dm"