diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 05d6be652148e..96b07d361fcaa 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -32,6 +32,7 @@ init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_antennae, GLOB.moth_antennae_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_markings, GLOB.moth_markings_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/pod_hair, GLOB.pod_hair_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/skrell_tail,GLOB.skrell_hair_list) //Species for(var/spath in subtypesof(/datum/species)) diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 96db76f5349bc..5649015b216bd 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -89,6 +89,8 @@ init_sprite_accessory_subtypes(/datum/sprite_accessory/moth_markings, GLOB.moth_markings_list) if(!GLOB.pod_hair_list.len) init_sprite_accessory_subtypes(/datum/sprite_accessory/pod_hair, GLOB.pod_hair_list) + if(!GLOB.skrell_hair_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/skrell_tail,GLOB.skrell_hair_list) //For now we will always return none for tail_human and ears. | "For now" he says. return(list( @@ -110,6 +112,7 @@ "moth_markings" = pick(GLOB.moth_markings_list), "tail_monkey" = "None", "pod_hair" = pick(GLOB.pod_hair_list), + "skrell_hair" = pick(GLOB.skrell_hair_list) )) /proc/random_hairstyle(gender) diff --git a/config/game_options.txt b/config/game_options.txt index 7d7631a8cadc5..dbb3ecf481473 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -346,6 +346,7 @@ ROUNDSTART_RACES lizard ROUNDSTART_RACES moth ROUNDSTART_RACES plasmaman #ROUNDSTART_RACES shadow +ROUNDSTART_RACES skrell ## Races that are better than humans in some ways, but worse in others ROUNDSTART_RACES ethereal diff --git a/modular_galactic/skrell/bodyparts.dmi b/modular_galactic/skrell/bodyparts.dmi new file mode 100644 index 0000000000000..13b04dc5c641f Binary files /dev/null and b/modular_galactic/skrell/bodyparts.dmi differ diff --git a/modular_galactic/skrell/skrell.dm b/modular_galactic/skrell/skrell.dm new file mode 100644 index 0000000000000..08f41199e4c7c --- /dev/null +++ b/modular_galactic/skrell/skrell.dm @@ -0,0 +1,104 @@ +/////////////////////////////////////////////////// +//Skrell species, organs and human species define// +/////////////////////////////////////////////////// + + +/datum/species/skrell + name = "Skrell" + plural_form = "Skrells" + id = SPECIES_SKRELL + species_traits = list( + EYECOLOR, + MUTCOLORS, + LIPS, + ) + coldmod = 1.25 + heatmod = 0.75 + brutemod = 1.20 + burnmod = 0.80 + bodytemp_normal = (BODYTEMP_NORMAL + 70) + bodytemp_heat_damage_limit = FIRE_MINIMUM_TEMPERATURE_TO_SPREAD + bodytemp_cold_damage_limit = (T20C - 10) + species_language_holder = /datum/language_holder/skrell + toxic_food = DAIRY | MEAT + disliked_food = RAW | CLOTH + liked_food = TOXIC | FRUIT | VEGETABLES + changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_MAGIC | MIRROR_PRIDE | ERT_SPAWN | RACE_SWAP | SLIME_EXTRACT + exotic_blood = /datum/reagent/copper + payday_modifier = 0.75 + mutantbrain = /obj/item/organ/internal/brain/skrell + mutanteyes = /obj/item/organ/internal/eyes/skrell + mutantlungs = /obj/item/organ/internal/lungs/skrell + mutantheart = /obj/item/organ/internal/heart/skrell + mutantliver = /obj/item/organ/internal/liver/skrell + mutanttongue = /obj/item/organ/internal/tongue/skrell + external_organs = list( + /obj/item/organ/external/skrell = "Screll Tentacles Short", + ) + bodypart_overrides = list( + BODY_ZONE_HEAD = /obj/item/bodypart/head/skrell, + BODY_ZONE_CHEST = /obj/item/bodypart/chest/skrell, + BODY_ZONE_L_ARM = /obj/item/bodypart/arm/left/skrell, + BODY_ZONE_R_ARM = /obj/item/bodypart/arm/right/skrell, + BODY_ZONE_L_LEG = /obj/item/bodypart/leg/left/skrell, + BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/skrell, + ) + +/datum/species/skrell/randomize_features(mob/living/carbon/human_mob) + randomize_external_organs(human_mob) + +/obj/item/organ/internal/tongue/skrell + name = "internal vocal sacs" + desc = "An Strange looking sac." + icon = 'modular_galactic/skrell/skrell_organs.dmi' + icon_state = "tongue" + taste_sensitivity = 5 + +/obj/item/organ/internal/tongue/skrell/get_possible_languages() + return ..() + /datum/language/skrell + +/obj/item/organ/internal/heart/skrell + name = "skrellian heart" + icon = 'modular_galactic/skrell/skrell_organs.dmi' + icon_state = "heart-on" + +/obj/item/organ/internal/brain/skrell + name = "spongy brain" + icon = 'modular_galactic/skrell/skrell_organs.dmi' + icon_state = "brain2" + +/obj/item/organ/internal/eyes/skrell + name = "amphibian eyes" + desc = "Large black orbs." + icon = 'modular_galactic/skrell/skrell_organs.dmi' + icon_state = "eyes" + flash_protect = FLASH_PROTECTION_SENSITIVE + +/obj/item/organ/internal/lungs/skrell + name = "skrell lungs" + icon = 'modular_galactic/skrell/skrell_organs.dmi' + icon_state = "lungs" + safe_plasma_max = 40 + safe_co2_max = 40 + + cold_message = "You can't stand the freezing cold with every breath you take!" + cold_level_1_threshold = 248 + cold_level_2_threshold = 220 + cold_level_3_threshold = 170 + cold_level_1_damage = COLD_GAS_DAMAGE_LEVEL_2 //Keep in mind with gas damage levels, you can set these to be negative, if you want someone to heal, instead. + cold_level_2_damage = COLD_GAS_DAMAGE_LEVEL_2 + cold_level_3_damage = COLD_GAS_DAMAGE_LEVEL_3 + cold_damage_type = BRUTE + + + hot_message = "You can't stand the searing heat with every breath you take!" + heat_level_1_threshold = 318 + heat_level_2_threshold = 348 + heat_level_3_threshold = 1000 + heat_level_1_damage = HEAT_GAS_DAMAGE_LEVEL_2 + heat_level_2_damage = HEAT_GAS_DAMAGE_LEVEL_2 + heat_level_3_damage = HEAT_GAS_DAMAGE_LEVEL_3 + heat_damage_type = BURN + +/mob/living/carbon/human/species/skrell + race = /datum/species/skrell diff --git a/modular_galactic/skrell/skrell.dmi b/modular_galactic/skrell/skrell.dmi new file mode 100644 index 0000000000000..a370455d505f0 Binary files /dev/null and b/modular_galactic/skrell/skrell.dmi differ diff --git a/modular_galactic/skrell/skrell_accessory.dm b/modular_galactic/skrell/skrell_accessory.dm new file mode 100644 index 0000000000000..419ba17c29db3 --- /dev/null +++ b/modular_galactic/skrell/skrell_accessory.dm @@ -0,0 +1,59 @@ +//////////////////////////////////////////////////// +// Skrell accessory defines // +//////////////////////////////////////////////////// +/datum/sprite_accessory/skrell_tail + name = "Skrell Male Tentacles" + icon = 'modular_galactic/skrell/tails.dmi' + +/datum/sprite_accessory/skrell_tail/none + name = "Bald" + icon_state = "none" + +/datum/sprite_accessory/skrell_tail/long + name = "Skrell Tentacles Long" + icon_state = "long" + + +/datum/sprite_accessory/skrell_tail/very_short + name = "Skrell Tentacles Very Short" + icon_state = "veryshort" + +/datum/sprite_accessory/skrell_tail/mid + name = "Skrell Tentacles Middle" + icon_state = "middle" + +/datum/sprite_accessory/skrell_tail/mid_alt + name = "Skrell Tentacles Middle Alt" + icon_state = "middle2" + +/datum/sprite_accessory/skrell_tail/wavy + name = "Screll Tentacles Wavy" + icon_state = "wavy" + +/datum/sprite_accessory/skrell_tail/wavy_alt + name = "Screll Tentacles Wavy Alt" + icon_state = "wavy2" + +/datum/sprite_accessory/skrell_tail/pulled_back + name = "Screll Tentacles Pulled Back" + icon_state = "pulledback" + +/datum/sprite_accessory/skrell_tail/pulled_back_alt + name = "Screll Tentacles Pulled Back Alt" + icon_state = "pulledback2" + +/datum/sprite_accessory/skrell_tail/very_long + name = "Screll Tentacles Very Long" + icon_state = "verylong" + +/datum/sprite_accessory/skrell_tail/overeye + name = "Screll Tentacles Overeye" + icon_state = "overeye" + +/datum/sprite_accessory/skrell_tail/overeye_alt + name = "Screll Tentacles Overeye Alt" + icon_state = "overeye2" + +/datum/sprite_accessory/skrell_tail/flip_flap + name = "Screll Tentacles Flip Flap" + icon_state = "flipflap" diff --git a/modular_galactic/skrell/skrell_accessory_preference.dm b/modular_galactic/skrell/skrell_accessory_preference.dm new file mode 100644 index 0000000000000..6a27f22e693ba --- /dev/null +++ b/modular_galactic/skrell/skrell_accessory_preference.dm @@ -0,0 +1,34 @@ +/datum/preference/choiced/skrell_hair + savefile_key = "feature_skrell_hair" + savefile_identifier = PREFERENCE_CHARACTER + category = PREFERENCE_CATEGORY_FEATURES + main_feature_name = "Hairstyle" + should_generate_icons = TRUE + +/datum/preference/choiced/skrell_hair/init_possible_values() + var/list/values = list() + var/icon/skrell_head = icon('modular_galactic/skrell/bodyparts.dmi', "skrell_head_m") + + for (var/tentacle in GLOB.skrell_hair_list) + var/datum/sprite_accessory/skrell_hair = GLOB.skrell_hair_list[tentacle] + if(skrell_hair.locked) + continue + + var/icon/icon_with_hair = new(skrell_head) + var/icon/icon_adj = icon(skrell_hair.icon, "m_skrell_hair_[skrell_hair.icon_state]_ADJ") + var/icon/icon_front = icon(skrell_hair.icon, "m_skrell_hair_[skrell_hair.icon_state]_FRONT") + icon_adj.Blend(icon_front, ICON_OVERLAY) + icon_with_hair.Blend(icon_adj, ICON_OVERLAY) + icon_with_hair.Scale(64, 64) + icon_with_hair.Crop(15, 64, 15 + 31, 64 - 31) + icon_with_hair.Blend(COLOR_RED, ICON_MULTIPLY) + + values[skrell_hair.name] = icon_with_hair + + return values + +/datum/preference/choiced/skrell_hair/create_default_value() + return pick(assoc_to_keys_features(GLOB.skrell_hair_list)) + +/datum/preference/choiced/skrell_hair/apply_to_human(mob/living/carbon/human/target, value) + target.dna.features["skrell_hair"] = value diff --git a/modular_galactic/skrell/skrell_bodyparts.dm b/modular_galactic/skrell/skrell_bodyparts.dm new file mode 100644 index 0000000000000..d524df573f783 --- /dev/null +++ b/modular_galactic/skrell/skrell_bodyparts.dm @@ -0,0 +1,49 @@ +//////////////////////////////////////////////////// +// Skrell bodyparts defines // +//////////////////////////////////////////////////// + + +/obj/item/bodypart/head/skrell + icon_greyscale = 'modular_galactic/skrell/bodyparts.dmi' + biological_state = BIO_FLESH_BONE + limb_id = SPECIES_SKRELL + is_dimorphic = TRUE + should_draw_greyscale = TRUE + dmg_overlay_type = null + +/obj/item/bodypart/chest/skrell + icon_greyscale = 'modular_galactic/skrell/bodyparts.dmi' + biological_state = BIO_FLESH_BONE + limb_id = SPECIES_SKRELL + is_dimorphic = TRUE + should_draw_greyscale = TRUE + dmg_overlay_type = null + +/obj/item/bodypart/arm/left/skrell + icon_greyscale = 'modular_galactic/skrell/bodyparts.dmi' + biological_state = BIO_FLESH_BONE + limb_id = SPECIES_SKRELL + should_draw_greyscale = TRUE + dmg_overlay_type = null + + +/obj/item/bodypart/arm/right/skrell + icon_greyscale = 'modular_galactic/skrell/bodyparts.dmi' + biological_state = BIO_FLESH_BONE + limb_id = SPECIES_SKRELL + should_draw_greyscale = TRUE + dmg_overlay_type = null + +/obj/item/bodypart/leg/left/skrell + icon_greyscale = 'modular_galactic/skrell/bodyparts.dmi' + biological_state = BIO_FLESH_BONE + limb_id = SPECIES_SKRELL + should_draw_greyscale = TRUE + dmg_overlay_type = null + +/obj/item/bodypart/leg/right/skrell + icon_greyscale = 'modular_galactic/skrell/bodyparts.dmi' + biological_state = BIO_FLESH_BONE + limb_id = SPECIES_SKRELL + should_draw_greyscale = TRUE + dmg_overlay_type = null diff --git a/modular_galactic/skrell/skrell_defines.dm b/modular_galactic/skrell/skrell_defines.dm new file mode 100644 index 0000000000000..38a7b81d08d79 --- /dev/null +++ b/modular_galactic/skrell/skrell_defines.dm @@ -0,0 +1,157 @@ +//I had to change make_datum_references_lists to code\__HELPERS\global_lists.dm and random_features in code\__HELPERS\mobs.dm for correct operation. +///////////////////////////////////// +// code\__DEFINES\DNA.dm // +///////////////////////////////////// + +#define DNA_FEATURE_BLOCKS 16 +#define DNA_SKRELL_HAIR_BLOCK 16 +#define ORGAN_SLOT_EXTERNAL_SKRELL_HAIR "skrell_hair" + +#define SPECIES_SKRELL "skrell" + +GLOBAL_LIST_EMPTY(skrell_hair_list) +//////////////////////////////////// +// code\datums\dna.dm // +//////////////////////////////////// +/datum/dna/generate_unique_features() + . = "" + var/list/L = new /list(DNA_FEATURE_BLOCKS) + + if(features["mcolor"]) + L[DNA_MUTANT_COLOR_BLOCK] = sanitize_hexcolor(features["mcolor"], include_crunch = FALSE) + if(features["ethcolor"]) + L[DNA_ETHEREAL_COLOR_BLOCK] = sanitize_hexcolor(features["ethcolor"], include_crunch = FALSE) + if(features["body_markings"]) + L[DNA_LIZARD_MARKINGS_BLOCK] = construct_block(GLOB.body_markings_list.Find(features["body_markings"]), GLOB.body_markings_list.len) + if(features["tail_cat"]) + L[DNA_TAIL_BLOCK] = construct_block(GLOB.tails_list_human.Find(features["tail_cat"]), GLOB.tails_list_human.len) + if(features["tail_lizard"]) + L[DNA_LIZARD_TAIL_BLOCK] = construct_block(GLOB.tails_list_lizard.Find(features["tail_lizard"]), GLOB.tails_list_lizard.len) + if(features["snout"]) + L[DNA_SNOUT_BLOCK] = construct_block(GLOB.snouts_list.Find(features["snout"]), GLOB.snouts_list.len) + if(features["horns"]) + L[DNA_HORNS_BLOCK] = construct_block(GLOB.horns_list.Find(features["horns"]), GLOB.horns_list.len) + if(features["frills"]) + L[DNA_FRILLS_BLOCK] = construct_block(GLOB.frills_list.Find(features["frills"]), GLOB.frills_list.len) + if(features["spines"]) + L[DNA_SPINES_BLOCK] = construct_block(GLOB.spines_list.Find(features["spines"]), GLOB.spines_list.len) + if(features["ears"]) + L[DNA_EARS_BLOCK] = construct_block(GLOB.ears_list.Find(features["ears"]), GLOB.ears_list.len) + if(features["moth_wings"] != "Burnt Off") + L[DNA_MOTH_WINGS_BLOCK] = construct_block(GLOB.moth_wings_list.Find(features["moth_wings"]), GLOB.moth_wings_list.len) + if(features["moth_antennae"] != "Burnt Off") + L[DNA_MOTH_ANTENNAE_BLOCK] = construct_block(GLOB.moth_antennae_list.Find(features["moth_antennae"]), GLOB.moth_antennae_list.len) + if(features["moth_markings"]) + L[DNA_MOTH_MARKINGS_BLOCK] = construct_block(GLOB.moth_markings_list.Find(features["moth_markings"]), GLOB.moth_markings_list.len) + if(features["caps"]) + L[DNA_MUSHROOM_CAPS_BLOCK] = construct_block(GLOB.caps_list.Find(features["caps"]), GLOB.caps_list.len) + if(features["pod_hair"]) + L[DNA_POD_HAIR_BLOCK] = construct_block(GLOB.pod_hair_list.Find(features["pod_hair"]), GLOB.pod_hair_list.len) + if(features["skrell_hair"]) + L[DNA_SKRELL_HAIR_BLOCK] = construct_block(GLOB.skrell_hair_list.Find(features["skrell_hair"]), GLOB.skrell_hair_list.len) + + for(var/blocknum in 1 to DNA_FEATURE_BLOCKS) + . += L[blocknum] || random_string(GET_UI_BLOCK_LEN(blocknum), GLOB.hex_characters) + + +/datum/dna/update_uf_block(blocknumber) + if(!blocknumber) + CRASH("UF block index is null") + if(!ishuman(holder)) + CRASH("Non-human mobs shouldn't have DNA") + switch(blocknumber) + if(DNA_MUTANT_COLOR_BLOCK) + set_uni_feature_block(blocknumber, sanitize_hexcolor(features["mcolor"], include_crunch = FALSE)) + if(DNA_ETHEREAL_COLOR_BLOCK) + set_uni_feature_block(blocknumber, sanitize_hexcolor(features["ethcolor"], include_crunch = FALSE)) + if(DNA_LIZARD_MARKINGS_BLOCK) + set_uni_feature_block(blocknumber, construct_block(GLOB.body_markings_list.Find(features["body_markings"]), GLOB.body_markings_list.len)) + if(DNA_TAIL_BLOCK) + set_uni_feature_block(blocknumber, construct_block(GLOB.tails_list.Find(features["tail_lizard"]), GLOB.tails_list.len)) + if(DNA_SNOUT_BLOCK) + set_uni_feature_block(blocknumber, construct_block(GLOB.snouts_list.Find(features["snout"]), GLOB.snouts_list.len)) + if(DNA_HORNS_BLOCK) + set_uni_feature_block(blocknumber, construct_block(GLOB.horns_list.Find(features["horns"]), GLOB.horns_list.len)) + if(DNA_FRILLS_BLOCK) + set_uni_feature_block(blocknumber, construct_block(GLOB.frills_list.Find(features["frills"]), GLOB.frills_list.len)) + if(DNA_SPINES_BLOCK) + set_uni_feature_block(blocknumber, construct_block(GLOB.spines_list.Find(features["spines"]), GLOB.spines_list.len)) + if(DNA_EARS_BLOCK) + set_uni_feature_block(blocknumber, construct_block(GLOB.ears_list.Find(features["ears"]), GLOB.ears_list.len)) + if(DNA_MOTH_WINGS_BLOCK) + set_uni_feature_block(blocknumber, construct_block(GLOB.moth_wings_list.Find(features["moth_wings"]), GLOB.moth_wings_list.len)) + if(DNA_MOTH_ANTENNAE_BLOCK) + set_uni_feature_block(blocknumber, construct_block(GLOB.moth_antennae_list.Find(features["moth_antennae"]), GLOB.moth_antennae_list.len)) + if(DNA_MOTH_MARKINGS_BLOCK) + set_uni_feature_block(blocknumber, construct_block(GLOB.moth_markings_list.Find(features["moth_markings"]), GLOB.moth_markings_list.len)) + if(DNA_MUSHROOM_CAPS_BLOCK) + set_uni_feature_block(blocknumber, construct_block(GLOB.caps_list.Find(features["caps"]), GLOB.caps_list.len)) + if(DNA_POD_HAIR_BLOCK) + set_uni_feature_block(blocknumber, construct_block(GLOB.pod_hair_list.Find(features["pod_hair"]), GLOB.pod_hair_list.len)) + if(DNA_SKRELL_HAIR_BLOCK) + set_uni_feature_block(blocknumber, construct_block(GLOB.skrell_hair_list.Find(features["skrell_hair"]),GLOB.skrell_hair_list.len)) + +/mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0) + ..() + var/structure = dna.unique_identity + hair_color = sanitize_hexcolor(get_uni_identity_block(structure, DNA_HAIR_COLOR_BLOCK)) + facial_hair_color = sanitize_hexcolor(get_uni_identity_block(structure, DNA_FACIAL_HAIR_COLOR_BLOCK)) + skin_tone = GLOB.skin_tones[deconstruct_block(get_uni_identity_block(structure, DNA_SKIN_TONE_BLOCK), GLOB.skin_tones.len)] + eye_color_left = sanitize_hexcolor(get_uni_identity_block(structure, DNA_EYE_COLOR_LEFT_BLOCK)) + eye_color_right = sanitize_hexcolor(get_uni_identity_block(structure, DNA_EYE_COLOR_RIGHT_BLOCK)) + if(HAS_TRAIT(src, TRAIT_SHAVED)) + hairstyle = "Shaved" + else + facial_hairstyle = GLOB.facial_hairstyles_list[deconstruct_block(get_uni_identity_block(structure, DNA_FACIAL_HAIRSTYLE_BLOCK), GLOB.facial_hairstyles_list.len)] + if(HAS_TRAIT(src, TRAIT_BALD)) + hairstyle = "Bald" + else + hairstyle = GLOB.hairstyles_list[deconstruct_block(get_uni_identity_block(structure, DNA_HAIRSTYLE_BLOCK), GLOB.hairstyles_list.len)] + var/features = dna.unique_features + if(dna.features["mcolor"]) + dna.features["mcolor"] = sanitize_hexcolor(get_uni_feature_block(features, DNA_MUTANT_COLOR_BLOCK)) + if(dna.features["ethcolor"]) + dna.features["ethcolor"] = sanitize_hexcolor(get_uni_feature_block(features, DNA_ETHEREAL_COLOR_BLOCK)) + if(dna.features["body_markings"]) + dna.features["body_markings"] = GLOB.body_markings_list[deconstruct_block(get_uni_feature_block(features, DNA_LIZARD_MARKINGS_BLOCK), GLOB.body_markings_list.len)] + if(dna.features["snout"]) + dna.features["snout"] = GLOB.snouts_list[deconstruct_block(get_uni_feature_block(features, DNA_SNOUT_BLOCK), GLOB.snouts_list.len)] + if(dna.features["horns"]) + dna.features["horns"] = GLOB.horns_list[deconstruct_block(get_uni_feature_block(features, DNA_HORNS_BLOCK), GLOB.horns_list.len)] + if(dna.features["frills"]) + dna.features["frills"] = GLOB.frills_list[deconstruct_block(get_uni_feature_block(features, DNA_FRILLS_BLOCK), GLOB.frills_list.len)] + if(dna.features["spines"]) + dna.features["spines"] = GLOB.spines_list[deconstruct_block(get_uni_feature_block(features, DNA_SPINES_BLOCK), GLOB.spines_list.len)] + if(dna.features["tail_cat"]) + dna.features["tail_cat"] = GLOB.tails_list_human[deconstruct_block(get_uni_feature_block(features, DNA_TAIL_BLOCK), GLOB.tails_list_human.len)] + if(dna.features["tail_lizard"]) + dna.features["tail_lizard"] = GLOB.tails_list_lizard[deconstruct_block(get_uni_feature_block(features, DNA_LIZARD_TAIL_BLOCK), GLOB.tails_list_lizard.len)] + if(dna.features["ears"]) + dna.features["ears"] = GLOB.ears_list[deconstruct_block(get_uni_feature_block(features, DNA_EARS_BLOCK), GLOB.ears_list.len)] + if(dna.features["moth_wings"]) + var/genetic_value = GLOB.moth_wings_list[deconstruct_block(get_uni_feature_block(features, DNA_MOTH_WINGS_BLOCK), GLOB.moth_wings_list.len)] + dna.features["original_moth_wings"] = genetic_value + dna.features["moth_wings"] = genetic_value + if(dna.features["moth_antennae"]) + var/genetic_value = GLOB.moth_antennae_list[deconstruct_block(get_uni_feature_block(features, DNA_MOTH_ANTENNAE_BLOCK), GLOB.moth_antennae_list.len)] + dna.features["original_moth_antennae"] = genetic_value + dna.features["moth_antennae"] = genetic_value + if(dna.features["moth_markings"]) + dna.features["moth_markings"] = GLOB.moth_markings_list[deconstruct_block(get_uni_feature_block(features, DNA_MOTH_MARKINGS_BLOCK), GLOB.moth_markings_list.len)] + if(dna.features["caps"]) + dna.features["caps"] = GLOB.caps_list[deconstruct_block(get_uni_feature_block(features, DNA_MUSHROOM_CAPS_BLOCK), GLOB.caps_list.len)] + if(dna.features["pod_hair"]) + dna.features["pod_hair"] = GLOB.pod_hair_list[deconstruct_block(get_uni_feature_block(features, DNA_POD_HAIR_BLOCK), GLOB.pod_hair_list.len)] + if(dna.features["skrell_hair"]) + dna.features["skrell_hair"] = GLOB.skrell_hair_list[deconstruct_block(get_uni_feature_block(features, DNA_SKRELL_HAIR_BLOCK), GLOB.skrell_hair_list.len)] + + for(var/obj/item/organ/external/external_organ in organs) + external_organ.mutate_feature(features, src) + + if(icon_update) + dna.species.handle_body(src) // We want 'update_body_parts(update_limb_data = TRUE)' to be called only if mutcolor_update is TRUE, so no 'update_body()' here. + update_body_parts() //We can call this because it doesnt refresh limb data, and it handles hair and such. + if(mutcolor_update) + update_body_parts(update_limb_data = TRUE) + if(mutations_overlay_update) + update_mutations_overlay() diff --git a/modular_galactic/skrell/skrell_eyes.dm b/modular_galactic/skrell/skrell_eyes.dm new file mode 100644 index 0000000000000..b76539441234c --- /dev/null +++ b/modular_galactic/skrell/skrell_eyes.dm @@ -0,0 +1,34 @@ +/////////////////////////////////////////////////// +// Skrell eyes // +/////////////////////////////////////////////////// + +#define OFFSET_X 1 +#define OFFSET_Y 2 +/obj/item/organ/internal/eyes/skrell/generate_body_overlay(mob/living/carbon/human/parent) + if(!istype(parent) || parent.getorgan(/obj/item/organ/internal/eyes) != src) + CRASH("Generating a body overlay for [src] targeting an invalid parent '[parent]'.") + + var/mutable_appearance/eye_left = mutable_appearance('modular_galactic/skrell/skrell_eyes.dmi', "[eye_icon_state]_l", -BODY_LAYER) + var/mutable_appearance/eye_right = mutable_appearance('modular_galactic/skrell/skrell_eyes.dmi', "[eye_icon_state]_r", -BODY_LAYER) + var/list/overlays = list(eye_left, eye_right) + + if(EYECOLOR in parent.dna?.species.species_traits) + eye_right.color = eye_color_right + eye_left.color = eye_color_left + + var/obscured = parent.check_obscured_slots(TRUE) + if(overlay_ignore_lighting && !(obscured & ITEM_SLOT_EYES)) + eye_left.overlays += emissive_appearance(eye_left.icon, eye_left.icon_state, parent, alpha = eye_left.alpha) + eye_right.overlays += emissive_appearance(eye_right.icon, eye_right.icon_state, parent, alpha = eye_right.alpha) + + + if(OFFSET_FACE in parent.dna?.species.offset_features) + var/offset = parent.dna.species.offset_features[OFFSET_FACE] + for(var/mutable_appearance/overlay in overlays) + overlay.pixel_x += offset[OFFSET_X] + overlay.pixel_y += offset[OFFSET_Y] + + return overlays + +#undef OFFSET_X +#undef OFFSET_Y diff --git a/modular_galactic/skrell/skrell_eyes.dmi b/modular_galactic/skrell/skrell_eyes.dmi new file mode 100644 index 0000000000000..020b3251f95d7 Binary files /dev/null and b/modular_galactic/skrell/skrell_eyes.dmi differ diff --git a/modular_galactic/skrell/skrell_language.dm b/modular_galactic/skrell/skrell_language.dm new file mode 100644 index 0000000000000..dd2b3c3762e37 --- /dev/null +++ b/modular_galactic/skrell/skrell_language.dm @@ -0,0 +1,29 @@ +/////////////////////////////////////////////////// +// Skrell lang and lang holder // +/////////////////////////////////////////////////// + +/datum/language/skrell + name = "Skrellian" + desc = "The language of the skrells. A bunch of warbling and musical tone." + space_chance = 100 + flags = TONGUELESS_SPEECH + key = "K" + syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix","*","!") + default_priority = 90 + icon = 'modular_galactic/skrell/skrell.dmi' + icon_state = "skrell" + + +/datum/language_holder/skrell + understood_languages = list( + /datum/language/common = list(LANGUAGE_ATOM), + /datum/language/skrell = list(LANGUAGE_ATOM), + /datum/language/slime = list(LANGUAGE_ATOM) + ) + + spoken_languages = list( + /datum/language/common = list(LANGUAGE_ATOM), + /datum/language/skrell = list(LANGUAGE_ATOM), + /datum/language/slime = list(LANGUAGE_ATOM) + ) + diff --git a/modular_galactic/skrell/skrell_organs.dm b/modular_galactic/skrell/skrell_organs.dm new file mode 100644 index 0000000000000..f45d01043131c --- /dev/null +++ b/modular_galactic/skrell/skrell_organs.dm @@ -0,0 +1,20 @@ +//////Duplicated from code\modules\surgery\organs\liver.dm///////////// +#define LIVER_DEFAULT_TOX_TOLERANCE 3 //amount of toxins the liver can filter out +#define LIVER_DEFAULT_TOX_RESISTANCE 1 //lower values lower how harmful toxins are to the liver +#define LIVER_FAILURE_STAGE_SECONDS 60 //amount of seconds before liver failure reaches a new stage +#define MAX_TOXIN_LIVER_DAMAGE 2 //the max damage the liver can recieve per second (~1 min at max damage will destroy liver) +/////////////////////////////////////////////////////////////////////// + +/obj/item/organ/internal/liver/skrell + name = "skrell liver" + icon_state = "liver" + icon = 'modular_galactic/skrell/skrell_organs.dmi' + alcohol_tolerance = 3 + toxTolerance = 10 //can shrug off up to 10u of toxins. + liver_resistance = 1.2 * LIVER_DEFAULT_TOX_RESISTANCE + + +#undef LIVER_DEFAULT_TOX_TOLERANCE +#undef LIVER_DEFAULT_TOX_RESISTANCE +#undef LIVER_FAILURE_STAGE_SECONDS +#undef MAX_TOXIN_LIVER_DAMAGE diff --git a/modular_galactic/skrell/skrell_organs.dmi b/modular_galactic/skrell/skrell_organs.dmi new file mode 100644 index 0000000000000..327e9983a171c Binary files /dev/null and b/modular_galactic/skrell/skrell_organs.dmi differ diff --git a/modular_galactic/skrell/skrell_pocket.dm b/modular_galactic/skrell/skrell_pocket.dm new file mode 100644 index 0000000000000..e5f8ec086c03e --- /dev/null +++ b/modular_galactic/skrell/skrell_pocket.dm @@ -0,0 +1,74 @@ +///////////////////////////////////////////////////////////////// +//Storage datum and open_storage override for additional checks// +///////////////////////////////////////////////////////////////// + +/datum/storage/skrell_pocket + max_specific_storage = WEIGHT_CLASS_SMALL + max_total_storage = 3 + max_slots = 1 + allow_big_nesting = FALSE + +/datum/storage/skrell_pocket/open_storage(mob/to_show) + var/obj/item/resolve_parent = parent?.resolve() + if(!resolve_parent) + return FALSE + + var/obj/item/resolve_location = real_location?.resolve() + if(!resolve_location) + return FALSE + + if(isobserver(to_show)) + show_contents(to_show) + return FALSE + + if(istype(to_show,/mob/living/carbon)) + var/mob/living/carbon/C = to_show + var/obj/item/storage/skrell_pocket/pocket = resolve_parent + if(!pocket||!(pocket in C.contents)) + resolve_parent.balloon_alert(to_show, "Non-skrells can't use the pocket!") + return FALSE + else if(!is_species(to_show,/datum/species/skrell)) + resolve_parent.balloon_alert(to_show, "Non-skrells can't use the pocket!") + return FALSE + var/datum/dna/dna = C.has_dna() + if(!dna||dna.features["skrell_hair"]=="Bald") + resolve_parent.balloon_alert(to_show, "pocket cant be used without tails!") + return FALSE + + + if(!isliving(to_show) || to_show.incapacitated()) + return FALSE + + if(locked) + if(!silent) + resolve_parent.balloon_alert(to_show, "locked!") + return FALSE + + if(!quickdraw || to_show.get_active_held_item()) + if(display_contents) + show_contents(to_show) + + if(animated) + animate_parent() + + if(rustle_sound) + playsound(resolve_parent, SFX_RUSTLE, 50, TRUE, -5) + + return TRUE + + var/obj/item/to_remove = locate() in resolve_location + + if(!to_remove) + return TRUE + + attempt_remove(to_remove) + + INVOKE_ASYNC(src, PROC_REF(put_in_hands_async), to_show, to_remove) + + if(!silent) + to_show.visible_message(span_warning("[to_show] draws [to_remove] from [resolve_parent]!"), span_notice("You draw [to_remove] from [resolve_parent].")) + + return TRUE + + + diff --git a/modular_galactic/skrell/skrell_tails.dm b/modular_galactic/skrell/skrell_tails.dm new file mode 100644 index 0000000000000..2975335024c06 --- /dev/null +++ b/modular_galactic/skrell/skrell_tails.dm @@ -0,0 +1,56 @@ +//////////////////////////////////////////////////////////////////////// +//Skrell tail external organ, action override and abstract pocket item// +//////////////////////////////////////////////////////////////////////// + +/obj/item/organ/external/skrell + name = "skrell hair" + icon = 'modular_galactic/skrell/skrell_organs.dmi' + icon_state = "skrell_headpocket" + desc = "For stroking these tails you can apply for alimony" + zone = BODY_ZONE_HEAD + slot = ORGAN_SLOT_EXTERNAL_SKRELL_HAIR + dna_block = DNA_SKRELL_HAIR_BLOCK + preference = "feature_skrell_hair" + actions_types = list(/datum/action/item_action/organ_action/use/skrell_pocket) + restyle_flags = EXTERNAL_RESTYLE_FLESH + bodypart_overlay = /datum/bodypart_overlay/mutant/skrell + var/obj/item/storage/skrell_pocket/pocket + +/datum/bodypart_overlay/mutant/skrell + layers = EXTERNAL_FRONT|EXTERNAL_ADJACENT + feature_key = "skrell_hair" + +/datum/bodypart_overlay/mutant/skrell/can_draw_on_bodypart(mob/living/carbon/human/human) + if(!(human.head?.flags_inv & HIDEHAIR) || (human.wear_mask?.flags_inv & HIDEHAIR)) + return TRUE + return FALSE + +/obj/item/organ/external/skrell/ui_action_click(mob/user, actiontype) + pocket.atom_storage?.open_storage(user) + +/datum/bodypart_overlay/mutant/skrell/get_global_feature_list() + return GLOB.skrell_hair_list + +/obj/item/organ/external/skrell/Insert(mob/living/carbon/reciever, special, drop_if_replaced) + . = ..() + pocket = new /obj/item/storage/skrell_pocket(reciever) + +/obj/item/organ/external/skrell/Remove(mob/living/carbon/organ_owner, special, moving) + . = ..() + if(src&&src.loc&&pocket&&pocket.atom_storage) + pocket.atom_storage.remove_all() + qdel(pocket) + +/obj/item/storage/skrell_pocket + name = "Skrell's pocket" + desc = "Most likely you shouldn't see it" + item_flags = ABSTRACT | DROPDEL + resistance_flags = INDESTRUCTIBLE + +/obj/item/storage/skrell_pocket/New(loc, ...) + create_storage(storage_type = /datum/storage/skrell_pocket) + +/datum/action/item_action/organ_action/use/skrell_pocket + name = "Open pocket" + button_icon = 'modular_galactic/skrell/skrell_organs.dmi' + button_icon_state = "skrell_headpocket" diff --git a/modular_galactic/skrell/tails.dmi b/modular_galactic/skrell/tails.dmi new file mode 100644 index 0000000000000..2678ca59cc021 Binary files /dev/null and b/modular_galactic/skrell/tails.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 323b9ba332c0f..e6c07245284e2 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -5148,4 +5148,14 @@ #include "interface\menu.dm" #include "interface\stylesheet.dm" #include "interface\skin.dmf" +#include "modular_galactic\skrell\skrell_defines.dm" +#include "modular_galactic\skrell\skrell_accessory.dm" +#include "modular_galactic\skrell\skrell_accessory_preference.dm" +#include "modular_galactic\skrell\skrell_bodyparts.dm" +#include "modular_galactic\skrell\skrell_eyes.dm" +#include "modular_galactic\skrell\skrell_language.dm" +#include "modular_galactic\skrell\skrell_organs.dm" +#include "modular_galactic\skrell\skrell_pocket.dm" +#include "modular_galactic\skrell\skrell_tails.dm" +#include "modular_galactic\skrell\skrell.dm" // END_INCLUDE