From c570e5bae10cfd41d6c1dd5736660fd0e0786756 Mon Sep 17 00:00:00 2001 From: Spaghetti-Bit Date: Tue, 1 Oct 2024 05:04:03 -0600 Subject: [PATCH 01/22] Pain --- SQL/updates/60-61.sql | 6 + code/__DEFINES/flags.dm | 7 +- code/__DEFINES/misc_defines.dm | 2 +- code/modules/client/preference/character.dm | 121 ++++++++++-------- .../client/preference/link_processing.dm | 6 + code/modules/client/preference/preferences.dm | 2 + .../mob/living/carbon/human/human_defines.dm | 2 + .../living/carbon/human/human_update_icons.dm | 19 ++- .../living/carbon/human/species/_species.dm | 11 +- .../living/carbon/human/species/machine.dm | 64 ++++++++- .../carbon/human/species/slimepeople.dm | 104 ++++++++++++++- code/modules/surgery/robotics.dm | 21 ++- 12 files changed, 298 insertions(+), 67 deletions(-) create mode 100644 SQL/updates/60-61.sql diff --git a/SQL/updates/60-61.sql b/SQL/updates/60-61.sql new file mode 100644 index 0000000000000..eeedc3c8c6f29 --- /dev/null +++ b/SQL/updates/60-61.sql @@ -0,0 +1,6 @@ +# Updates the DB from 60 to 61 ~SpaghettiBit +# Adds a subtype race to be stored on character saves + +# Add species_subtype after species +ALTER TABLE `characters` + ADD COLUMN `species_subtype` VARCHAR(7) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'None' AFTER `species`; diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index c4a222ebc141a..dafe9ef78ffc2 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -107,9 +107,10 @@ #define HAS_ALT_HEADS (1<<11) #define HAS_WING (1<<12) #define HAS_BODYACC_COLOR (1<<13) -#define BALD (1<<14) -#define ALL_RPARTS (1<<15) -#define SHAVED (1<<16) +#define HAS_SPECIES_SUBTYPE (1<<14) +#define BALD (1<<15) +#define ALL_RPARTS (1<<16) +#define SHAVED (1<<17) //Pre-baked combinations of the above body flags #define HAS_BODY_ACCESSORY (HAS_TAIL | HAS_WING) diff --git a/code/__DEFINES/misc_defines.dm b/code/__DEFINES/misc_defines.dm index 7d5b8ecdb2526..ee9e361d36df4 100644 --- a/code/__DEFINES/misc_defines.dm +++ b/code/__DEFINES/misc_defines.dm @@ -423,7 +423,7 @@ #define INVESTIGATE_HOTMIC "hotmic" // The SQL version required by this version of the code -#define SQL_VERSION 60 +#define SQL_VERSION 61 // Vending machine stuff #define CAT_NORMAL (1<<0) diff --git a/code/modules/client/preference/character.dm b/code/modules/client/preference/character.dm index 1a598016a8f17..db41e06286928 100644 --- a/code/modules/client/preference/character.dm +++ b/code/modules/client/preference/character.dm @@ -37,6 +37,8 @@ var/e_colour = "#000000" //Eye color var/alt_head = "None" //Alt head style. var/species = "Human" + /// Used for DNA species to allow select species to imitate / morph into different species. + var/species_subtype = "None" var/language = "None" //Secondary language var/autohiss_mode = AUTOHISS_OFF //Species autohiss level. OFF, BASIC, FULL. /// If a spawned cyborg should have an MMI, a positronic, or a robobrain. MMI by default @@ -147,6 +149,7 @@ body_type=:body_type, age=:age, species=:species, + species_subtype=:species_subtype, language=:language, hair_colour=:h_colour, secondary_hair_colour=:h_sec_colour, @@ -210,6 +213,7 @@ "body_type" = body_type, "age" = age, "species" = species, + "species_subtype" = species_subtype, "language" = language, "h_colour" = h_colour, "h_sec_colour" = h_sec_colour, @@ -278,7 +282,7 @@ var/datum/db_query/query = SSdbcore.NewQuery({" INSERT INTO characters (ckey, slot, OOC_Notes, real_name, name_is_always_random, gender, - age, species, language, + age, species, species_subtype, language, hair_colour, secondary_hair_colour, facial_hair_colour, secondary_facial_hair_colour, skin_tone, skin_colour, @@ -305,7 +309,7 @@ hair_gradient, hair_gradient_offset, hair_gradient_colour, hair_gradient_alpha, custom_emotes, runechat_color, cyborg_brain_type, body_type) VALUES (:ckey, :slot, :metadata, :name, :be_random_name, :gender, - :age, :species, :language, + :age, :species, :species_subtype, :language, :h_colour, :h_sec_colour, :f_colour, :f_sec_colour, :s_tone, :s_colour, @@ -341,6 +345,7 @@ "body_type" = body_type, "age" = age, "species" = species, + "species_subtype" = species_subtype, "language" = language, "h_colour" = h_colour, "h_sec_colour" = h_sec_colour, @@ -416,45 +421,45 @@ gender = query.item[4] age = text2num(query.item[5]) species = query.item[6] - language = query.item[7] - - h_colour = query.item[8] - h_sec_colour = query.item[9] - f_colour = query.item[10] - f_sec_colour = query.item[11] - s_tone = text2num(query.item[12]) - s_colour = query.item[13] - m_colours = params2list(query.item[14]) - hacc_colour = query.item[15] - h_style = query.item[16] - f_style = query.item[17] - m_styles = params2list(query.item[18]) - ha_style = query.item[19] - alt_head = query.item[20] - e_colour = query.item[21] - underwear = query.item[22] - undershirt = query.item[23] - backbag = query.item[24] - b_type = query.item[25] + species_subtype = query.item[7] + language = query.item[8] + h_colour = query.item[9] + h_sec_colour = query.item[10] + f_colour = query.item[11] + f_sec_colour = query.item[12] + s_tone = text2num(query.item[13]) + s_colour = query.item[14] + m_colours = params2list(query.item[15]) + hacc_colour = query.item[16] + h_style = query.item[17] + f_style = query.item[18] + m_styles = params2list(query.item[19]) + ha_style = query.item[20] + alt_head = query.item[21] + e_colour = query.item[22] + underwear = query.item[23] + undershirt = query.item[24] + backbag = query.item[25] + b_type = query.item[26] //Jobs - alternate_option = text2num(query.item[26]) - job_support_high = text2num(query.item[27]) - job_support_med = text2num(query.item[28]) - job_support_low = text2num(query.item[29]) - job_medsci_high = text2num(query.item[30]) - job_medsci_med = text2num(query.item[31]) - job_medsci_low = text2num(query.item[32]) - job_engsec_high = text2num(query.item[33]) - job_engsec_med = text2num(query.item[34]) - job_engsec_low = text2num(query.item[35]) + alternate_option = text2num(query.item[27]) + job_support_high = text2num(query.item[28]) + job_support_med = text2num(query.item[29]) + job_support_low = text2num(query.item[30]) + job_medsci_high = text2num(query.item[31]) + job_medsci_med = text2num(query.item[32]) + job_medsci_low = text2num(query.item[33]) + job_engsec_high = text2num(query.item[34]) + job_engsec_med = text2num(query.item[35]) + job_engsec_low = text2num(query.item[36]) //Miscellaneous - flavor_text = query.item[36] - med_record = query.item[37] - sec_record = query.item[38] - gen_record = query.item[39] + flavor_text = query.item[37] + med_record = query.item[38] + sec_record = query.item[39] + gen_record = query.item[40] // Apparently, the preceding vars weren't always encoded properly... if(findtext(flavor_text, "<")) // ... so let's clumsily check for tags! flavor_text = html_encode(flavor_text) @@ -464,29 +469,29 @@ sec_record = html_encode(sec_record) if(findtext(gen_record, "<")) gen_record = html_encode(gen_record) - disabilities = text2num(query.item[40]) - player_alt_titles = params2list(query.item[41]) - organ_data = params2list(query.item[42]) - rlimb_data = params2list(query.item[43]) - nanotrasen_relation = query.item[44] - speciesprefs = text2num(query.item[45]) + disabilities = text2num(query.item[41]) + player_alt_titles = params2list(query.item[42]) + organ_data = params2list(query.item[43]) + rlimb_data = params2list(query.item[44]) + nanotrasen_relation = query.item[45] + speciesprefs = text2num(query.item[46]) //socks - socks = query.item[46] - body_accessory = query.item[47] - loadout_gear = query.item[48] - autohiss_mode = text2num(query.item[49]) + socks = query.item[47] + body_accessory = query.item[48] + loadout_gear = query.item[49] // Index [50] is the slot - h_grad_style = query.item[51] - h_grad_offset_x = query.item[52] // parsed down below - h_grad_colour = query.item[53] - h_grad_alpha = query.item[54] - var/custom_emotes_tmp = query.item[55] - runechat_color = query.item[56] - physique = query.item[57] - height = query.item[58] - cyborg_brain_type = query.item[59] - body_type = query.item[60] + autohiss_mode = text2num(query.item[51]) + h_grad_style = query.item[52] + h_grad_offset_x = query.item[53] // parsed down below + h_grad_colour = query.item[54] + h_grad_alpha = query.item[55] + var/custom_emotes_tmp = query.item[56] + runechat_color = query.item[57] + physique = query.item[58] + height = query.item[59] + cyborg_brain_type = query.item[60] + body_type = query.item[61] //Sanitize var/datum/species/SP = GLOB.all_species[species] @@ -501,6 +506,9 @@ species = "Human" stack_trace("Character doesn't have a species, character name is [real_name]. Defaulting to human.") + if(isnull(species_subtype)) + species_subtype = "None" + if(isnull(language)) language = "None" @@ -1813,6 +1821,7 @@ /datum/character_save/proc/copy_to(mob/living/carbon/human/character) var/datum/species/S = GLOB.all_species[species] character.set_species(S.type, delay_icon_update = TRUE) // Yell at me if this causes everything to melt + character.species_subtype = species_subtype if(be_random_name) real_name = random_name(gender, species) diff --git a/code/modules/client/preference/link_processing.dm b/code/modules/client/preference/link_processing.dm index 99966235522ff..5500f74622459 100644 --- a/code/modules/client/preference/link_processing.dm +++ b/code/modules/client/preference/link_processing.dm @@ -292,6 +292,12 @@ if(!(NS.autohiss_basic_map)) active_character.autohiss_mode = AUTOHISS_OFF + if("species_subtype") + if(S.bodyflags & HAS_SPECIES_SUBTYPE) + var/new_subtype = tgui_input_list(user, "Choose your character's species subtype:", "Character Preference", S.allowed_species_subtypes) + if(isnull(new_subtype)) + return + active_character.species_subtype = new_subtype if("speciesprefs") active_character.speciesprefs = !active_character.speciesprefs //Starts 0, so if someone clicks the button up top there, this won't be 0 anymore. If they click it again, it'll go back to 0. if("language") diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index 2191f4a34f4e2..df5c74ce8d348 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -203,6 +203,8 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts dat += "Age: [active_character.age]
" dat += "Body: (®)
" dat += "Species: [active_character.species]
" + if(S.bodyflags & HAS_SPECIES_SUBTYPE) + dat += "Species Sub-Type: [active_character.species_subtype]
" dat += "Gender: [active_character.gender == MALE ? "Male" : (active_character.gender == FEMALE ? "Female" : "Genderless")]
" dat += "Body Type: [active_character.body_type == MALE ? "Masculine" : "Feminine"]" dat += "
" diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index 501eda399e798..e013d187f250a 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -20,6 +20,8 @@ var/list/m_styles = DEFAULT_MARKING_STYLES //All markings set to None. var/s_tone = 0 //Skin tone + /// Species Sub-Type - overrites the species_sheet_name when it's not "None", acts the same as a skin tone. + var/species_subtype = "None" //Skin colour var/skin_colour = "#000000" 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 47f744999feb1..bbeecbd097d1a 100644 --- a/code/modules/mob/living/carbon/human/human_update_icons.dm +++ b/code/modules/mob/living/carbon/human/human_update_icons.dm @@ -172,8 +172,11 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) var/hulk = HAS_TRAIT(src, TRAIT_HULK) var/skeleton = HAS_TRAIT(src, TRAIT_SKELETONIZED) - if(dna.species && dna.species.bodyflags & HAS_ICON_SKIN_TONE) - dna.species.updatespeciescolor(src) + if(dna.species) + if(dna.species.bodyflags & HAS_ICON_SKIN_TONE) + dna.species.updatespeciescolor(src) + if(dna.species.bodyflags & HAS_SPECIES_SUBTYPE) + dna.species.updatespeciessubtype(src) //CACHING: Generate an index key from visible bodyparts. //0 = destroyed, 1 = normal, 2 = robotic, 3 = necrotic. @@ -236,6 +239,10 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) husk_over.Blend(mask, ICON_ADD) base_icon.Blend(husk_over, ICON_OVERLAY) + if(istype(src.dna.species, /datum/species/slime) && species_subtype != "None") // Used for a when slime morphs into another species. Makes them slightly transparent. + base_icon.GrayScale() + base_icon.Blend("[skin_colour]DC", ICON_AND) //DC = 220 alpha. + var/mutable_appearance/new_base = mutable_appearance(base_icon, layer = -LIMBS_LAYER) GLOB.human_icon_cache[icon_key] = new_base standing += new_base @@ -1237,6 +1244,9 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) if(HAS_TRAIT(src, TRAIT_I_WANT_BRAINS)) wings_icon.ColorTone(COLORTONE_DEAD_EXT_ORGAN) wings_icon.SetIntensity(0.7) + if(istype(src.dna.species, /datum/species/slime) && species_subtype != "None") // Slimfies the wings + wings_icon.GrayScale() + wings_icon.Blend("[skin_colour]DC", ICON_AND) //DC = 220 alpha. var/mutable_appearance/wings = mutable_appearance(wings_icon, layer = -WING_LAYER) wings.pixel_x = body_accessory.pixel_x_offset wings.pixel_y = body_accessory.pixel_y_offset @@ -1281,6 +1291,11 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) accessory_s.Blend(skin_colour, body_accessory.blend_mode) if(tail_marking_icon && (body_accessory.name in tail_marking_style.tails_allowed)) accessory_s.Blend(tail_marking_icon, ICON_OVERLAY) + + if(istype(src.dna.species, /datum/species/slime) && species_subtype != "None") // Slimfies the tail + accessory_s.GrayScale() + accessory_s.Blend("[skin_colour]A0", ICON_AND) //DC = 160 alpha. Less alpha here because the tail is generally stubborn... + if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. var/icon/under = new/icon("icon" = 'icons/mob/body_accessory.dmi', "icon_state" = "accessory_none_s") diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm index 26b07818d2dc0..910c7eab506a5 100644 --- a/code/modules/mob/living/carbon/human/species/_species.dm +++ b/code/modules/mob/living/carbon/human/species/_species.dm @@ -3,6 +3,10 @@ var/name /// Pluralized name (since "[name]s" is not always valid) var/name_plural + /// Sub-type of the species. Used for when slimes imitate a species or when an IPC has augments that look like another species. This will affect sprite_sheet_name + var/species_subtype = "None" + /// List of available sub-types for the species to imitate / morph into (Machine / Slime) + var/allowed_species_subtypes = list() /// The corresponding key for spritesheets var/sprite_sheet_name /// Article to use when referring to an individual of the species, if pronunciation is different from expected. @@ -198,7 +202,9 @@ /datum/species/New() unarmed = new unarmed_type() - if(!sprite_sheet_name) + if(!isnull(species_subtype) && species_subtype != "None") + sprite_sheet_name = species_subtype + else if(!sprite_sheet_name) sprite_sheet_name = name /datum/species/proc/get_random_name(gender) @@ -395,6 +401,9 @@ /datum/species/proc/updatespeciescolor(mob/living/carbon/human/H) //Handles changing icobase for species that have multiple skin colors. return +/datum/species/proc/updatespeciessubtype(mob/living/carbon/human/H) // Handles changing icobase for species that can imitate/morph into other species + return + // Do species-specific reagent handling here // Return 1 if it should do normal processing too // Return the parent value if processing does not explicitly stop diff --git a/code/modules/mob/living/carbon/human/species/machine.dm b/code/modules/mob/living/carbon/human/species/machine.dm index a7503197e8415..2f810e41d119a 100644 --- a/code/modules/mob/living/carbon/human/species/machine.dm +++ b/code/modules/mob/living/carbon/human/species/machine.dm @@ -24,7 +24,7 @@ inherent_traits = list(TRAIT_VIRUSIMMUNE, TRAIT_NOBREATH, TRAIT_NOGERMS, TRAIT_NODECAY, TRAIT_NOPAIN, TRAIT_GENELESS) //Computers that don't decay? What a lie! inherent_biotypes = MOB_ROBOTIC | MOB_HUMANOID clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_SKIN_COLOR | HAS_HEAD_MARKINGS | HAS_HEAD_ACCESSORY | ALL_RPARTS | SHAVED + bodyflags = HAS_SKIN_COLOR | HAS_HEAD_MARKINGS | HAS_HEAD_ACCESSORY | ALL_RPARTS | SHAVED | HAS_SPECIES_SUBTYPE dietflags = 0 //IPCs can't eat, so no diet taste_sensitivity = TASTE_SENSITIVITY_NO_TASTE blood_color = COLOR_BLOOD_MACHINE @@ -74,6 +74,68 @@ "is frying their own circuits!", "is blocking their ventilation port!") + allowed_species_subtypes = list( + 1 = "None", + 2 = "Vox", + 3 = "Unathi", + 4 = "Nian" + ) + +/datum/species/machine/updatespeciessubtype(mob/living/carbon/human/H, owner_sensitive = 1) //Handling species-subtype and imitation + if(H.dna.species.bodyflags & HAS_SPECIES_SUBTYPE) + var/new_icobase = 'icons/mob/human_races/r_machine.dmi' //Default IPC. + if(H.species_subtype == species_subtype) // No update, no need to go further. + return + switch(H.species_subtype) + if("Nian") + new_icobase = 'icons/mob/human_races/nian/r_moth.dmi' + species_subtype = "Nian" + tail = null + wing = "plain" + bodyflags |= (HAS_HEAD_ACCESSORY | HAS_WING) + H.body_accessory = null + if("Unathi") // Unathi + new_icobase = 'icons/mob/human_races/r_lizard.dmi' + species_subtype = "Unathi" + tail = "sogtail" + wing = null + bodyflags |= (HAS_HEAD_ACCESSORY | HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED) + H.body_accessory = null + if("Vox") // Vox :) + new_icobase = 'icons/mob/human_races/vox/r_voxgry.dmi' + tail = "voxtail_gry" + wing = null + species_subtype = "Vox" + bodyflags |= (HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED) + H.body_accessory = null + if("None") // Regular IPC + // Reset + new_icobase = initial(icobase) + species_subtype = "None" + tail = initial(tail) + eyes = initial(eyes) + wing = initial(wing) + bodyflags = initial(bodyflags) + H.body_accessory = null + if(species_subtype != "None") + sprite_sheet_name = species_subtype + else + sprite_sheet_name = name + for(var/obj/item/organ/external/limb in H.bodyparts) // Update robotic limbs to match new sub species ico base + limb.set_company(limb.model, sprite_sheet_name) + + // Update misc parts that are stored as reference in species and used on the mob. Also resets stylings to none to prevent anything wacky... + H.tail = tail + H.wing = wing + + var/obj/item/organ/external/head/head = H.get_organ("head") + head.h_style = "Bald" + head.f_style = "Shaved" + head.ha_style = "None" + H.s_tone = 0 + H.m_styles = DEFAULT_MARKING_STYLES //Wipes out markings, setting them all to "None". + H.m_colours = DEFAULT_MARKING_COLOURS //Defaults colour to #00000 for all markings. + H.change_icobase(new_icobase, owner_sensitive) //Update the icobase of all our organs, but make sure we don't mess with frankenstein limbs in doing so. /datum/species/machine/on_species_gain(mob/living/carbon/human/H) ..() diff --git a/code/modules/mob/living/carbon/human/species/slimepeople.dm b/code/modules/mob/living/carbon/human/species/slimepeople.dm index bcf0f0f9b64fb..d371de7d04f80 100644 --- a/code/modules/mob/living/carbon/human/species/slimepeople.dm +++ b/code/modules/mob/living/carbon/human/species/slimepeople.dm @@ -36,7 +36,7 @@ species_traits = list(LIPS, NO_CLONESCAN, EXOTIC_COLOR) inherent_traits = list(TRAIT_WATERBREATH, TRAIT_NO_BONES) clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_SKIN_COLOR | NO_EYES + bodyflags = HAS_SKIN_COLOR | NO_EYES | HAS_SPECIES_SUBTYPE dietflags = DIET_CARN reagent_tag = PROCESS_ORG @@ -57,6 +57,14 @@ "is ripping out their own core!", "is turning a dull, brown color and melting into a puddle!") + allowed_species_subtypes = list( + 1 = "None", + 2 = "Vox", + 3 = "Unathi", + 4 = "Tajaran", + 5 = "Nian" + ) + var/reagent_skin_coloring = FALSE /datum/species/slime/on_species_gain(mob/living/carbon/human/H) @@ -65,6 +73,8 @@ grow.Grant(H) var/datum/action/innate/slimecolor/recolor = new() recolor.Grant(H) + var/datum/action/innate/morphform/reform = new() + reform.Grant(H) RegisterSignal(H, COMSIG_HUMAN_UPDATE_DNA, PROC_REF(blend)) blend(H) @@ -76,8 +86,82 @@ i.Remove(H) if(istype(i, /datum/action/innate/regrow)) i.Remove(H) + if(istype(i, /datum/action/innate/morphform)) + i.Remove(H) UnregisterSignal(H, COMSIG_HUMAN_UPDATE_DNA) +/datum/species/slime/updatespeciessubtype(mob/living/carbon/human/H, owner_sensitive = 1) //Handling species-subtype and imitation + if(H.dna.species.bodyflags & HAS_SPECIES_SUBTYPE) + var/new_icobase = 'icons/mob/human_races/r_slime.dmi' //Default slime person. + if(H.species_subtype == species_subtype) // No update, no need to go further. + return + bodyflags = initial(bodyflags) + switch(H.species_subtype) + if("Nian") // Nian + new_icobase = 'icons/mob/human_races/nian/r_moth.dmi' + species_subtype = "Nian" + tail = null + wing = "plain" + bodyflags |= (HAS_HEAD_ACCESSORY | HAS_WING) + H.body_accessory = null + if("Tajaran") // Tajaran + new_icobase = 'icons/mob/human_races/r_tajaran.dmi' + species_subtype = "Tajaran" + tail = "tajtail" + wing = null + bodyflags |= (HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED) + H.body_accessory = null + if("Unathi") // Unathi + new_icobase = 'icons/mob/human_races/r_lizard.dmi' + species_subtype = "Unathi" + tail = "sogtail" + wing = null + bodyflags |= (HAS_HEAD_ACCESSORY | HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED) + H.body_accessory = null + if("Vox") // Vox :) + new_icobase = 'icons/mob/human_races/vox/r_voxgry.dmi' + tail = "voxtail_gry" + wing = null + species_subtype = "Vox" + bodyflags |= (HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED) + H.body_accessory = null + if("None") // Regular slime person + // Reset + new_icobase = initial(icobase) + species_subtype = "None" + tail = null + eyes = initial(eyes) + wing = null + bodyflags = initial(bodyflags) + H.body_accessory = null + + if(species_subtype != "None") + sprite_sheet_name = species_subtype + else + sprite_sheet_name = name + var/datum/species/s = GLOB.all_species[species_subtype] + if(isnull(s)) + s = src + for(var/obj/item/organ/external/limb in H.bodyparts) // Update robotic limbs to match new sub species ico base in the case they have robotic limbs + limb.icobase = s.icobase // update their icobase for when we apply the slimfy effect + limb.set_company(limb.model, sprite_sheet_name) + + // Update misc parts that are stored as reference in species and used on the mob. Also resets stylings to none to prevent anything wacky... + H.tail = tail + H.wing = wing + + var/obj/item/organ/external/head/head = H.get_organ("head") + head.h_style = "Bald" + head.f_style = "Shaved" + head.ha_style = "None" + H.s_tone = 0 + H.m_styles = DEFAULT_MARKING_STYLES //Wipes out markings, setting them all to "None". + H.m_colours = DEFAULT_MARKING_COLOURS //Defaults colour to #00000 for all markings. + H.change_icobase(new_icobase, owner_sensitive) //Update the icobase of all our organs, but make sure we don't mess with frankenstein limbs in doing so. + +/datum/species/slime/proc/slimify(mob/living/carbon/human/H) // WIP -- MutableAppearance, greyscale then overlay slime color over. + return + /datum/species/slime/proc/blend(mob/living/carbon/human/H) var/new_color = BlendRGB(H.skin_colour, "#acacac", 0.5) // Blends this to make it work better if(H.dna.species.blood_color != new_color) // Put here, so if it's a roundstart, dyed, or CMA'd slime, their blood changes to match skin @@ -199,6 +283,24 @@ else to_chat(H, "You need to hold still in order to regrow a limb!") +/datum/action/innate/morphform + name = "Morph Form" + check_flags = AB_CHECK_CONSCIOUS + button_overlay_icon = 'icons/effects/effects.dmi' + button_overlay_icon_state = "greenglow" + +/datum/action/innate/morphform/Activate() + var/mob/living/carbon/human/H = owner + var/new_subtype = tgui_input_list(H, "Choose a species to imitate", "Select Subtype", H.dna.species.allowed_species_subtypes) + if(H.species_subtype == new_subtype) + return to_chat(H, "You stand there as your body shifts and then returns to its original form.") + H.visible_message("[H] begins to hold still and concentrate on [H.p_their()] form as it begins to shift and contort...", "You begin to focus on changing your form... (This will take [round(50/10)] seconds, and you must hold still.)") + if(do_after(H, 50, FALSE, H, extra_checks = list(CALLBACK(H, TYPE_PROC_REF(/mob/living, IsStunned))), use_default_checks = FALSE)) // Override the check for weakness, only check for stunned + H.species_subtype = new_subtype + H.dna.species.updatespeciessubtype(H) + H.regenerate_icons() + else + to_chat(H, "You need to hold still in order to shift your form!") #undef SLIMEPERSON_COLOR_SHIFT_TRIGGER #undef SLIMEPERSON_ICON_UPDATE_PERIOD #undef SLIMEPERSON_BLOOD_SCALING_FACTOR diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index 5c7f42e33cd0a..c66dbae05bf1b 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -753,13 +753,30 @@ else if(!target.Adjacent(user)) to_chat(user, "The multitool is out of range! Please try again.") return SURGERY_STEP_INCOMPLETE + + var/new_subtype = tgui_input_list(user, "Choose a species look-alike for this machine", "Select Subtype", target.dna.species.allowed_species_subtypes) + if(isnull(new_subtype)) + to_chat(user, "You must choose a subtype! Please try again.") + return SURGERY_STEP_INCOMPLETE + else if(!target.Adjacent(user)) + to_chat(user, "The multitool is out of range! Please try again.") + return SURGERY_STEP_INCOMPLETE + var/new_gender = gender_list[gender_key] var/old_name = target.real_name target.real_name = new_name + target.species_subtype = new_subtype target.gender = new_gender user.visible_message( - "[user] edits [old_name]'s identity parameters with [tool]; [target.p_they()] [target.p_are()] now known as [new_name].", - "You alter [old_name]'s identity parameters with [tool]; [target.p_they()] [target.p_are()] now known as [new_name].", + "[user] edits [old_name]'s identity parameters with [tool], changing their appearance; [target.p_they()] [target.p_are()] now known as [new_name].", + "You alter [old_name]'s identity parameters with [tool], changing their appearance; [target.p_they()] [target.p_are()] now known as [new_name].", chat_message_type = MESSAGE_TYPE_COMBAT ) + + if(!isnull(target.dna)) + for(var/obj/item/organ/external/limb in target.bodyparts) // Update robotic limbs to match new sub species + limb.set_company(limb.model, target.dna.species.sprite_sheet_name) // Update the limbs to properly use their new sprite sheet. + target.dna.species.updatespeciessubtype(src) + target.regenerate_icons() + return SURGERY_STEP_CONTINUE From b0e1e77610fd014130b99d8a5786eb0ec1721a17 Mon Sep 17 00:00:00 2001 From: Spaghetti-Bit Date: Tue, 1 Oct 2024 06:09:05 -0600 Subject: [PATCH 02/22] More transparency / alpha --- .../living/carbon/human/human_update_icons.dm | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) 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 bbeecbd097d1a..4e55dd7059de5 100644 --- a/code/modules/mob/living/carbon/human/human_update_icons.dm +++ b/code/modules/mob/living/carbon/human/human_update_icons.dm @@ -1244,9 +1244,9 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) if(HAS_TRAIT(src, TRAIT_I_WANT_BRAINS)) wings_icon.ColorTone(COLORTONE_DEAD_EXT_ORGAN) wings_icon.SetIntensity(0.7) - if(istype(src.dna.species, /datum/species/slime) && species_subtype != "None") // Slimfies the wings + if(istype(src.dna.species, /datum/species/slime)) // Slimfies the wings wings_icon.GrayScale() - wings_icon.Blend("[skin_colour]DC", ICON_AND) //DC = 220 alpha. + wings_icon.Blend("[skin_colour]A0", ICON_AND) //DC = 160 alpha. var/mutable_appearance/wings = mutable_appearance(wings_icon, layer = -WING_LAYER) wings.pixel_x = body_accessory.pixel_x_offset wings.pixel_y = body_accessory.pixel_y_offset @@ -1292,7 +1292,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) if(tail_marking_icon && (body_accessory.name in tail_marking_style.tails_allowed)) accessory_s.Blend(tail_marking_icon, ICON_OVERLAY) - if(istype(src.dna.species, /datum/species/slime) && species_subtype != "None") // Slimfies the tail + if(istype(src.dna.species, /datum/species/slime)) // Slimfies the tail accessory_s.GrayScale() accessory_s.Blend("[skin_colour]A0", ICON_AND) //DC = 160 alpha. Less alpha here because the tail is generally stubborn... @@ -1334,6 +1334,11 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) tail_s.Blend(skin_colour, ICON_ADD) if(tail_marking_icon && !tail_marking_style.tails_allowed) tail_s.Blend(tail_marking_icon, ICON_OVERLAY) + + if(istype(src.dna.species, /datum/species/slime)) // Slimifies the tail + tail_s.GrayScale() + tail_s.Blend("[skin_colour]A0", ICON_AND) //DC = 160 alpha. + if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. var/icon/under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "blank") @@ -1373,11 +1378,15 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) var/icon/accessory_s = new/icon("icon" = body_accessory.get_animated_icon(), "icon_state" = body_accessory.get_animated_icon_state()) if(dna.species.bodyflags & HAS_SKIN_COLOR) accessory_s.Blend(skin_colour, body_accessory.blend_mode) + if(istype(src.dna.species, /datum/species/slime)) // Slimfies the wings + accessory_s.GrayScale() + accessory_s.Blend("[skin_colour]A0", ICON_AND) //DC = 160 alpha. if(tail_marking_icon && (body_accessory.name in tail_marking_style.tails_allowed)) accessory_s.Blend(tail_marking_icon, ICON_OVERLAY) if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. var/icon/under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "Vulpkanin_tail_delay") + if(body_accessory.allowed_species && (dna.species.name in body_accessory.allowed_species)) under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.name]_tail_delay") under.Insert(new/icon(accessory_s, dir=SOUTH), dir=SOUTH) @@ -1409,6 +1418,9 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) var/icon/tailw_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[tail]w_s") if(dna.species.bodyflags & HAS_SKIN_COLOR) tailw_s.Blend(skin_colour, ICON_ADD) + if(istype(src.dna.species, /datum/species/slime)) // Slimfies the wings + tailw_s.GrayScale() + tailw_s.Blend("[skin_colour]A0", ICON_AND) //DC = 160 alpha. if(tail_marking_icon && !tail_marking_style.tails_allowed) tailw_s.Blend(tail_marking_icon, ICON_OVERLAY) if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) From 5e5b6e31db05f21f9fc6f83d262c3e4d70dc2d78 Mon Sep 17 00:00:00 2001 From: Spaghetti-Bit Date: Tue, 1 Oct 2024 06:11:38 -0600 Subject: [PATCH 03/22] Vulp + Name override --- .../carbon/human/species/slimepeople.dm | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/code/modules/mob/living/carbon/human/species/slimepeople.dm b/code/modules/mob/living/carbon/human/species/slimepeople.dm index d371de7d04f80..50746f3beaa2b 100644 --- a/code/modules/mob/living/carbon/human/species/slimepeople.dm +++ b/code/modules/mob/living/carbon/human/species/slimepeople.dm @@ -36,7 +36,7 @@ species_traits = list(LIPS, NO_CLONESCAN, EXOTIC_COLOR) inherent_traits = list(TRAIT_WATERBREATH, TRAIT_NO_BONES) clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_SKIN_COLOR | NO_EYES | HAS_SPECIES_SUBTYPE + bodyflags = HAS_SKIN_COLOR | NO_EYES | HAS_SPECIES_SUBTYPE | HAS_HEAD_ACCESSORY | HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED | HAS_BODY_ACCESSORY dietflags = DIET_CARN reagent_tag = PROCESS_ORG @@ -62,7 +62,8 @@ 2 = "Vox", 3 = "Unathi", 4 = "Tajaran", - 5 = "Nian" + 5 = "Nian", + 6 = "Vulpkanin" ) var/reagent_skin_coloring = FALSE @@ -95,44 +96,56 @@ var/new_icobase = 'icons/mob/human_races/r_slime.dmi' //Default slime person. if(H.species_subtype == species_subtype) // No update, no need to go further. return - bodyflags = initial(bodyflags) + //bodyflags = initial(bodyflags) switch(H.species_subtype) + if("Vulpkanin") // Vulp + new_icobase = 'icons/mob/human_races/r_vulpkanin.dmi' + species_subtype = "Vulpkanin" + name = "Vulpkanin" + tail = "vulptail" + wing = null + //bodyflags |= (HAS_HEAD_ACCESSORY | HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED) + H.body_accessory = null if("Nian") // Nian new_icobase = 'icons/mob/human_races/nian/r_moth.dmi' species_subtype = "Nian" + name = "Nian" tail = null wing = "plain" - bodyflags |= (HAS_HEAD_ACCESSORY | HAS_WING) + //bodyflags |= (HAS_HEAD_ACCESSORY | HAS_WING) H.body_accessory = null if("Tajaran") // Tajaran new_icobase = 'icons/mob/human_races/r_tajaran.dmi' species_subtype = "Tajaran" + name = "Tajaran" tail = "tajtail" wing = null - bodyflags |= (HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED) + //bodyflags |= (HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED) H.body_accessory = null if("Unathi") // Unathi new_icobase = 'icons/mob/human_races/r_lizard.dmi' species_subtype = "Unathi" tail = "sogtail" wing = null - bodyflags |= (HAS_HEAD_ACCESSORY | HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED) + //bodyflags |= (HAS_HEAD_ACCESSORY | HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED) H.body_accessory = null if("Vox") // Vox :) new_icobase = 'icons/mob/human_races/vox/r_voxgry.dmi' + name = "Vox" tail = "voxtail_gry" wing = null species_subtype = "Vox" - bodyflags |= (HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED) + //bodyflags |= (HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED) H.body_accessory = null if("None") // Regular slime person // Reset new_icobase = initial(icobase) species_subtype = "None" + name = "Slime People" tail = null eyes = initial(eyes) wing = null - bodyflags = initial(bodyflags) + //bodyflags = initial(bodyflags) H.body_accessory = null if(species_subtype != "None") From 4114b67cd514d2c8414ddc3938daed1a0a81056b Mon Sep 17 00:00:00 2001 From: Spaghetti-Bit Date: Tue, 1 Oct 2024 06:11:53 -0600 Subject: [PATCH 04/22] more transparency alpha stuff --- code/modules/mob/living/carbon/human/human_update_icons.dm | 3 +++ 1 file changed, 3 insertions(+) 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 4e55dd7059de5..81a1661607f24 100644 --- a/code/modules/mob/living/carbon/human/human_update_icons.dm +++ b/code/modules/mob/living/carbon/human/human_update_icons.dm @@ -1257,6 +1257,9 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) if(HAS_TRAIT(src, TRAIT_I_WANT_BRAINS)) under_wing_icon.ColorTone(COLORTONE_DEAD_EXT_ORGAN) under_wing_icon.SetIntensity(0.7) + if(istype(src.dna.species, /datum/species/slime)) // Slimfies the wings + under_wing_icon.GrayScale() + under_wing_icon.Blend("[skin_colour]A0", ICON_AND) //DC = 160 alpha. var/mutable_appearance/under_wing = mutable_appearance(under_wing_icon, layer = -WING_UNDERLIMBS_LAYER) under_wing.pixel_x = body_accessory.pixel_x_offset under_wing.pixel_y = body_accessory.pixel_y_offset From d30735d3f187a89d5a13eb633f6e0b6abb85f4f3 Mon Sep 17 00:00:00 2001 From: Spaghetti-Bit Date: Thu, 3 Oct 2024 01:15:56 -0600 Subject: [PATCH 05/22] Reworks species subtype for slimepeople --- .../carbon/human/species/slimepeople.dm | 90 ++++++------------- 1 file changed, 29 insertions(+), 61 deletions(-) diff --git a/code/modules/mob/living/carbon/human/species/slimepeople.dm b/code/modules/mob/living/carbon/human/species/slimepeople.dm index 50746f3beaa2b..30c5e4c16e130 100644 --- a/code/modules/mob/living/carbon/human/species/slimepeople.dm +++ b/code/modules/mob/living/carbon/human/species/slimepeople.dm @@ -63,7 +63,10 @@ 3 = "Unathi", 4 = "Tajaran", 5 = "Nian", - 6 = "Vulpkanin" + 6 = "Vulpkanin", + 7 = "Kidan", + 8 = "Grey", + 9 = "Drask" ) var/reagent_skin_coloring = FALSE @@ -96,72 +99,39 @@ var/new_icobase = 'icons/mob/human_races/r_slime.dmi' //Default slime person. if(H.species_subtype == species_subtype) // No update, no need to go further. return - //bodyflags = initial(bodyflags) - switch(H.species_subtype) - if("Vulpkanin") // Vulp - new_icobase = 'icons/mob/human_races/r_vulpkanin.dmi' - species_subtype = "Vulpkanin" - name = "Vulpkanin" - tail = "vulptail" - wing = null - //bodyflags |= (HAS_HEAD_ACCESSORY | HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED) - H.body_accessory = null - if("Nian") // Nian - new_icobase = 'icons/mob/human_races/nian/r_moth.dmi' - species_subtype = "Nian" - name = "Nian" - tail = null - wing = "plain" - //bodyflags |= (HAS_HEAD_ACCESSORY | HAS_WING) - H.body_accessory = null - if("Tajaran") // Tajaran - new_icobase = 'icons/mob/human_races/r_tajaran.dmi' - species_subtype = "Tajaran" - name = "Tajaran" - tail = "tajtail" - wing = null - //bodyflags |= (HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED) - H.body_accessory = null - if("Unathi") // Unathi - new_icobase = 'icons/mob/human_races/r_lizard.dmi' - species_subtype = "Unathi" - tail = "sogtail" - wing = null - //bodyflags |= (HAS_HEAD_ACCESSORY | HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED) - H.body_accessory = null - if("Vox") // Vox :) - new_icobase = 'icons/mob/human_races/vox/r_voxgry.dmi' - name = "Vox" - tail = "voxtail_gry" - wing = null - species_subtype = "Vox" - //bodyflags |= (HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED) - H.body_accessory = null - if("None") // Regular slime person - // Reset - new_icobase = initial(icobase) - species_subtype = "None" - name = "Slime People" - tail = null - eyes = initial(eyes) - wing = null - //bodyflags = initial(bodyflags) - H.body_accessory = null - - if(species_subtype != "None") + species_subtype = H.species_subtype // Update our species subtype to match the Mob's subtype. + if(species_subtype != "None") // Update our species display and reference name to match the subtype. Used for species specific clothing and accessories. sprite_sheet_name = species_subtype else - sprite_sheet_name = name + sprite_sheet_name = name // Resets sprite sheet back to slime people. + var/datum/species/s = GLOB.all_species[species_subtype] if(isnull(s)) - s = src + s = GLOB.all_species[name] // Reset species fully to slime person again. + + // Copy over new species variables to our current species. + new_icobase = s.icobase + tail = s.tail + wing = s.wing + eyes = s.eyes + scream_verb = s.scream_verb + male_scream_sound = s.male_scream_sound + female_scream_sound = s.female_scream_sound + default_headacc = s.default_headacc + default_bodyacc = s.default_bodyacc + male_cough_sounds = s.male_cough_sounds + female_cough_sounds = s.female_cough_sounds + male_sneeze_sound = s.male_sneeze_sound + female_sneeze_sound = s.female_sneeze_sound + + H.body_accessory = default_bodyacc + H.tail = tail + H.wing = wing for(var/obj/item/organ/external/limb in H.bodyparts) // Update robotic limbs to match new sub species ico base in the case they have robotic limbs limb.icobase = s.icobase // update their icobase for when we apply the slimfy effect limb.set_company(limb.model, sprite_sheet_name) // Update misc parts that are stored as reference in species and used on the mob. Also resets stylings to none to prevent anything wacky... - H.tail = tail - H.wing = wing var/obj/item/organ/external/head/head = H.get_organ("head") head.h_style = "Bald" @@ -172,9 +142,6 @@ H.m_colours = DEFAULT_MARKING_COLOURS //Defaults colour to #00000 for all markings. H.change_icobase(new_icobase, owner_sensitive) //Update the icobase of all our organs, but make sure we don't mess with frankenstein limbs in doing so. -/datum/species/slime/proc/slimify(mob/living/carbon/human/H) // WIP -- MutableAppearance, greyscale then overlay slime color over. - return - /datum/species/slime/proc/blend(mob/living/carbon/human/H) var/new_color = BlendRGB(H.skin_colour, "#acacac", 0.5) // Blends this to make it work better if(H.dna.species.blood_color != new_color) // Put here, so if it's a roundstart, dyed, or CMA'd slime, their blood changes to match skin @@ -314,6 +281,7 @@ H.regenerate_icons() else to_chat(H, "You need to hold still in order to shift your form!") + #undef SLIMEPERSON_COLOR_SHIFT_TRIGGER #undef SLIMEPERSON_ICON_UPDATE_PERIOD #undef SLIMEPERSON_BLOOD_SCALING_FACTOR From 82659f6876432772636234f07e71dfb28cf9efc6 Mon Sep 17 00:00:00 2001 From: Spaghetti-Bit Date: Sat, 12 Oct 2024 14:25:05 -0600 Subject: [PATCH 06/22] Iteration 3... --- code/datums/diseases/advance/symptoms/hair.dm | 6 +-- code/game/dna/dna2_helpers.dm | 2 +- .../miniantags/tourist/tourist_arrivals.dm | 4 +- code/game/objects/structures/dresser.dm | 6 +-- code/modules/awaymissions/mob_spawn.dm | 4 +- code/modules/client/preference/character.dm | 33 +++++++++++--- code/modules/clothing/clothing.dm | 4 +- code/modules/customitems/item_defines.dm | 2 +- .../mob/living/carbon/human/appearance.dm | 18 ++++---- .../living/carbon/human/body_accessories.dm | 2 +- .../living/carbon/human/human_update_icons.dm | 45 +++++++++++-------- .../living/carbon/human/species/machine.dm | 2 +- .../carbon/human/species/slimepeople.dm | 16 ++++--- .../chemistry/reagents/misc_reagents.dm | 12 ++--- code/modules/response_team/ert.dm | 4 +- code/modules/surgery/organs/organ_icon.dm | 8 ++-- .../tgui/modules/appearance_changer.dm | 10 ++++- 17 files changed, 111 insertions(+), 67 deletions(-) diff --git a/code/datums/diseases/advance/symptoms/hair.dm b/code/datums/diseases/advance/symptoms/hair.dm index 60419bd5b25f3..b1f56f177bece 100644 --- a/code/datums/diseases/advance/symptoms/hair.dm +++ b/code/datums/diseases/advance/symptoms/hair.dm @@ -37,13 +37,13 @@ BONUS switch(A.stage) if(1, 2, 3) to_chat(H, "Your scalp itches.") - head_organ.h_style = random_hair_style(H.gender, head_organ.dna.species.name) + head_organ.h_style = random_hair_style(H.gender, head_organ.dna.species.sprite_sheet_name) else to_chat(H, "Hair bursts forth from your scalp!") var/datum/sprite_accessory/tmp_hair_style = GLOB.hair_styles_full_list["Very Long Hair"] - if(head_organ.dna.species.name in tmp_hair_style.species_allowed) //If 'Very Long Hair' is a style the person's species can have, give it to them. + if(head_organ.dna.species.sprite_sheet_name in tmp_hair_style.species_allowed) //If 'Very Long Hair' is a style the person's species can have, give it to them. head_organ.h_style = "Very Long Hair" else //Otherwise, give them a random hair style. - head_organ.h_style = random_hair_style(H.gender, head_organ.dna.species.name) + head_organ.h_style = random_hair_style(H.gender, head_organ.dna.species.sprite_sheet_name) H.update_hair() diff --git a/code/game/dna/dna2_helpers.dm b/code/game/dna/dna2_helpers.dm index c387b34e5c33d..546ade34ebaa7 100644 --- a/code/game/dna/dna2_helpers.dm +++ b/code/game/dna/dna2_helpers.dm @@ -240,7 +240,7 @@ var/list/available = list() for(var/head_accessory in GLOB.head_accessory_styles_list) var/datum/sprite_accessory/S = GLOB.head_accessory_styles_list[head_accessory] - if(!(head_organ.dna.species.name in S.species_allowed)) //If the user's head is not of a species the head accessory style allows, skip it. Otherwise, add it to the list. + if(!(head_organ.dna.species.sprite_sheet_name in S.species_allowed)) //If the user's head is not of a species the head accessory style allows, skip it. Otherwise, add it to the list. continue available += head_accessory var/list/sorted = sortTim(available, GLOBAL_PROC_REF(cmp_text_asc)) diff --git a/code/game/gamemodes/miniantags/tourist/tourist_arrivals.dm b/code/game/gamemodes/miniantags/tourist/tourist_arrivals.dm index 545b67f3a9db3..ca69243d9da6d 100644 --- a/code/game/gamemodes/miniantags/tourist/tourist_arrivals.dm +++ b/code/game/gamemodes/miniantags/tourist/tourist_arrivals.dm @@ -118,8 +118,8 @@ head_organ.sec_hair_colour = hair_c M.change_eye_color(eye_c) M.s_tone = skin_tone - head_organ.h_style = random_hair_style(M.gender, head_organ.dna.species.name) - head_organ.f_style = random_facial_hair_style(M.gender, head_organ.dna.species.name) + head_organ.h_style = random_hair_style(M.gender, head_organ.dna.species.sprite_sheet_name) + head_organ.f_style = random_facial_hair_style(M.gender, head_organ.dna.species.sprite_sheet_name) M.regenerate_icons() M.update_body() diff --git a/code/game/objects/structures/dresser.dm b/code/game/objects/structures/dresser.dm index 5bc31b1d05020..e93f865cc7ed7 100644 --- a/code/game/objects/structures/dresser.dm +++ b/code/game/objects/structures/dresser.dm @@ -21,7 +21,7 @@ var/list/valid_underwear = list() for(var/underwear in GLOB.underwear_list) var/datum/sprite_accessory/S = GLOB.underwear_list[underwear] - if(!(H.dna.species.name in S.species_allowed)) + if(!(H.dna.species.sprite_sheet_name in S.species_allowed)) continue valid_underwear[underwear] = GLOB.underwear_list[underwear] var/new_underwear = tgui_input_list(user, "Choose your underwear:", "Changing", valid_underwear) @@ -32,7 +32,7 @@ var/list/valid_undershirts = list() for(var/undershirt in GLOB.undershirt_list) var/datum/sprite_accessory/S = GLOB.undershirt_list[undershirt] - if(!(H.dna.species.name in S.species_allowed)) + if(!(H.dna.species.sprite_sheet_name in S.species_allowed)) continue valid_undershirts[undershirt] = GLOB.undershirt_list[undershirt] var/new_undershirt = tgui_input_list(user, "Choose your undershirt:", "Changing", valid_undershirts) @@ -43,7 +43,7 @@ var/list/valid_sockstyles = list() for(var/sockstyle in GLOB.socks_list) var/datum/sprite_accessory/S = GLOB.socks_list[sockstyle] - if(!(H.dna.species.name in S.species_allowed)) + if(!(H.dna.species.sprite_sheet_name in S.species_allowed)) continue valid_sockstyles[sockstyle] = GLOB.socks_list[sockstyle] var/new_socks = tgui_input_list(user, "Choose your socks:", "Changing", valid_sockstyles) diff --git a/code/modules/awaymissions/mob_spawn.dm b/code/modules/awaymissions/mob_spawn.dm index 1741cdb69f174..fd214d485ff22 100644 --- a/code/modules/awaymissions/mob_spawn.dm +++ b/code/modules/awaymissions/mob_spawn.dm @@ -250,12 +250,12 @@ if(hair_style) D.h_style = hair_style else - D.h_style = random_hair_style(gender, D.dna.species.name) + D.h_style = random_hair_style(gender, D.dna.species.sprite_sheet_name) D.hair_colour = rand_hex_color() if(facial_hair_style) D.f_style = facial_hair_style else - D.f_style = random_facial_hair_style(gender, D.dna.species.name) + D.f_style = random_facial_hair_style(gender, D.dna.species.sprite_sheet_name) D.facial_colour = rand_hex_color() if(skin_tone) H.s_tone = skin_tone diff --git a/code/modules/client/preference/character.dm b/code/modules/client/preference/character.dm index db41e06286928..4d94b7c7914f0 100644 --- a/code/modules/client/preference/character.dm +++ b/code/modules/client/preference/character.dm @@ -831,19 +831,42 @@ //Icon-based species colour. var/coloured_tail if(current_species) - if(current_species.bodyflags & HAS_ICON_SKIN_TONE) //Handling species-specific icon-based skin tones by flagged race. - var/mob/living/carbon/human/H = new - H.dna.species = current_species + if(species_subtype != "None" && current_species.bodyflags & HAS_SPECIES_SUBTYPE && istype(current_species, /datum/species/slime)) + var/datum/species/subtype_species = GLOB.all_species[species_subtype] + if(subtype_species) + current_species.sprite_sheet_name = subtype_species.sprite_sheet_name + current_species.icobase = subtype_species.icobase + current_species.tail = subtype_species.tail + current_species.wing = subtype_species.wing + current_species.eyes = subtype_species.eyes + current_species.scream_verb = subtype_species.scream_verb + current_species.male_scream_sound = subtype_species.male_scream_sound + current_species.female_scream_sound = subtype_species.female_scream_sound + current_species.default_headacc = subtype_species.default_headacc + current_species.default_bodyacc = subtype_species.default_bodyacc + current_species.male_cough_sounds = subtype_species.male_cough_sounds + current_species.female_cough_sounds = subtype_species.female_cough_sounds + current_species.male_sneeze_sound = subtype_species.male_sneeze_sound + current_species.female_sneeze_sound = subtype_species.female_sneeze_sound + current_species.bodyflags = subtype_species.bodyflags + current_species.bodyflags |= HAS_SKIN_COLOR | NO_EYES | HAS_SPECIES_SUBTYPE + else + current_species = initial(current_species) + var/mob/living/carbon/human/H = new + H.dna.species = current_species + if(current_species.bodyflags & HAS_SPECIES_SUBTYPE) + H.dna.species.updatespeciessubtype(H) + icobase = H.dna.species.icobase + else if(current_species.bodyflags & HAS_ICON_SKIN_TONE) //Handling species-specific icon-based skin tones by flagged race. H.s_tone = s_tone H.dna.species.updatespeciescolor(H, 0) //The mob's species wasn't set, so it's almost certainly different than the character's species at the moment. Thus, we need to be owner-insensitive. var/obj/item/organ/external/chest/C = H.get_organ("chest") icobase = C.icobase ? C.icobase : C.dna.species.icobase if(H.dna.species.bodyflags & HAS_TAIL) coloured_tail = H.tail ? H.tail : H.dna.species.tail - - qdel(H) else icobase = current_species.icobase + qdel(H) else icobase = 'icons/mob/human_races/r_human.dmi' diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index 9733856a3c3db..7b5197a67dd25 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -107,10 +107,10 @@ if(H.dna.species) if(exclusive) - if(!(H.dna.species.name in species_restricted)) + if(!(H.dna.species.sprite_sheet_name in species_restricted)) wearable = TRUE else - if(H.dna.species.name in species_restricted) + if(H.dna.species.sprite_sheet_name in species_restricted) wearable = TRUE if(!wearable) diff --git a/code/modules/customitems/item_defines.dm b/code/modules/customitems/item_defines.dm index 55605f6b23028..98ac1977579c8 100644 --- a/code/modules/customitems/item_defines.dm +++ b/code/modules/customitems/item_defines.dm @@ -58,7 +58,7 @@ return var/datum/sprite_accessory/body_markings/tattoo/temp_tatt = GLOB.marking_styles_list[tattoo_icon] - if(!(target.dna.species.name in temp_tatt.species_allowed)) + if(!(target.dna.species.sprite_sheet_name in temp_tatt.species_allowed)) to_chat(user, "You can't think of a way to make the [tattoo_name] design work on [target == user ? "your" : "[target]'s"] body type.") return diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm index 18cbb6991cbbc..0dc9de25b3378 100644 --- a/code/modules/mob/living/carbon/human/appearance.dm +++ b/code/modules/mob/living/carbon/human/appearance.dm @@ -389,14 +389,14 @@ continue if(H.dna.species.bodyflags & ALL_RPARTS) //If the user is a species who can have a robotic head... var/datum/robolimb/robohead = GLOB.all_robolimbs[H.model] - if((H.dna.species.name in S.species_allowed) && robohead.is_monitor && ((S.models_allowed && (robohead.company in S.models_allowed)) || !S.models_allowed)) //If this is a hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list. + if((H.dna.species.sprite_sheet_name in S.species_allowed) && robohead.is_monitor && ((S.models_allowed && (robohead.company in S.models_allowed)) || !S.models_allowed)) //If this is a hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list. valid_hairstyles += hairstyle //Give them their hairstyles if they do. else if(!robohead.is_monitor && ("Human" in S.species_allowed)) /*If the hairstyle is not native to the user's species and they're using a head with an ipc-style screen, don't let them access it. But if the user has a robotic humanoid head and the hairstyle can fit humans, let them use it as a wig. */ valid_hairstyles += hairstyle else //If the user is not a species who can have robotic heads, use the default handling. - if(H.dna.species.name in S.species_allowed) //If the user's head is of a species the hairstyle allows, add it to the list. + if(H.dna.species.sprite_sheet_name in S.species_allowed) //If the user's head is of a species the hairstyle allows, add it to the list. valid_hairstyles += hairstyle return sortTim(valid_hairstyles, GLOBAL_PROC_REF(cmp_text_asc)) @@ -415,15 +415,15 @@ continue if(H.dna.species.bodyflags & ALL_RPARTS) //If the user is a species who can have a robotic head... var/datum/robolimb/robohead = GLOB.all_robolimbs[H.model] - if(H.dna.species.name in S.species_allowed) //If this is a facial hair style native to the user's species... - if((H.dna.species.name in S.species_allowed) && robohead.is_monitor && ((S.models_allowed && (robohead.company in S.models_allowed)) || !S.models_allowed)) //If this is a facial hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list. + if(H.dna.species.sprite_sheet_name in S.species_allowed) //If this is a facial hair style native to the user's species... + if((H.dna.species.sprite_sheet_name in S.species_allowed) && robohead.is_monitor && ((S.models_allowed && (robohead.company in S.models_allowed)) || !S.models_allowed)) //If this is a facial hair style native to the user's species, check to see if they have a head with an ipc-style screen and that the head's company is in the screen style's allowed models list. valid_facial_hairstyles += facialhairstyle //Give them their facial hairstyles if they do. else if(!robohead.is_monitor && ("Human" in S.species_allowed)) /*If the facial hairstyle is not native to the user's species and they're using a head with an ipc-style screen, don't let them access it. But if the user has a robotic humanoid head and the facial hairstyle can fit humans, let them use it as a wig. */ valid_facial_hairstyles += facialhairstyle else //If the user is not a species who can have robotic heads, use the default handling. - if(H.dna.species.name in S.species_allowed) //If the user's head is of a species the facial hair style allows, add it to the list. + if(H.dna.species.sprite_sheet_name in S.species_allowed) //If the user's head is of a species the facial hair style allows, add it to the list. valid_facial_hairstyles += facialhairstyle return sortTim(valid_facial_hairstyles, GLOBAL_PROC_REF(cmp_text_asc)) @@ -437,7 +437,7 @@ for(var/head_accessory in GLOB.head_accessory_styles_list) var/datum/sprite_accessory/S = GLOB.head_accessory_styles_list[head_accessory] - if(!(H.dna.species.name in S.species_allowed)) //If the user's head is not of a species the head accessory style allows, skip it. Otherwise, add it to the list. + if(!(H.dna.species.sprite_sheet_name in S.species_allowed)) //If the user's head is not of a species the head accessory style allows, skip it. Otherwise, add it to the list. continue valid_head_accessories += head_accessory @@ -456,7 +456,7 @@ continue if(S.marking_location != location) //If the marking isn't for the location we desire, skip. continue - if(!(dna.species.name in S.species_allowed)) //If the user is not of a species the marking style allows, skip it. Otherwise, add it to the list. + if(!(dna.species.sprite_sheet_name in S.species_allowed)) //If the user is not of a species the marking style allows, skip it. Otherwise, add it to the list. continue if(location == "tail") if(!body_accessory) @@ -490,7 +490,7 @@ else if(check_rights(R_ADMIN, FALSE, src)) valid_body_accessories = GLOB.body_accessory_by_name.Copy() break - else if(dna.species.name in A.allowed_species) //If the user is not of a species the body accessory style allows, skip it. Otherwise, add it to the list. + else if(dna.species.sprite_sheet_name in A.allowed_species) //If the user is not of a species the body accessory style allows, skip it. Otherwise, add it to the list. valid_body_accessories += B if(dna.species.optional_body_accessory) valid_body_accessories += "None" @@ -505,7 +505,7 @@ valid_alt_heads["None"] = GLOB.alt_heads_list["None"] //The only null entry should be the "None" option, and there should always be a "None" option. for(var/alternate_head in GLOB.alt_heads_list) var/datum/sprite_accessory/alt_heads/head = GLOB.alt_heads_list[alternate_head] - if(!(H.dna.species.name in head.species_allowed)) + if(!(H.dna.species.sprite_sheet_name in head.species_allowed)) continue valid_alt_heads += alternate_head diff --git a/code/modules/mob/living/carbon/human/body_accessories.dm b/code/modules/mob/living/carbon/human/body_accessories.dm index 364626c0dffbd..ca3adfbdcca62 100644 --- a/code/modules/mob/living/carbon/human/body_accessories.dm +++ b/code/modules/mob/living/carbon/human/body_accessories.dm @@ -50,7 +50,7 @@ GLOBAL_LIST_EMPTY(body_accessory_by_species) var/has_behind = FALSE /datum/body_accessory/proc/try_restrictions(mob/living/carbon/human/H) - return (H.dna.species.name in allowed_species) + return (H.dna.species.sprite_sheet_name in allowed_species) /datum/body_accessory/proc/get_animated_icon() //return animated if it has it, return static if it does not. if(animated_icon) 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 81a1661607f24..2d05c0c748019 100644 --- a/code/modules/mob/living/carbon/human/human_update_icons.dm +++ b/code/modules/mob/living/carbon/human/human_update_icons.dm @@ -303,20 +303,26 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) if(chest_organ && m_styles["body"]) var/body_marking = m_styles["body"] var/datum/sprite_accessory/body_marking_style = GLOB.marking_styles_list[body_marking] - if(body_marking_style && body_marking_style.species_allowed && (dna.species.name in body_marking_style.species_allowed)) + if(body_marking_style && body_marking_style.species_allowed && (dna.species.sprite_sheet_name in body_marking_style.species_allowed)) var/icon/b_marking_s = icon("icon" = body_marking_style.icon, "icon_state" = "[body_marking_style.icon_state]_s") if(body_marking_style.do_colouration) b_marking_s.Blend(m_colours["body"], ICON_ADD) + if(istype(src.dna.species, /datum/species/slime)) + b_marking_s.GrayScale() + b_marking_s.Blend("[skin_colour]A0", ICON_AND) markings_standing.Blend(b_marking_s, ICON_OVERLAY) //Head markings. var/obj/item/organ/external/head/head_organ = get_organ("head") if(istype(head_organ) && m_styles["head"]) //If the head is destroyed, forget the head markings. This prevents floating optical markings on decapitated IPCs, for example. var/head_marking = m_styles["head"] var/datum/sprite_accessory/head_marking_style = GLOB.marking_styles_list[head_marking] - if(head_marking_style && head_marking_style.species_allowed && (head_organ.dna.species.name in head_marking_style.species_allowed)) + if(head_marking_style && head_marking_style.species_allowed && (head_organ.dna.species.sprite_sheet_name in head_marking_style.species_allowed)) var/icon/h_marking_s = icon("icon" = head_marking_style.icon, "icon_state" = "[head_marking_style.icon_state]_s") if(head_marking_style.do_colouration) h_marking_s.Blend(m_colours["head"], ICON_ADD) + if(istype(src.dna.species, /datum/species/slime)) + h_marking_s.GrayScale() + h_marking_s.Blend("[skin_colour]A0", ICON_AND) markings_standing.Blend(h_marking_s, ICON_OVERLAY) overlays_standing[MARKINGS_LAYER] = mutable_appearance(markings_standing, layer = -MARKINGS_LAYER) @@ -341,10 +347,13 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) if(head_organ.ha_style && (head_organ.dna.species.bodyflags & HAS_HEAD_ACCESSORY)) var/datum/sprite_accessory/head_accessory/head_accessory_style = GLOB.head_accessory_styles_list[head_organ.ha_style] if(head_accessory_style && head_accessory_style.species_allowed) - if(head_organ.dna.species.name in head_accessory_style.species_allowed) + if(head_organ.dna.species.sprite_sheet_name in head_accessory_style.species_allowed) var/icon/head_accessory_s = new/icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s") if(head_accessory_style.do_colouration) head_accessory_s.Blend(head_organ.headacc_colour, ICON_ADD) + if(istype(src.dna.species, /datum/species/slime)) // Slimifies head acc + head_accessory_s.GrayScale() + head_accessory_s.Blend("[skin_colour]A0", ICON_AND) //DC = 160 alpha. if(HAS_TRAIT(src, TRAIT_I_WANT_BRAINS)) head_accessory_s.ColorTone(COLORTONE_DEAD_EXT_ORGAN) head_accessory_s.SetIntensity(0.7) @@ -376,7 +385,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) MA.layer = -HAIR_LAYER if(O.h_style && !(head?.flags & BLOCKHEADHAIR && !ismachineperson(src))) var/datum/sprite_accessory/hair/hair = GLOB.hair_styles_full_list[O.h_style] - if(hair?.species_allowed && ((O.dna.species.name in hair.species_allowed) || (O.dna.species.bodyflags & ALL_RPARTS))) + if(hair?.species_allowed && ((O.dna.species.sprite_sheet_name in hair.species_allowed) || (O.dna.species.bodyflags & ALL_RPARTS))) // Base hair var/icon/hair_icon = new /icon(hair.icon, "[hair.icon_state]_s") if(HAS_TRAIT(src, TRAIT_I_WANT_BRAINS)) @@ -425,8 +434,8 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) return var/species_name = "" - if(dna.species.name in list("Drask", "Grey", "Vox", "Kidan")) - species_name = "_[lowertext(dna.species.name)]" + if(dna.species.sprite_sheet_name in list("Drask", "Grey", "Vox", "Kidan")) + species_name = "_[lowertext(dna.species.sprite_sheet_name)]" var/icon/hands_mask = icon('icons/mob/body_accessory.dmi', "accessory_none_s") //Needs a blank icon, not actually related to markings at all @@ -468,7 +477,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) if(head_organ.f_style) var/datum/sprite_accessory/facial_hair/facial_hair_style = GLOB.facial_hair_styles_list[head_organ.f_style] if(facial_hair_style && facial_hair_style.species_allowed) - if((head_organ.dna.species.name in facial_hair_style.species_allowed) || (head_organ.dna.species.bodyflags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics... + if((head_organ.dna.species.sprite_sheet_name in facial_hair_style.species_allowed) || (head_organ.dna.species.bodyflags & ALL_RPARTS)) //If the head's species is in the list of allowed species for the hairstyle, or the head's species is one flagged to have bodies comprised wholly of cybernetics... var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") if(istype(head_organ.dna.species, /datum/species/slime)) // I am el worstos facial_s.Blend("[skin_colour]A0", ICON_AND) @@ -1244,7 +1253,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) if(HAS_TRAIT(src, TRAIT_I_WANT_BRAINS)) wings_icon.ColorTone(COLORTONE_DEAD_EXT_ORGAN) wings_icon.SetIntensity(0.7) - if(istype(src.dna.species, /datum/species/slime)) // Slimfies the wings + if(istype(src.dna.species, /datum/species/slime)) // Slimifies the wings wings_icon.GrayScale() wings_icon.Blend("[skin_colour]A0", ICON_AND) //DC = 160 alpha. var/mutable_appearance/wings = mutable_appearance(wings_icon, layer = -WING_LAYER) @@ -1257,7 +1266,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) if(HAS_TRAIT(src, TRAIT_I_WANT_BRAINS)) under_wing_icon.ColorTone(COLORTONE_DEAD_EXT_ORGAN) under_wing_icon.SetIntensity(0.7) - if(istype(src.dna.species, /datum/species/slime)) // Slimfies the wings + if(istype(src.dna.species, /datum/species/slime)) // Slimifies the wings under_wing_icon.GrayScale() under_wing_icon.Blend("[skin_colour]A0", ICON_AND) //DC = 160 alpha. var/mutable_appearance/under_wing = mutable_appearance(under_wing_icon, layer = -WING_UNDERLIMBS_LAYER) @@ -1295,7 +1304,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) if(tail_marking_icon && (body_accessory.name in tail_marking_style.tails_allowed)) accessory_s.Blend(tail_marking_icon, ICON_OVERLAY) - if(istype(src.dna.species, /datum/species/slime)) // Slimfies the tail + if(istype(src.dna.species, /datum/species/slime)) // Slimifies the body acc accessory_s.GrayScale() accessory_s.Blend("[skin_colour]A0", ICON_AND) //DC = 160 alpha. Less alpha here because the tail is generally stubborn... @@ -1381,7 +1390,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) var/icon/accessory_s = new/icon("icon" = body_accessory.get_animated_icon(), "icon_state" = body_accessory.get_animated_icon_state()) if(dna.species.bodyflags & HAS_SKIN_COLOR) accessory_s.Blend(skin_colour, body_accessory.blend_mode) - if(istype(src.dna.species, /datum/species/slime)) // Slimfies the wings + if(istype(src.dna.species, /datum/species/slime)) // Slimifies the wings accessory_s.GrayScale() accessory_s.Blend("[skin_colour]A0", ICON_AND) //DC = 160 alpha. if(tail_marking_icon && (body_accessory.name in tail_marking_style.tails_allowed)) @@ -1390,8 +1399,8 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. var/icon/under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "Vulpkanin_tail_delay") - if(body_accessory.allowed_species && (dna.species.name in body_accessory.allowed_species)) - under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.name]_tail_delay") + if(body_accessory.allowed_species && (dna.species.sprite_sheet_name in body_accessory.allowed_species)) + under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.sprite_sheet_name]_tail_delay") under.Insert(new/icon(accessory_s, dir=SOUTH), dir=SOUTH) under.Insert(new/icon(accessory_s, dir=EAST), dir=EAST) under.Insert(new/icon(accessory_s, dir=WEST), dir=WEST) @@ -1403,8 +1412,8 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) // Creates a blank icon, and copies accessory_s' north direction sprite into it before passing that to the tail layer that overlays uniforms and such. var/icon/over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "Vulpkanin_tail_delay") - if(body_accessory.allowed_species && (dna.species.name in body_accessory.allowed_species)) // If the user's species is in the list of allowed species for the currently selected body accessory, use the appropriate animation timing blank - over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.name]_tail_delay") + if(body_accessory.allowed_species && (dna.species.sprite_sheet_name in body_accessory.allowed_species)) // If the user's species is in the list of allowed species for the currently selected body accessory, use the appropriate animation timing blank + over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.sprite_sheet_name]_tail_delay") over.Insert(new/icon(accessory_s, dir=NORTH), dir=NORTH) var/mutable_appearance/tail = mutable_appearance(over, layer = -TAIL_LAYER) @@ -1421,14 +1430,14 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) var/icon/tailw_s = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[tail]w_s") if(dna.species.bodyflags & HAS_SKIN_COLOR) tailw_s.Blend(skin_colour, ICON_ADD) - if(istype(src.dna.species, /datum/species/slime)) // Slimfies the wings + if(istype(src.dna.species, /datum/species/slime)) // Slimifies the tail tailw_s.GrayScale() tailw_s.Blend("[skin_colour]A0", ICON_AND) //DC = 160 alpha. if(tail_marking_icon && !tail_marking_style.tails_allowed) tailw_s.Blend(tail_marking_icon, ICON_OVERLAY) if((!body_accessory || istype(body_accessory, /datum/body_accessory/tail)) && dna.species.bodyflags & TAIL_OVERLAPPED) // If the player has a species whose tail is overlapped by limbs... (having a non-tail body accessory like the snake body will override this) // Gives the underlimbs layer SEW direction icons since it's overlayed by limbs and just about everything else anyway. - var/icon/under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.name]_tail_delay") + var/icon/under = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.sprite_sheet_name]_tail_delay") under.Insert(new/icon(tailw_s, dir=SOUTH), dir=SOUTH) under.Insert(new/icon(tailw_s, dir=EAST), dir=EAST) under.Insert(new/icon(tailw_s, dir=WEST), dir=WEST) @@ -1436,7 +1445,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) overlays_standing[TAIL_UNDERLIMBS_LAYER] = mutable_appearance(under, layer = -TAIL_UNDERLIMBS_LAYER) // Creates a blank icon, and copies accessory_s' north direction sprite into it before passing that to the tail layer that overlays uniforms and such. - var/icon/over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.name]_tail_delay") + var/icon/over = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[dna.species.sprite_sheet_name]_tail_delay") over.Insert(new/icon(tailw_s, dir=NORTH), dir=NORTH) overlays_standing[TAIL_LAYER] = mutable_appearance(over, layer = -TAIL_LAYER) diff --git a/code/modules/mob/living/carbon/human/species/machine.dm b/code/modules/mob/living/carbon/human/species/machine.dm index 2f810e41d119a..1b2ed806f0b7b 100644 --- a/code/modules/mob/living/carbon/human/species/machine.dm +++ b/code/modules/mob/living/carbon/human/species/machine.dm @@ -225,7 +225,7 @@ var/list/hair = list() for(var/i in GLOB.hair_styles_public_list) var/datum/sprite_accessory/hair/tmp_hair = GLOB.hair_styles_public_list[i] - if((head_organ.dna.species.name in tmp_hair.species_allowed) && (robohead.company in tmp_hair.models_allowed)) //Populate the list of available monitor styles only with styles that the monitor-head is allowed to use. + if((head_organ.dna.species.sprite_sheet_name in tmp_hair.species_allowed) && (robohead.company in tmp_hair.models_allowed)) //Populate the list of available monitor styles only with styles that the monitor-head is allowed to use. hair += i diff --git a/code/modules/mob/living/carbon/human/species/slimepeople.dm b/code/modules/mob/living/carbon/human/species/slimepeople.dm index 30c5e4c16e130..0322b2fde14f1 100644 --- a/code/modules/mob/living/carbon/human/species/slimepeople.dm +++ b/code/modules/mob/living/carbon/human/species/slimepeople.dm @@ -36,7 +36,7 @@ species_traits = list(LIPS, NO_CLONESCAN, EXOTIC_COLOR) inherent_traits = list(TRAIT_WATERBREATH, TRAIT_NO_BONES) clothing_flags = HAS_UNDERWEAR | HAS_UNDERSHIRT | HAS_SOCKS - bodyflags = HAS_SKIN_COLOR | NO_EYES | HAS_SPECIES_SUBTYPE | HAS_HEAD_ACCESSORY | HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED | HAS_BODY_ACCESSORY + bodyflags = HAS_SKIN_COLOR | NO_EYES | HAS_SPECIES_SUBTYPE dietflags = DIET_CARN reagent_tag = PROCESS_ORG @@ -70,6 +70,7 @@ ) var/reagent_skin_coloring = FALSE + var/static_bodyflags = HAS_SKIN_COLOR | NO_EYES | HAS_SPECIES_SUBTYPE /datum/species/slime/on_species_gain(mob/living/carbon/human/H) ..() @@ -100,10 +101,6 @@ if(H.species_subtype == species_subtype) // No update, no need to go further. return species_subtype = H.species_subtype // Update our species subtype to match the Mob's subtype. - if(species_subtype != "None") // Update our species display and reference name to match the subtype. Used for species specific clothing and accessories. - sprite_sheet_name = species_subtype - else - sprite_sheet_name = name // Resets sprite sheet back to slime people. var/datum/species/s = GLOB.all_species[species_subtype] if(isnull(s)) @@ -123,12 +120,19 @@ female_cough_sounds = s.female_cough_sounds male_sneeze_sound = s.male_sneeze_sound female_sneeze_sound = s.female_sneeze_sound + bodyflags = s.bodyflags + if(species_subtype != "None") // Update our species display and reference name to match the subtype. Used for species specific clothing and accessories. + sprite_sheet_name = species_subtype + bodyflags |= static_bodyflags + else + sprite_sheet_name = name // Resets sprite sheet back to slime people. - H.body_accessory = default_bodyacc + H.body_accessory = GLOB.body_accessory_by_name[default_bodyacc] H.tail = tail H.wing = wing for(var/obj/item/organ/external/limb in H.bodyparts) // Update robotic limbs to match new sub species ico base in the case they have robotic limbs limb.icobase = s.icobase // update their icobase for when we apply the slimfy effect + limb.dna.species = src // Update limb to match our newly modified species limb.set_company(limb.model, sprite_sheet_name) // Update misc parts that are stored as reference in species and used on the mob. Also resets stylings to none to prevent anything wacky... diff --git a/code/modules/reagents/chemistry/reagents/misc_reagents.dm b/code/modules/reagents/chemistry/reagents/misc_reagents.dm index becb5f5bb504b..4a95fb9b2d0b9 100644 --- a/code/modules/reagents/chemistry/reagents/misc_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/misc_reagents.dm @@ -359,8 +359,8 @@ var/obj/item/organ/external/head/head_organ = H.get_organ("head") if(!istype(head_organ)) return ..() - head_organ.h_style = random_hair_style(H.gender, head_organ.dna.species.name) - head_organ.f_style = random_facial_hair_style(H.gender, head_organ.dna.species.name) + head_organ.h_style = random_hair_style(H.gender, head_organ.dna.species.sprite_sheet_name) + head_organ.f_style = random_facial_hair_style(H.gender, head_organ.dna.species.sprite_sheet_name) H.update_hair() H.update_fhair() ..() @@ -383,14 +383,14 @@ var/datum/sprite_accessory/tmp_hair_style = GLOB.hair_styles_full_list["Very Long Hair"] var/datum/sprite_accessory/tmp_facial_hair_style = GLOB.facial_hair_styles_list["Very Long Beard"] - if(head_organ.dna.species.name in tmp_hair_style.species_allowed) //If 'Very Long Hair' is a style the person's species can have, give it to them. + if(head_organ.dna.species.sprite_sheet_name in tmp_hair_style.species_allowed) //If 'Very Long Hair' is a style the person's species can have, give it to them. head_organ.h_style = "Very Long Hair" else //Otherwise, give them a random hair style. - head_organ.h_style = random_hair_style(H.gender, head_organ.dna.species.name) - if(head_organ.dna.species.name in tmp_facial_hair_style.species_allowed) //If 'Very Long Beard' is a style the person's species can have, give it to them. + head_organ.h_style = random_hair_style(H.gender, head_organ.dna.species.sprite_sheet_name) + if(head_organ.dna.species.sprite_sheet_name in tmp_facial_hair_style.species_allowed) //If 'Very Long Beard' is a style the person's species can have, give it to them. head_organ.f_style = "Very Long Beard" else //Otherwise, give them a random facial hair style. - head_organ.f_style = random_facial_hair_style(H.gender, head_organ.dna.species.name) + head_organ.f_style = random_facial_hair_style(H.gender, head_organ.dna.species.sprite_sheet_name) H.update_hair() H.update_fhair() if(!H.wear_mask || H.wear_mask && !istype(H.wear_mask, /obj/item/clothing/mask/fakemoustache)) diff --git a/code/modules/response_team/ert.dm b/code/modules/response_team/ert.dm index 5830ff8631f1d..144ed1c192c5d 100644 --- a/code/modules/response_team/ert.dm +++ b/code/modules/response_team/ert.dm @@ -196,8 +196,8 @@ GLOBAL_LIST_EMPTY(ert_request_messages) M.change_eye_color(eye_c) M.s_tone = skin_tone head_organ.headacc_colour = pick("#1f138b", "#272525", "#07a035", "#8c00ff", "#a80c0c") - head_organ.h_style = random_hair_style(M.gender, head_organ.dna.species.name) - head_organ.f_style = random_facial_hair_style(M.gender, head_organ.dna.species.name) + head_organ.h_style = random_hair_style(M.gender, head_organ.dna.species.sprite_sheet_name) + head_organ.f_style = random_facial_hair_style(M.gender, head_organ.dna.species.sprite_sheet_name) M.rename_character(null, "[pick("Corporal", "Sergeant", "Staff Sergeant", "Sergeant First Class", "Master Sergeant", "Sergeant Major")] [pick(GLOB.last_names)]") M.age = rand(23,35) diff --git a/code/modules/surgery/organs/organ_icon.dm b/code/modules/surgery/organs/organ_icon.dm index 7704c6707c542..86a1bf4b56756 100644 --- a/code/modules/surgery/organs/organ_icon.dm +++ b/code/modules/surgery/organs/organ_icon.dm @@ -108,7 +108,7 @@ var/head_marking = owner.m_styles["head"] if(head_marking) var/datum/sprite_accessory/head_marking_style = GLOB.marking_styles_list[head_marking] - if(head_marking_style && head_marking_style.species_allowed && (dna.species.name in head_marking_style.species_allowed) && head_marking_style.marking_location == "head") + if(head_marking_style && head_marking_style.species_allowed && (dna.species.sprite_sheet_name in head_marking_style.species_allowed) && head_marking_style.marking_location == "head") var/icon/h_marking_s = new /icon("icon" = head_marking_style.icon, "icon_state" = "[head_marking_style.icon_state]_s") if(head_marking_style.do_colouration) h_marking_s.Blend(owner.m_colours["head"], ICON_ADD) @@ -117,7 +117,7 @@ if(!((owner.head && (owner.head.flags & BLOCKHAIR)) || (owner.wear_mask && (owner.wear_mask.flags & BLOCKHAIR)))) //Common restriction for all the below features. if(ha_style) var/datum/sprite_accessory/head_accessory_style = GLOB.head_accessory_styles_list[ha_style] - if(head_accessory_style && head_accessory_style.species_allowed && (dna.species.name in head_accessory_style.species_allowed)) + if(head_accessory_style && head_accessory_style.species_allowed && (dna.species.sprite_sheet_name in head_accessory_style.species_allowed)) var/icon/head_accessory_s = new /icon("icon" = head_accessory_style.icon, "icon_state" = "[head_accessory_style.icon_state]_s") if(head_accessory_style.do_colouration) head_accessory_s.Blend(headacc_colour, ICON_ADD) @@ -125,7 +125,7 @@ if(f_style) var/datum/sprite_accessory/facial_hair_style = GLOB.facial_hair_styles_list[f_style] - if(facial_hair_style && ((facial_hair_style.species_allowed && (dna.species.name in facial_hair_style.species_allowed)) || (dna.species.bodyflags & ALL_RPARTS))) + if(facial_hair_style && ((facial_hair_style.species_allowed && (dna.species.sprite_sheet_name in facial_hair_style.species_allowed)) || (dna.species.bodyflags & ALL_RPARTS))) var/icon/facial_s = new /icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s") if(istype(dna.species, /datum/species/slime)) // I am el worstos facial_s.Blend("[owner.skin_colour]A0", ICON_AND) //A0 = 160 alpha. @@ -136,7 +136,7 @@ if(h_style) if(!ismachineperson(owner) || (ismachineperson(owner) && ((owner.head && (owner.head.flags & BLOCKHEADHAIR)) || (owner.wear_mask && (owner.wear_mask.flags & BLOCKHEADHAIR))))) var/datum/sprite_accessory/hair_style = GLOB.hair_styles_full_list[h_style] - if(hair_style && ((dna.species.name in hair_style.species_allowed) || (dna.species.bodyflags & ALL_RPARTS))) + if(hair_style && ((dna.species.sprite_sheet_name in hair_style.species_allowed) || (dna.species.bodyflags & ALL_RPARTS))) var/icon/hair_s = new /icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s") if(istype(dna.species, /datum/species/slime)) // I am el worstos hair_s.Blend("[owner.skin_colour]A0", ICON_AND) //A0 = 160 alpha. diff --git a/code/modules/tgui/modules/appearance_changer.dm b/code/modules/tgui/modules/appearance_changer.dm index ba291eb65a4ec..c2176758a09c7 100644 --- a/code/modules/tgui/modules/appearance_changer.dm +++ b/code/modules/tgui/modules/appearance_changer.dm @@ -17,9 +17,13 @@ var/list/whitelist var/list/blacklist + /// Temporary holder when we first initialize the TGUI, we store this as our owner's previous subtype so we can tell when it updates. + var/owner_subtype + /datum/ui_module/appearance_changer/New(datum/host, mob/living/carbon/human/H, check_species_whitelist = TRUE, list/species_whitelist = list(), list/species_blacklist = list()) ..() owner = H + owner_subtype = owner.dna.species.species_subtype head_organ = owner.get_organ("head") check_whitelist = check_species_whitelist whitelist = species_whitelist @@ -214,7 +218,11 @@ ui.open() /datum/ui_module/appearance_changer/ui_data(mob/user) - generate_data(check_whitelist, whitelist, blacklist) + if(user.dna.species.species_subtype != owner_subtype) + owner_subtype = user.dna.species.species_subtype + cut_and_generate_data() + else + generate_data(check_whitelist, whitelist, blacklist) var/list/data = list() data["specimen"] = owner.dna.species.name From 4fa8dec064f1e4184f31936b9df195887396ab98 Mon Sep 17 00:00:00 2001 From: Spaghetti-Bit Date: Thu, 14 Nov 2024 09:40:28 -0700 Subject: [PATCH 07/22] Me when initial --- code/modules/client/preference/character.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/modules/client/preference/character.dm b/code/modules/client/preference/character.dm index 162604a143afb..3c223b6c68543 100644 --- a/code/modules/client/preference/character.dm +++ b/code/modules/client/preference/character.dm @@ -850,8 +850,6 @@ current_species.female_sneeze_sound = subtype_species.female_sneeze_sound current_species.bodyflags = subtype_species.bodyflags current_species.bodyflags |= HAS_SKIN_COLOR | NO_EYES | HAS_SPECIES_SUBTYPE - else - current_species = initial(current_species) var/mob/living/carbon/human/H = new H.dna.species = current_species if(current_species.bodyflags & HAS_SPECIES_SUBTYPE) From 1c7e807f8f596184b517405514a83702c7af9dbc Mon Sep 17 00:00:00 2001 From: Spaghetti-Bit Date: Thu, 14 Nov 2024 09:43:51 -0700 Subject: [PATCH 08/22] 60 - 61 --- config/example/config.toml | 454 ++++++++++++++++--------------------- 1 file changed, 193 insertions(+), 261 deletions(-) diff --git a/config/example/config.toml b/config/example/config.toml index dbbd2398b41e7..e730a31f2bca8 100644 --- a/config/example/config.toml +++ b/config/example/config.toml @@ -34,10 +34,8 @@ # - voting_configuration # - - ################################################################ - [admin_configuration] # This section contains all information regarding admin setup. This includes ranks, rights, and if you are using the database-backed admin system @@ -69,70 +67,68 @@ enable_localhost_autoadmin = true # +MAINTAINER = Access to super dangerous debug verbs that can break an entire round. Use sparingly. # +DEV_TEAM = Access to dev team chat admin_ranks = [ - # Format: {name = "My Rank", rights = ["+LIST", "+OF", "+RIGHTS"]} - { name = "Mentor", rights = [ - "+MENTOR", - ] }, - { name = "Trial Admin", rights = [ - "+ADMIN", - "+BAN", - "+STEALTH", - "+REJUVINATE", - ] }, - { name = "Game Admin", rights = [ - "+ADMIN", - "+BAN", - "+STEALTH", - "+REJUVINATE", - "+DEBUG", - "+BUILDMODE", - "+EVENT", - "+SERVER", - "+POSSESS", - "+PROCCALL", - "+VAREDIT", - "+SOUND", - "+SPAWN", - ] }, - { name = "Head of Staff", rights = [ - "+EVERYTHING", - ] }, - { name = "Hosting Provider", rights = [ - "+EVERYTHING", - ] }, - { name = "Maintainers", rights = [ - "+EVERYTHING", - ] }, - { name = "Developer", rights = [ - "+DEV_TEAM", - ] }, + # Format: {name = "My Rank", rights = ["+LIST", "+OF", "+RIGHTS"]} + {name = "Mentor", rights = [ + "+MENTOR", + ]}, + {name = "Trial Admin", rights = [ + "+ADMIN", + "+BAN", + "+STEALTH", + "+REJUVINATE", + ]}, + {name = "Game Admin", rights = [ + "+ADMIN", + "+BAN", + "+STEALTH", + "+REJUVINATE", + "+DEBUG", + "+BUILDMODE", + "+EVENT", + "+SERVER", + "+POSSESS", + "+PROCCALL", + "+VAREDIT", + "+SOUND", + "+SPAWN", + ]}, + {name = "Head of Staff", rights = [ + "+EVERYTHING", + ]}, + {name = "Hosting Provider", rights = [ + "+EVERYTHING", + ]}, + {name = "Maintainers", rights = [ + "+EVERYTHING", + ]}, + {name = "Developer", rights = [ + "+DEV_TEAM", + ]}, ] # List of people and the admin rank they are assigned to admin_assignments = [ - #{ckey = "Your Name Here", rank = "Hosting Provider"} + #{ckey = "Your Name Here", rank = "Hosting Provider"} ] # Allow admins to set their own OOC colour allow_admin_ooc_colour = true # Map of admin rank colours to their respective rank. Note you can use hex or colour name here. admin_rank_colour_map = [ - { name = "Head of Staff", colour = "#e74c3c" }, - { name = "Maintainer", colour = "#992d22" }, - { name = "Server Dev", colour = "#1abc9c" }, - { name = "Community Manager", colour = "#e91e63" }, - { name = "Game Admin", colour = "#238afa" }, - { name = "Trial Admin", colour = "#7fb6fc" }, - { name = "Developer", colour = "#61b413" }, - { name = "Mentor", colour = "#f1c40f" }, + {name = "Head of Staff", colour = "#e74c3c"}, + {name = "Maintainer", colour = "#992d22"}, + {name = "Server Dev", colour = "#1abc9c"}, + {name = "Community Manager", colour = "#e91e63"}, + {name = "Game Admin", colour = "#238afa"}, + {name = "Trial Admin", colour = "#7fb6fc"}, + {name = "Developer", colour = "#61b413"}, + {name = "Mentor", colour = "#f1c40f"}, ] # Map of common CIDs that should not be banned, plus their reasons common_cid_map = [ - { cid = "3923664137", reason = "Mass-Match related to Walmart branded prebuilt PCs" }, + {cid = "3923664137", reason = "Mass-Match related to Walmart branded prebuilt PCs"}, ] - ################################################################ - [afk_configuration] # This section contains options for the auto AFK cryo system @@ -145,10 +141,8 @@ afk_auto_despawn_minutes = 21 # Amount of time before SSD people are auto cryo'd ssd_auto_cryo_minutes = 15 - ################################################################ - [custom_sprites_configuration] # This section contains a list of information for people with custom sprites for mobs, if they donated # It is split by mob type, and screens have their own system @@ -164,16 +158,14 @@ ai_hologram = ["ckeyhere"] pai_holoform = ["ckeyhere"] # List of dictionary entries for ckeys with a custom IPC screean ipc_screens = [ - { ckey = "ckeyhere", screens = [ - "Icon State 1", - "Icon State 2", - ] }, + {ckey = "ckeyhere", screens = [ + "Icon State 1", + "Icon State 2", + ]}, ] - ################################################################ - [database_configuration] # This section contains all the settings for the ingame database # If you are running in production, you will want to be using a database @@ -181,7 +173,7 @@ ipc_screens = [ # Enable/disable the database on a whole sql_enabled = false # SQL version. If this is a mismatch, round start will be delayed -sql_version = 60 +sql_version = 61 # SQL server address. Can be an IP or DNS name sql_address = "127.0.0.1" # SQL server port @@ -197,10 +189,8 @@ async_query_timeout = 10 # How many threads is the async SQL engine allowed to open. 50 is normal. Trust me. async_thread_limit = 50 - ################################################################ - [discord_configuration] # This section contains all the information related to Discord webhook sending from the code # If you are using webhooks, please fill out this section in full @@ -210,8 +200,8 @@ enable_discord_webhooks = false main_webhook_urls = ["https://webhook.one", "https://webhook.two"] # List of all webhook URLs for the mentor feed (mentorhelps relay) mentor_webhook_urls = [ - "https://mentor.webhook.one", - "https://mentor.webhook.two", + "https://mentor.webhook.one", + "https://mentor.webhook.two", ] # List of all webhook URLs for the admin feed (round alerts, ahelps, etc) admin_webhook_urls = ["https://admin.webhook.one", "https://admin.webhook.two"] @@ -224,34 +214,30 @@ mentor_role_id = "" # Forward all ahelps to the discord? If disabled, ahelps are only forwarded if admins are AFK/Offline forward_all_ahelps = true - ################################################################ - [event_configuration] # This section contains settings for ingame random events # Disable this to disable all random events allow_random_events = true # Map of lower bounds for event delays. In minutes. -event_delay_lower_bounds = { mundane = 10, moderate = 30, major = 50 } +event_delay_lower_bounds = {mundane = 10, moderate = 30, major = 50} # Map of upper bounds for event delays. In minutes. -event_delay_upper_bounds = { mundane = 15, moderate = 45, major = 70 } +event_delay_upper_bounds = {mundane = 15, moderate = 45, major = 70} # Expected round length in minutes. Changes event weights expected_round_length = 120 # Initial delays for the first events firing off. If any of these are commented, a random value based on above thresholds is used. # You must specify an upper and lower bound, or the code cries a lot. The events system is so bad good god. # Values are in minutes event_initial_delays = [ - #{severity = "mundane", lower_bound = 10, upper_bound = 15}, - { severity = "moderate", lower_bound = 25, upper_bound = 40 }, - { severity = "major", lower_bound = 55, upper_bound = 75 }, + #{severity = "mundane", lower_bound = 10, upper_bound = 15}, + {severity = "moderate", lower_bound = 25, upper_bound = 40}, + {severity = "major", lower_bound = 55, upper_bound = 75}, ] - ################################################################ - [gamemode_configuration] # This section contains setups for the gamemodes, as well as their probabilities @@ -259,21 +245,21 @@ event_initial_delays = [ antag_account_age_restrictions = false # Gamemode probabilities map for if you are using secret or random gamemode_probabilities = [ - { gamemode = "abduction", probability = 0 }, - { gamemode = "changeling", probability = 0 }, - { gamemode = "cult", probability = 3 }, - { gamemode = "extend-a-traitormongous", probability = 2 }, # Autotraitor - { gamemode = "extended", probability = 3 }, - { gamemode = "nuclear", probability = 2 }, - { gamemode = "raginmages", probability = 0 }, - { gamemode = "revolution", probability = 0 }, - { gamemode = "traitor", probability = 2 }, - { gamemode = "traitorchan", probability = 3 }, - { gamemode = "traitorvamp", probability = 3 }, - { gamemode = "vampchan", probability = 3}, - { gamemode = "vampire", probability = 3 }, - { gamemode = "wizard", probability = 2 }, - { gamemode = "trifecta", probability = 3 }, + {gamemode = "abduction", probability = 0}, + {gamemode = "changeling", probability = 0}, + {gamemode = "cult", probability = 3}, + {gamemode = "extend-a-traitormongous", probability = 2}, # Autotraitor + {gamemode = "extended", probability = 3}, + {gamemode = "nuclear", probability = 2}, + {gamemode = "raginmages", probability = 0}, + {gamemode = "revolution", probability = 0}, + {gamemode = "traitor", probability = 2}, + {gamemode = "traitorchan", probability = 3}, + {gamemode = "traitorvamp", probability = 3}, + {gamemode = "vampchan", probability = 3}, + {gamemode = "vampire", probability = 3}, + {gamemode = "wizard", probability = 2}, + {gamemode = "trifecta", probability = 3}, ] # Do we want the amount of traitors to scale with population? traitor_scaling = true @@ -288,10 +274,8 @@ enable_gamemode_player_limit = true # Enable to generate zero or more random station traits on game start. add_random_station_traits = false - ################################################################ - [general_configuration] # General setup for the server (branding, options, etc) @@ -381,10 +365,8 @@ revival_brain_life = 6000 # 10 minutes # Enable random silicon lawset (If said lawset has default = TRUE in the code). Disable for always crewsimov random_ai_lawset = true - ################################################################ - [lighting_effects_configuration] # Settings that allow you to change light effects (bloom / exposure intensity) @@ -405,10 +387,8 @@ exposure_contrast_base = 9.5 # Contrast of exposure effect that depends on light_power exposure_contrast_power = 0 - ################################################################ - [ipintel_configuration] # This section contains all the information for IPIntel (The Anti VPN system) @@ -431,10 +411,8 @@ playtime_ignore_threshold = 10 # Details URL for more info on an IP (such as ASN). IP is tacked on the end. details_url = "https://iphub.info/?ip=" - ################################################################ - [job_configuration] # This section contains information on job configuartion, as well as the jon amounts @@ -463,51 +441,41 @@ assistant_security_ratio = 2 enable_job_amount_overrides = true # Job slot amount map. These are overrides. If you dont specify a value here, the code will be used as default. -1 is infinite job_slot_amounts = [ - # Commmand - { name = "Captain", lowpop = 1, highpop = 1 }, - { name = "Head of Personnel", lowpop = 1, highpop = 1 }, - { name = "Head of Security", lowpop = 1, highpop = 1 }, - { name = "Chief Engineer", lowpop = 1, highpop = 1 }, - { name = "Research Director", lowpop = 1, highpop = 1 }, - { name = "Chief Medical Officer", lowpop = 1, highpop = 1 }, - # Engineering - { name = "Life Support Specialist", lowpop = 3, highpop = 4 }, - { name = "Station Engineer", lowpop = 5, highpop = 6 }, - # Medical - { name = "Chemist", lowpop = 2, highpop = 2 }, - { name = "Geneticist", lowpop = 2, highpop = 2 }, - { name = "Medical Doctor", lowpop = 5, highpop = 6 }, - { name = "Virologist", lowpop = 1, highpop = 1 }, - # Science - { name = "Roboticist", lowpop = 2, highpop = 2 }, - { name = "Scientist", lowpop = 6, highpop = 7 }, - # Security - { name = "Detective", lowpop = 1, highpop = 1 }, - { name = "Security Officer", lowpop = 8, highpop = 9 }, - { name = "Warden", lowpop = 1, highpop = 1 }, - { name = "Internal Affairs Agent", lowpop = 2, highpop = 2 }, - # Service - { name = "Bartender", lowpop = 1, highpop = 1 }, - { name = "Botanist", lowpop = 2, highpop = 2 }, - { name = "Chaplain", lowpop = 1, highpop = 1 }, - { name = "Chef", lowpop = 1, highpop = 1 }, - { name = "Janitor", lowpop = 1, highpop = 2 }, - { name = "Librarian", lowpop = 1, highpop = 1 }, - # Cargo/Supply - { name = "Quartermaster", lowpop = 1, highpop = 1 }, - { name = "Shaft Miner", lowpop = 6, highpop = 6 }, - { name = "Cargo Technician", lowpop = 3, highpop = 4 }, - # Silicon - { name = "AI", lowpop = 1, highpop = 1 }, - { name = "Cyborg", lowpop = 1, highpop = 1 }, - # Misc - { name = "Assistant", lowpop = -1, highpop = -1 }, + # Commmand + {name = "Captain", lowpop = 1, highpop = 1}, + {name = "Head of Personnel", lowpop = 1, highpop = 1}, + {name = "Head of Security", lowpop = 1, highpop = 1}, + {name = "Chief Engineer", lowpop = 1, highpop = 1}, + {name = "Research Director", lowpop = 1, highpop = 1}, + {name = "Chief Medical Officer", lowpop = 1, highpop = 1}, # Engineering + {name = "Life Support Specialist", lowpop = 3, highpop = 4}, + {name = "Station Engineer", lowpop = 5, highpop = 6}, # Medical + {name = "Chemist", lowpop = 2, highpop = 2}, + {name = "Geneticist", lowpop = 2, highpop = 2}, + {name = "Medical Doctor", lowpop = 5, highpop = 6}, + {name = "Virologist", lowpop = 1, highpop = 1}, # Science + {name = "Roboticist", lowpop = 2, highpop = 2}, + {name = "Scientist", lowpop = 6, highpop = 7}, # Security + {name = "Detective", lowpop = 1, highpop = 1}, + {name = "Security Officer", lowpop = 8, highpop = 9}, + {name = "Warden", lowpop = 1, highpop = 1}, + {name = "Internal Affairs Agent", lowpop = 2, highpop = 2}, # Service + {name = "Bartender", lowpop = 1, highpop = 1}, + {name = "Botanist", lowpop = 2, highpop = 2}, + {name = "Chaplain", lowpop = 1, highpop = 1}, + {name = "Chef", lowpop = 1, highpop = 1}, + {name = "Janitor", lowpop = 1, highpop = 2}, + {name = "Librarian", lowpop = 1, highpop = 1}, # Cargo/Supply + {name = "Quartermaster", lowpop = 1, highpop = 1}, + {name = "Shaft Miner", lowpop = 6, highpop = 6}, + {name = "Cargo Technician", lowpop = 3, highpop = 4}, # Silicon + {name = "AI", lowpop = 1, highpop = 1}, + {name = "Cyborg", lowpop = 1, highpop = 1}, # Misc + {name = "Assistant", lowpop = -1, highpop = -1}, ] - ################################################################ - [logging_configuration] # Configuration for all things related to logging data to disk # If you are in production you will want most of these on @@ -545,10 +513,8 @@ enable_adminchat_logging = true # Log debug messages enable_debug_logging = true - ################################################################ - [metrics_configuration] # This section contains values for all metrics storing. # This is designed for ElasticSearch but you might be able to make it work with other things. @@ -561,10 +527,8 @@ metrics_endpoint = "http://elastic-host:9200/your_index/_doc" # Metrics API token. Placed into the auth header metrics_api_token = "your_base64_encoded_thingy==" - ################################################################ - [mc_configuration] # This section is settings for the MC # Dont change these unless you know what you are doing @@ -582,10 +546,8 @@ mc_highpop_threshold_enable = 65 # Threshold to disable MC highpop mode mc_highpop_threshold_disable = 60 - ################################################################ - [movement_configuration] # This section contains values for all mob movement stuff. # We suggest VVing ingame till you get values you like. @@ -608,10 +570,8 @@ slime_delay = 1.5 # Move delay for other simple animals animal_delay = 2.5 - ################################################################ - [overflow_configuration] # This contains information for re-routing players to an overflow server # We dont use this in production, but you may find it useful @@ -623,10 +583,8 @@ overflow_server = "byond://yourdomain.com:1111" # List of ckeys who will not get rerouted to the overflow server overflow_whitelist = ["keyhere", "anotherhere"] - ################################################################ - [redis_configuration] # This section contains all the settings for using redis. # This is heavily tied into the Paradise production architecture and you probably dont need it. @@ -636,10 +594,8 @@ redis_enabled = false # Redis connection string. Include your passphrase if needed redis_connstring = "redis://127.0.0.1/" - ################################################################ - [ruin_configuration] # This section contains configuration for all space ruins and lava ruins @@ -654,113 +610,96 @@ maximum_zlevels = 4 # List of all space ruins that can generate in the world # Commenting something out in here DISABLES IT FROM SPAWNING active_space_ruins = [ - "_maps/map_files/RandomRuins/SpaceRuins/way_home.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/asteroid1.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/asteroid2.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/asteroid3.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/asteroid4.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/asteroid5.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/derelict1.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/derelict2.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/derelict3.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/derelict4.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/derelict5.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/spacebar.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/deepstorage.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/emptyshell.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/intactemptyship.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/meatpackers.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/mechtransport.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/turretedoutpost.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/debris1.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/debris2.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/debris3.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/listeningpost.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/moonoutpost19.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/onehalf.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/syndiecakesfactory.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/voyager.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/wreckedcargoship.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/abandoned_engi_sat.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/telecomns_returns.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/casino.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/rocky_motel.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/abandoned_sec_shuttle.dmm", - - ### The following ruins are based from past pre-spawned Zlevel content ### - "_maps/map_files/RandomRuins/SpaceRuins/abandonedtele.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/blowntcommsat.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/clownmime.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/dj.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/druglab.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/syndicatedruglab.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/syndiedepot.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/syndie_space_base.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/ussp_tele.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/ussp.dmm", - - - # The following is the white ship ruin. Its force-spawned and is required to stop SSshuttle runtiming on startup - # Its also important incase a white-ship console is ever built midround - # DO NOT DISABLE THIS UNLESS YOU HAVE A GOOD REASON - "_maps/map_files/RandomRuins/SpaceRuins/whiteship.dmm", - - # The following is a force-spawned ruin consisting mostly of empty space with a shuttle docking port for the free golem shuttle - # Disabling it will lead to the free golem shuttle sometimes being stuck on lavaland. - "_maps/map_files/RandomRuins/SpaceRuins/golemtarget.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/way_home.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/asteroid1.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/asteroid2.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/asteroid3.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/asteroid4.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/asteroid5.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/derelict1.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/derelict2.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/derelict3.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/derelict4.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/derelict5.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/spacebar.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/deepstorage.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/emptyshell.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/intactemptyship.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/meatpackers.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/mechtransport.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/turretedoutpost.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/debris1.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/debris2.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/debris3.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/listeningpost.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/moonoutpost19.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/onehalf.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/syndiecakesfactory.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/voyager.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/wreckedcargoship.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/abandoned_engi_sat.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/telecomns_returns.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/casino.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/rocky_motel.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/abandoned_sec_shuttle.dmm", ### The following ruins are based from past pre-spawned Zlevel content ### + "_maps/map_files/RandomRuins/SpaceRuins/abandonedtele.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/blowntcommsat.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/clownmime.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/dj.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/druglab.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/syndicatedruglab.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/syndiedepot.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/syndie_space_base.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/ussp_tele.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/ussp.dmm", # The following is the white ship ruin. Its force-spawned and is required to stop SSshuttle runtiming on startup # Its also important incase a white-ship console is ever built midround + # DO NOT DISABLE THIS UNLESS YOU HAVE A GOOD REASON + "_maps/map_files/RandomRuins/SpaceRuins/whiteship.dmm", # The following is a force-spawned ruin consisting mostly of empty space with a shuttle docking port for the free golem shuttle + # Disabling it will lead to the free golem shuttle sometimes being stuck on lavaland. + "_maps/map_files/RandomRuins/SpaceRuins/golemtarget.dmm", ] # List of all ruins that can generate on lavaland # Commenting something out in here DISABLES IT FROM SPAWNING active_lava_ruins = [ - ##BIODOMES - "_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_winter.dmm", - ##RESPAWN - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm", - ##SIN - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_envy.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_gluttony.dmm", - # Greed blacklisted on production because its reward (dice) has a 1/20 chance of making you a wizard - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_greed.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_pride.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_sloth.dmm", - ##MEGAFAUNA - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk1.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk2.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk3.dmm", - # Re-removed 7/24/2020, I ran a month-long test of hierophant Jun-Jul and the staff was still too strong. https://github.com/ParadiseSS13/Paradise/pull/13542 - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_hierophant.dmm", - - ##MISC - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_althland_excavation.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_althland_facility.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_dead_ratvar.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_elite_tumor.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_fountain_hall.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_monster_nest.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_puzzle.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_shuttlecrash.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_ufo_crash.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_watcher_grave.dmm", - "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_xeno_nest.dmm", + ##BIODOMES + "_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_clown_planet.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_biodome_winter.dmm", ##RESPAWN + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_ash_walker1.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_hermit.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_seed_vault.dmm", ##SIN + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_envy.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_gluttony.dmm", # Greed blacklisted on production because its reward (dice) has a 1/20 chance of making you a wizard + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_greed.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_pride.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_sloth.dmm", ##MEGAFAUNA + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk1.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk2.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_blooddrunk3.dmm", # Re-removed 7/24/2020, I ran a month-long test of hierophant Jun-Jul and the staff was still too strong. https://github.com/ParadiseSS13/Paradise/pull/13542 + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_hierophant.dmm", ##MISC + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_althland_excavation.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_althland_facility.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_cultaltar.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_dead_ratvar.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_elite_tumor.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_fountain_hall.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_monster_nest.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_pizzaparty.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_puzzle.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_random_ripley.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_shuttlecrash.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_survivalpod.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_ufo_crash.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_watcher_grave.dmm", + "_maps/map_files/RandomRuins/LavaRuins/lavaland_surface_xeno_nest.dmm", ] # Budget for lavaland ruins. A higher number means more will spawn lavaland_ruin_budget = 60 - ################################################################ - [system_configuration] # This contains stuff that the host should fill out, relating to backend stuff @@ -797,15 +736,13 @@ external_tos_handler = false # This is not for separate DD instances per region, but if you have a geo-routing setup deployed to optimise routing for players # I am 99.9% certain you will never need to fill this out regional_servers = [ - #{name = "UK", ip = "byond://uk.paradisestation.org:6666"}, + #{name = "UK", ip = "byond://uk.paradisestation.org:6666"}, ] # Send a toast on server init completion. You probably dont need this on in production toast_on_init_complete = true - ################################################################ - [url_configuration] # Configuration for all the URLs used by the server # If you are in production you will want to tweak these to your servers @@ -845,10 +782,8 @@ centcomm_ban_db_url = "https://centcom.melonmesa.com/ban/search/" # URL for the game stats page, if applicable. Round ID is appended right on the end. Include a trailing slash if necessary. #round_stats_url = "https://affectedarc07.github.io/ParaStats/#/round/" - ################################################################ - [voting_configuration] # This section contains all settings relating to the ingame voting system @@ -875,19 +810,17 @@ non_repeating_maps = true # - "Random" = no vote, map is random # If you dont enter one correctly, it will whine on startup map_vote_day_types = [ - { day_number = 1, rotation_type = "Vote" }, # Monday - { day_number = 2, rotation_type = "Random" }, # Tuesday - { day_number = 3, rotation_type = "Vote" }, # Wednesday - { day_number = 4, rotation_type = "Random" }, # Thursday - { day_number = 5, rotation_type = "Vote" }, # Friday - { day_number = 6, rotation_type = "Nodupes" }, # Saturday - { day_number = 7, rotation_type = "Nodupes" }, # Sunday + {day_number = 1, rotation_type = "Vote"}, # Monday + {day_number = 2, rotation_type = "Random"}, # Tuesday + {day_number = 3, rotation_type = "Vote"}, # Wednesday + {day_number = 4, rotation_type = "Random"}, # Thursday + {day_number = 5, rotation_type = "Vote"}, # Friday + {day_number = 6, rotation_type = "Nodupes"}, # Saturday + {day_number = 7, rotation_type = "Nodupes"}, # Sunday ] - ################################################################ - [asset_cache_configuration] # Browser assets are any file included in interfaces. css, images, javascript, etc. # This handles configuring how we get these to the player so interfaces can access them. @@ -906,5 +839,4 @@ asset_simple_preload = true # if you want to test this locally, you simpily run the `localhost-asset-webroot-server.py` python3 script to host assets stored in `data/asset-store/` via http://localhost:58715/ # asset_cdn_url = "http://localhost:58715/" - # Congratulations. You reached the end. heres a cookie. From 2cc5eeaf559b6ab6d25864ee55ee77a5e423aa97 Mon Sep 17 00:00:00 2001 From: Spaghetti-Bit Date: Thu, 14 Nov 2024 23:27:48 -0700 Subject: [PATCH 09/22] Character.dm select query changes. --- code/modules/client/preference/character.dm | 120 ++++++++++---------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/code/modules/client/preference/character.dm b/code/modules/client/preference/character.dm index 3c223b6c68543..8ea80f450bb80 100644 --- a/code/modules/client/preference/character.dm +++ b/code/modules/client/preference/character.dm @@ -282,7 +282,7 @@ var/datum/db_query/query = SSdbcore.NewQuery({" INSERT INTO characters (ckey, slot, OOC_Notes, real_name, name_is_always_random, gender, - age, species, species_subtype, language, + age, species, language, hair_colour, secondary_hair_colour, facial_hair_colour, secondary_facial_hair_colour, skin_tone, skin_colour, @@ -306,10 +306,10 @@ player_alt_titles, disabilities, organ_data, rlimb_data, nanotrasen_relation, physique, height, speciesprefs, socks, body_accessory, gear, autohiss, - hair_gradient, hair_gradient_offset, hair_gradient_colour, hair_gradient_alpha, custom_emotes, runechat_color, cyborg_brain_type, body_type) + hair_gradient, hair_gradient_offset, hair_gradient_colour, hair_gradient_alpha, custom_emotes, runechat_color, cyborg_brain_type, body_type, species_subtype) VALUES (:ckey, :slot, :metadata, :name, :be_random_name, :gender, - :age, :species, :species_subtype, :language, + :age, :species, :language, :h_colour, :h_sec_colour, :f_colour, :f_sec_colour, :s_tone, :s_colour, @@ -333,7 +333,7 @@ :playertitlelist, :disabilities, :organ_list, :rlimb_list, :nanotrasen_relation, :physique, :height, :speciesprefs, :socks, :body_accessory, :gearlist, :autohiss_mode, - :h_grad_style, :h_grad_offset, :h_grad_colour, :h_grad_alpha, :custom_emotes, :runechat_color, :cyborg_brain_type, :body_type) + :h_grad_style, :h_grad_offset, :h_grad_colour, :h_grad_alpha, :custom_emotes, :runechat_color, :cyborg_brain_type, :body_type, :species_subtype) "}, list( // This has too many params for anyone to look at this without going insae "ckey" = C.ckey, @@ -345,7 +345,6 @@ "body_type" = body_type, "age" = age, "species" = species, - "species_subtype" = species_subtype, "language" = language, "h_colour" = h_colour, "h_sec_colour" = h_sec_colour, @@ -397,7 +396,8 @@ "h_grad_alpha" = h_grad_alpha, "custom_emotes" = json_encode(custom_emotes), "runechat_color" = runechat_color, - "cyborg_brain_type" = cyborg_brain_type + "cyborg_brain_type" = cyborg_brain_type, + "species_subtype" = species_subtype )) if(!query.warn_execute()) @@ -421,45 +421,44 @@ gender = query.item[4] age = text2num(query.item[5]) species = query.item[6] - species_subtype = query.item[7] - language = query.item[8] - h_colour = query.item[9] - h_sec_colour = query.item[10] - f_colour = query.item[11] - f_sec_colour = query.item[12] - s_tone = text2num(query.item[13]) - s_colour = query.item[14] - m_colours = params2list(query.item[15]) - hacc_colour = query.item[16] - h_style = query.item[17] - f_style = query.item[18] - m_styles = params2list(query.item[19]) - ha_style = query.item[20] - alt_head = query.item[21] - e_colour = query.item[22] - underwear = query.item[23] - undershirt = query.item[24] - backbag = query.item[25] - b_type = query.item[26] + language = query.item[7] + h_colour = query.item[8] + h_sec_colour = query.item[9] + f_colour = query.item[10] + f_sec_colour = query.item[11] + s_tone = text2num(query.item[12]) + s_colour = query.item[13] + m_colours = params2list(query.item[14]) + hacc_colour = query.item[15] + h_style = query.item[16] + f_style = query.item[17] + m_styles = params2list(query.item[18]) + ha_style = query.item[19] + alt_head = query.item[20] + e_colour = query.item[21] + underwear = query.item[22] + undershirt = query.item[23] + backbag = query.item[24] + b_type = query.item[25] //Jobs - alternate_option = text2num(query.item[27]) - job_support_high = text2num(query.item[28]) - job_support_med = text2num(query.item[29]) - job_support_low = text2num(query.item[30]) - job_medsci_high = text2num(query.item[31]) - job_medsci_med = text2num(query.item[32]) - job_medsci_low = text2num(query.item[33]) - job_engsec_high = text2num(query.item[34]) - job_engsec_med = text2num(query.item[35]) - job_engsec_low = text2num(query.item[36]) + alternate_option = text2num(query.item[26]) + job_support_high = text2num(query.item[27]) + job_support_med = text2num(query.item[28]) + job_support_low = text2num(query.item[29]) + job_medsci_high = text2num(query.item[30]) + job_medsci_med = text2num(query.item[31]) + job_medsci_low = text2num(query.item[32]) + job_engsec_high = text2num(query.item[33]) + job_engsec_med = text2num(query.item[34]) + job_engsec_low = text2num(query.item[35]) //Miscellaneous - flavor_text = query.item[37] - med_record = query.item[38] - sec_record = query.item[39] - gen_record = query.item[40] + flavor_text = query.item[36] + med_record = query.item[37] + sec_record = query.item[38] + gen_record = query.item[39] // Apparently, the preceding vars weren't always encoded properly... if(findtext(flavor_text, "<")) // ... so let's clumsily check for tags! flavor_text = html_encode(flavor_text) @@ -469,29 +468,30 @@ sec_record = html_encode(sec_record) if(findtext(gen_record, "<")) gen_record = html_encode(gen_record) - disabilities = text2num(query.item[41]) - player_alt_titles = params2list(query.item[42]) - organ_data = params2list(query.item[43]) - rlimb_data = params2list(query.item[44]) - nanotrasen_relation = query.item[45] - speciesprefs = text2num(query.item[46]) + disabilities = text2num(query.item[40]) + player_alt_titles = params2list(query.item[41]) + organ_data = params2list(query.item[42]) + rlimb_data = params2list(query.item[43]) + nanotrasen_relation = query.item[44] + speciesprefs = text2num(query.item[45]) //socks - socks = query.item[47] - body_accessory = query.item[48] - loadout_gear = query.item[49] + socks = query.item[46] + body_accessory = query.item[47] + loadout_gear = query.item[48] + autohiss_mode = text2num(query.item[49]) // Index [50] is the slot - autohiss_mode = text2num(query.item[51]) - h_grad_style = query.item[52] - h_grad_offset_x = query.item[53] // parsed down below - h_grad_colour = query.item[54] - h_grad_alpha = query.item[55] - var/custom_emotes_tmp = query.item[56] - runechat_color = query.item[57] - physique = query.item[58] - height = query.item[59] - cyborg_brain_type = query.item[60] - body_type = query.item[61] + h_grad_style = query.item[51] + h_grad_offset_x = query.item[52] // parsed down below + h_grad_colour = query.item[53] + h_grad_alpha = query.item[54] + var/custom_emotes_tmp = query.item[55] + runechat_color = query.item[56] + physique = query.item[57] + height = query.item[58] + cyborg_brain_type = query.item[59] + body_type = query.item[60] + species_subtype = query.item[61] //Sanitize var/datum/species/SP = GLOB.all_species[species] From 2b63b9976de00cf7a5088b78ee0e1892aa5ba028 Mon Sep 17 00:00:00 2001 From: Spaghetti-Bit Date: Thu, 14 Nov 2024 23:36:39 -0700 Subject: [PATCH 10/22] 61-62 --- SQL/updates/61-62.sql | 6 ++ config/example/config.toml | 124 +++++++++++++++++-------------------- 2 files changed, 64 insertions(+), 66 deletions(-) create mode 100644 SQL/updates/61-62.sql diff --git a/SQL/updates/61-62.sql b/SQL/updates/61-62.sql new file mode 100644 index 0000000000000..312563ee9b150 --- /dev/null +++ b/SQL/updates/61-62.sql @@ -0,0 +1,6 @@ +# Updates the DB from 61 to 62 ~SpaghettiBit +# Adds a subtype race to be stored on character saves + +# Add species_subtype after species +ALTER TABLE `characters` + ADD COLUMN `species_subtype` VARCHAR(7) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'None' AFTER `species`; diff --git a/config/example/config.toml b/config/example/config.toml index 2660237a5f740..adea7d40fba8e 100644 --- a/config/example/config.toml +++ b/config/example/config.toml @@ -173,7 +173,7 @@ ipc_screens = [ # Enable/disable the database on a whole sql_enabled = false # SQL version. If this is a mismatch, round start will be delayed -sql_version = 61 +sql_version = 62 # SQL server address. Can be an IP or DNS name sql_address = "127.0.0.1" # SQL server port @@ -612,64 +612,56 @@ maximum_zlevels = 4 # List of all space ruins that can generate in the world # Commenting something out in here DISABLES IT FROM SPAWNING active_space_ruins = [ - "_maps/map_files/RandomRuins/SpaceRuins/way_home.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/asteroid1.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/asteroid2.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/asteroid3.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/asteroid4.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/asteroid5.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/derelict1.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/derelict2.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/derelict3.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/derelict4.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/derelict5.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/spacebar.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/deepstorage.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/emptyshell.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/intactemptyship.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/meatpackers.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/mechtransport.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/turretedoutpost.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/debris1.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/debris2.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/debris3.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/listeningpost.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/moonoutpost19.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/onehalf.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/syndiecakesfactory.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/voyager.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/wreckedcargoship.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/abandoned_engi_sat.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/telecomns_returns.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/casino.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/rocky_motel.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/abandoned_sec_shuttle.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/unathi_skiff.dmm", - - ### The following ruins are based from past pre-spawned Zlevel content ### - "_maps/map_files/RandomRuins/SpaceRuins/abandonedtele.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/blowntcommsat.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/clownmime.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/dj.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/druglab.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/syndicatedruglab.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/syndiedepot.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/syndie_space_base.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/ussp_tele.dmm", - "_maps/map_files/RandomRuins/SpaceRuins/ussp.dmm", - - - # The following is the white ship ruin. Its force-spawned and is required to stop SSshuttle runtiming on startup - # Its also important incase a white-ship console is ever built midround - # DO NOT DISABLE THIS UNLESS YOU HAVE A GOOD REASON - "_maps/map_files/RandomRuins/SpaceRuins/whiteship.dmm", - - # The following is a force-spawned ruin consisting mostly of empty space with a shuttle docking port for the free golem shuttle - # Disabling it will lead to the free golem shuttle sometimes being stuck on lavaland. - "_maps/map_files/RandomRuins/SpaceRuins/golemtarget.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/way_home.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/asteroid1.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/asteroid2.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/asteroid3.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/asteroid4.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/asteroid5.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/derelict1.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/derelict2.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/derelict3.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/derelict4.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/derelict5.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/spacebar.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/abandonedzoo.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/deepstorage.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/emptyshell.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/intactemptyship.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/meatpackers.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/mechtransport.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/turretedoutpost.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/debris1.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/debris2.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/debris3.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/listeningpost.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/moonoutpost19.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/oldstation.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/onehalf.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/syndiecakesfactory.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/wizardcrash.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/voyager.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/wreckedcargoship.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/abandoned_engi_sat.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/telecomns_returns.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/casino.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/rocky_motel.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/abandoned_sec_shuttle.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/unathi_skiff.dmm", ### The following ruins are based from past pre-spawned Zlevel content ### + "_maps/map_files/RandomRuins/SpaceRuins/abandonedtele.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/blowntcommsat.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/clownmime.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/dj.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/druglab.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/syndicatedruglab.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/syndiedepot.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/syndie_space_base.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/ussp_tele.dmm", + "_maps/map_files/RandomRuins/SpaceRuins/ussp.dmm", # The following is the white ship ruin. Its force-spawned and is required to stop SSshuttle runtiming on startup # Its also important incase a white-ship console is ever built midround + # DO NOT DISABLE THIS UNLESS YOU HAVE A GOOD REASON + "_maps/map_files/RandomRuins/SpaceRuins/whiteship.dmm", # The following is a force-spawned ruin consisting mostly of empty space with a shuttle docking port for the free golem shuttle + # Disabling it will lead to the free golem shuttle sometimes being stuck on lavaland. + "_maps/map_files/RandomRuins/SpaceRuins/golemtarget.dmm", ] # List of all ruins that can generate on lavaland # Commenting something out in here DISABLES IT FROM SPAWNING @@ -822,13 +814,13 @@ non_repeating_maps = true # - "FPTP" = A vote that excludes the map from the current round, and last round, then uses a weighted pick on the remaining maps, from preferences. # If you dont enter one correctly, it will whine on startup map_vote_day_types = [ - { day_number = 1, rotation_type = "Vote" }, # Monday - { day_number = 2, rotation_type = "Random" }, # Tuesday - { day_number = 3, rotation_type = "FPTP" }, # Wednesday - { day_number = 4, rotation_type = "Random" }, # Thursday - { day_number = 5, rotation_type = "Vote" }, # Friday - { day_number = 6, rotation_type = "FPTP" }, # Saturday - { day_number = 7, rotation_type = "FPTP" }, # Sunday + {day_number = 1, rotation_type = "Vote"}, # Monday + {day_number = 2, rotation_type = "Random"}, # Tuesday + {day_number = 3, rotation_type = "FPTP"}, # Wednesday + {day_number = 4, rotation_type = "Random"}, # Thursday + {day_number = 5, rotation_type = "Vote"}, # Friday + {day_number = 6, rotation_type = "FPTP"}, # Saturday + {day_number = 7, rotation_type = "FPTP"}, # Sunday ] ################################################################ From 52c7836884280830d440ecde236a251ee88dec99 Mon Sep 17 00:00:00 2001 From: Spaghetti-Bit Date: Thu, 14 Nov 2024 23:40:05 -0700 Subject: [PATCH 11/22] The real 61-62 --- code/__DEFINES/misc_defines.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/__DEFINES/misc_defines.dm b/code/__DEFINES/misc_defines.dm index ebcf72a653d95..be4fbdfa52423 100644 --- a/code/__DEFINES/misc_defines.dm +++ b/code/__DEFINES/misc_defines.dm @@ -423,7 +423,7 @@ #define INVESTIGATE_HOTMIC "hotmic" // The SQL version required by this version of the code -#define SQL_VERSION 61 +#define SQL_VERSION 62 // Vending machine stuff #define CAT_NORMAL (1<<0) From d2b19717a6deb2259e6c81e2c59638e9fd341e6c Mon Sep 17 00:00:00 2001 From: Spaghetti-Bit Date: Fri, 15 Nov 2024 17:55:40 -0700 Subject: [PATCH 12/22] Update to IPC imitation --- .../living/carbon/human/species/machine.dm | 72 +++++++++---------- 1 file changed, 33 insertions(+), 39 deletions(-) diff --git a/code/modules/mob/living/carbon/human/species/machine.dm b/code/modules/mob/living/carbon/human/species/machine.dm index df5406ffd2a02..8221442c51a42 100644 --- a/code/modules/mob/living/carbon/human/species/machine.dm +++ b/code/modules/mob/living/carbon/human/species/machine.dm @@ -78,55 +78,49 @@ 1 = "None", 2 = "Vox", 3 = "Unathi", - 4 = "Nian" + 4 = "Tajaran", + 5 = "Nian", + 6 = "Vulpkanin", + 7 = "Kidan", + 8 = "Grey", + 9 = "Drask" ) -/datum/species/machine/updatespeciessubtype(mob/living/carbon/human/H, owner_sensitive = 1) //Handling species-subtype and imitation + var/static_bodyflags = HAS_SKIN_COLOR | HAS_HEAD_MARKINGS | HAS_HEAD_ACCESSORY | ALL_RPARTS | SHAVED | HAS_SPECIES_SUBTYPE + +/datum/species/slime/updatespeciessubtype(mob/living/carbon/human/H, owner_sensitive = 1) //Handling species-subtype and imitation if(H.dna.species.bodyflags & HAS_SPECIES_SUBTYPE) - var/new_icobase = 'icons/mob/human_races/r_machine.dmi' //Default IPC. + var/new_icobase = 'icons/mob/human_races/r_machine.dmi' //Default IPC person. if(H.species_subtype == species_subtype) // No update, no need to go further. return - switch(H.species_subtype) - if("Nian") - new_icobase = 'icons/mob/human_races/nian/r_moth.dmi' - species_subtype = "Nian" - tail = null - wing = "plain" - bodyflags |= (HAS_HEAD_ACCESSORY | HAS_WING) - H.body_accessory = null - if("Unathi") // Unathi - new_icobase = 'icons/mob/human_races/r_lizard.dmi' - species_subtype = "Unathi" - tail = "sogtail" - wing = null - bodyflags |= (HAS_HEAD_ACCESSORY | HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED) - H.body_accessory = null - if("Vox") // Vox :) - new_icobase = 'icons/mob/human_races/vox/r_voxgry.dmi' - tail = "voxtail_gry" - wing = null - species_subtype = "Vox" - bodyflags |= (HAS_TAIL | TAIL_WAGGING | TAIL_OVERLAPPED) - H.body_accessory = null - if("None") // Regular IPC - // Reset - new_icobase = initial(icobase) - species_subtype = "None" - tail = initial(tail) - eyes = initial(eyes) - wing = initial(wing) - bodyflags = initial(bodyflags) - H.body_accessory = null - if(species_subtype != "None") + species_subtype = H.species_subtype // Update our species subtype to match the Mob's subtype. + + var/datum/species/s = GLOB.all_species[species_subtype] + if(isnull(s)) + s = GLOB.all_species[name] // Reset species fully to IPC again. + + // Copy over new species variables to our current species. + new_icobase = s.icobase + tail = s.tail + wing = s.wing + default_headacc = s.default_headacc + default_bodyacc = s.default_bodyacc + bodyflags = s.bodyflags + if(species_subtype != "None") // Update our species display and reference to match the subtype. Used for species specific clothing and accessories. sprite_sheet_name = species_subtype + bodyflags |= static_bodyflags else - sprite_sheet_name = name - for(var/obj/item/organ/external/limb in H.bodyparts) // Update robotic limbs to match new sub species ico base - limb.set_company(limb.model, sprite_sheet_name) + sprite_sheet_name = name // Resets sprite sheet back to IPC. - // Update misc parts that are stored as reference in species and used on the mob. Also resets stylings to none to prevent anything wacky... + H.body_accessory = GLOB.body_accessory_by_name[default_bodyacc] H.tail = tail H.wing = wing + for(var/obj/item/organ/external/limb in H.bodyparts) // Update robotic limbs to match new sub species ico base in the case they have robotic limbs + limb.icobase = s.icobase // update their icobase for when we apply the slimfy effect + limb.dna.species = src // Update limb to match our newly modified species + limb.set_company(limb.model, sprite_sheet_name) + + // Update misc parts that are stored as reference in species and used on the mob. Also resets stylings to none to prevent anything wacky... var/obj/item/organ/external/head/head = H.get_organ("head") head.h_style = "Bald" From bec00d18e814846ca1f1aae37ca300a456ab7292 Mon Sep 17 00:00:00 2001 From: Spaghetti-bit Date: Thu, 30 Jan 2025 04:30:20 -0700 Subject: [PATCH 13/22] +63-64.sql > species_subtype after pda_ringtone IPC identity configuration surgery. Slime "Morph" action: 10 seconds. Allows a slime person to change how they look. > Same cost as regenerating a limb. Link processing subspecies implement. --- SQL/updates/63-64.sql | 7 +- code/modules/client/preference/character.dm | 95 +++++----- .../client/preference/link_processing.dm | 173 ++++++++++-------- .../living/carbon/human/human_update_icons.dm | 7 +- .../living/carbon/human/species/_species.dm | 10 +- .../living/carbon/human/species/machine.dm | 78 ++++---- .../carbon/human/species/slimepeople.dm | 117 ++++++------ code/modules/surgery/robotics.dm | 8 +- 8 files changed, 268 insertions(+), 227 deletions(-) diff --git a/SQL/updates/63-64.sql b/SQL/updates/63-64.sql index 312563ee9b150..410d6577ad12c 100644 --- a/SQL/updates/63-64.sql +++ b/SQL/updates/63-64.sql @@ -1,6 +1,5 @@ -# Updates the DB from 61 to 62 ~SpaghettiBit +# Updates the DB from 63 to 64 ~SpaghettiBit # Adds a subtype race to be stored on character saves - -# Add species_subtype after species +# Add species_subtype after pda_ringtone ALTER TABLE `characters` - ADD COLUMN `species_subtype` VARCHAR(7) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'None' AFTER `species`; + ADD COLUMN `species_subtype` VARCHAR(7) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'None' AFTER `pda_ringtone`; diff --git a/code/modules/client/preference/character.dm b/code/modules/client/preference/character.dm index 78b8d6143638f..575794b028753 100644 --- a/code/modules/client/preference/character.dm +++ b/code/modules/client/preference/character.dm @@ -837,76 +837,65 @@ //Icon-based species colour. var/coloured_tail if(current_species) - if(species_subtype != "None" && current_species.bodyflags & HAS_SPECIES_SUBTYPE && istype(current_species, /datum/species/slime)) - var/datum/species/subtype_species = GLOB.all_species[species_subtype] - if(subtype_species) - current_species.sprite_sheet_name = subtype_species.sprite_sheet_name - current_species.icobase = subtype_species.icobase - current_species.tail = subtype_species.tail - current_species.wing = subtype_species.wing - current_species.eyes = subtype_species.eyes - current_species.scream_verb = subtype_species.scream_verb - current_species.male_scream_sound = subtype_species.male_scream_sound - current_species.female_scream_sound = subtype_species.female_scream_sound - current_species.default_headacc = subtype_species.default_headacc - current_species.default_bodyacc = subtype_species.default_bodyacc - current_species.male_cough_sounds = subtype_species.male_cough_sounds - current_species.female_cough_sounds = subtype_species.female_cough_sounds - current_species.male_sneeze_sound = subtype_species.male_sneeze_sound - current_species.female_sneeze_sound = subtype_species.female_sneeze_sound - current_species.bodyflags = subtype_species.bodyflags - current_species.bodyflags |= HAS_SKIN_COLOR | NO_EYES | HAS_SPECIES_SUBTYPE - var/mob/living/carbon/human/H = new + var/mob/living/carbon/human/fake/H = new H.dna.species = current_species - if(current_species.bodyflags & HAS_SPECIES_SUBTYPE) - H.dna.species.updatespeciessubtype(H) - icobase = H.dna.species.icobase + if(species_subtype != "None" && current_species.bodyflags & HAS_SPECIES_SUBTYPE) + var/datum/species/subtype_species = GLOB.all_species[species_subtype] + if(subtype_species) // Take certain attributes from our subtype to apply to our current species. + H.dna.species.updatespeciessubtype(H, subtype_species) + current_species = H.dna.species else if(current_species.bodyflags & HAS_ICON_SKIN_TONE) //Handling species-specific icon-based skin tones by flagged race. - var/mob/living/carbon/human/fake/H = new - H.dna.species = current_species H.s_tone = s_tone H.dna.species.updatespeciescolor(H, 0) //The mob's species wasn't set, so it's almost certainly different than the character's species at the moment. Thus, we need to be owner-insensitive. - var/obj/item/organ/external/chest/C = H.get_organ("chest") - icobase = C.icobase ? C.icobase : C.dna.species.icobase if(H.dna.species.bodyflags & HAS_TAIL) coloured_tail = H.tail ? H.tail : H.dna.species.tail - else - icobase = current_species.icobase + icobase = current_species.icobase qdel(H) else icobase = 'icons/mob/human_races/r_human.dmi' preview_icon = new /icon(icobase, "torso_[g]") preview_icon.Blend(new /icon(icobase, "groin_[g]"), ICON_OVERLAY) - var/head = "head" - if(alt_head && current_species.bodyflags & HAS_ALT_HEADS) - var/datum/sprite_accessory/alt_heads/H = GLOB.alt_heads_list[alt_head] - if(H.icon_state) - head = H.icon_state - preview_icon.Blend(new /icon(icobase, "[head]_[g]"), ICON_OVERLAY) - for(var/name in list("chest", "groin", "head", "r_arm", "r_hand", "r_leg", "r_foot", "l_leg", "l_foot", "l_arm", "l_hand")) - if(organ_data[name] == "amputated") continue - if(organ_data[name] == "cyborg") + if(organ_data[name] == "amputated") + continue + var/icon/bodypart = new /icon(icobase, "[name]") + if(name == "head") // Head nonsense. + var/head = "head" + if(alt_head && current_species.bodyflags & HAS_ALT_HEADS) + var/datum/sprite_accessory/alt_heads/H = GLOB.alt_heads_list[alt_head] + if(H.icon_state) + head = H.icon_state + bodypart = new /icon(icobase, "[head]_[g]") // head_state _ gender + if(name in list("chest", "groin")) // Groin and Chest nonsense + if(name == "chest") + name = "torso" + bodypart = new /icon(icobase, "[name]_[g]") // groin/torso _ gender + if(organ_data[name] == "cyborg") // Robotic limbs. var/datum/robolimb/R if(rlimb_data[name]) R = GLOB.all_robolimbs[rlimb_data[name]] if(!R) R = GLOB.basic_robolimb if(name == "chest") name = "torso" - preview_icon.Blend(icon(R.icon, "[name]"), ICON_OVERLAY) // This doesn't check gendered_icon. Not an issue while only limbs can be robotic. + if(length(R.sprite_sheets) && R.sprite_sheets[current_species.sprite_sheet_name]) // Species specific augmented limbs + R.icon = R.sprite_sheets[current_species.sprite_sheet_name] + bodypart.Blend(new /icon(R.icon, "[name]"), ICON_OVERLAY) + preview_icon.Blend(bodypart, ICON_OVERLAY) continue - preview_icon.Blend(new /icon(icobase, "[name]"), ICON_OVERLAY) - - // Skin color - if(current_species && (current_species.bodyflags & HAS_SKIN_COLOR)) - preview_icon.Blend(s_colour, ICON_ADD) - - // Skin tone - if(current_species && (current_species.bodyflags & HAS_SKIN_TONE)) - if(s_tone >= 0) - preview_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD) + if(istype(current_species, /datum/species/slime) && current_species.species_subtype != "None") // Applies to limbs that are not robotic. + bodypart.GrayScale() + bodypart.Blend("[s_colour]DC", ICON_AND) //DC = 220 alpha. else - preview_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT) + // Skin color + if(current_species && (current_species.bodyflags & HAS_SKIN_COLOR)) + bodypart.Blend(s_colour, ICON_ADD) + // Skin tone + if(current_species && (current_species.bodyflags & HAS_SKIN_TONE)) + if(s_tone >= 0) + bodypart.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD) + else + bodypart.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT) + preview_icon.Blend(bodypart, ICON_OVERLAY) // Body accessory if(current_species && (current_species.bodyflags & HAS_BODY_ACCESSORY)) @@ -1861,7 +1850,11 @@ /datum/character_save/proc/copy_to(mob/living/carbon/human/character) var/datum/species/S = GLOB.all_species[species] character.set_species(S.type, delay_icon_update = TRUE) // Yell at me if this causes everything to melt - character.species_subtype = species_subtype + var/datum/species/subtype = GLOB.all_species[species_subtype] + if(!isnull(subtype)) + character.dna.species.updatespeciessubtype(character, new subtype.type(), TRUE, FALSE) + else + character.species_subtype = "None" if(be_random_name) real_name = random_name(gender, species) diff --git a/code/modules/client/preference/link_processing.dm b/code/modules/client/preference/link_processing.dm index 6beb432da10f0..c0b256e6601ba 100644 --- a/code/modules/client/preference/link_processing.dm +++ b/code/modules/client/preference/link_processing.dm @@ -3,6 +3,11 @@ return var/datum/species/S = GLOB.all_species[active_character.species] + var/datum/species/subtype = GLOB.all_species[active_character.species_subtype] + if(isnull(subtype)) // Set the subtype to be the same as Species in the case we don't have one, saves alot of headaches when we're checking for valid markings etc. + subtype = S + else + S.bodyflags |= subtype.bodyflags if(href_list["preference"] == "job") switch(href_list["task"]) if("close") @@ -197,79 +202,20 @@ to_chat(user, "Invalid species, please pick something else.") return if(prev_species != active_character.species) - active_character.age = clamp(active_character.age, NS.min_age, NS.max_age) - var/datum/robolimb/robohead - if(NS.bodyflags & ALL_RPARTS) - var/head_model = "[!active_character.rlimb_data["head"] ? "Morpheus Cyberkinetics" : active_character.rlimb_data["head"]]" - robohead = GLOB.all_robolimbs[head_model] - //grab one of the valid hair styles for the newly chosen species - active_character.h_style = random_hair_style(active_character.gender, active_character.species, robohead) - - //grab one of the valid facial hair styles for the newly chosen species - active_character.f_style = random_facial_hair_style(active_character.gender, active_character.species, robohead) - - if(NS.bodyflags & HAS_HEAD_ACCESSORY) //Species that have head accessories. - active_character.ha_style = random_head_accessory(active_character.species) - else - active_character.ha_style = "None" // No Vulp ears on Unathi - active_character.hacc_colour = rand_hex_color() - - if(NS.bodyflags & HAS_HEAD_MARKINGS) //Species with head markings. - active_character.m_styles["head"] = random_marking_style("head", active_character.species, robohead, null, active_character.alt_head) - else - active_character.m_styles["head"] = "None" - active_character.m_colours["head"] = "#000000" - - if(NS.bodyflags & HAS_BODY_MARKINGS) //Species with body markings/tattoos. - active_character.m_styles["body"] = random_marking_style("body", active_character.species) - else - active_character.m_styles["body"] = "None" - active_character.m_colours["body"] = "#000000" - - if(NS.bodyflags & HAS_TAIL_MARKINGS) //Species with tail markings. - active_character.m_styles["tail"] = random_marking_style("tail", active_character.species, null, active_character.body_accessory) - else - active_character.m_styles["tail"] = "None" - active_character.m_colours["tail"] = "#000000" - - // Don't wear another species' underwear! - var/datum/sprite_accessory/SA = GLOB.underwear_list[active_character.underwear] - if(!SA || !(active_character.species in SA.species_allowed)) - active_character.underwear = random_underwear(active_character.body_type, active_character.species) - - SA = GLOB.undershirt_list[active_character.undershirt] - if(!SA || !(active_character.species in SA.species_allowed)) - active_character.undershirt = random_undershirt(active_character.body_type, active_character.species) - - SA = GLOB.socks_list[active_character.socks] - if(!SA || !(active_character.species in SA.species_allowed)) - active_character.socks = random_socks(active_character.body_type, active_character.species) - - //reset skin tone and colour - if(NS.bodyflags & (HAS_SKIN_TONE|HAS_ICON_SKIN_TONE)) - random_skin_tone(active_character.species) - else - active_character.s_tone = 0 - - if(!(NS.bodyflags & HAS_SKIN_COLOR)) - active_character.s_colour = "#000000" - - active_character.alt_head = "None" //No alt heads on species that don't have them. - active_character.speciesprefs = 0 //My Vox tank shouldn't change how my future Grey talks. - active_character.body_accessory = random_body_accessory(NS.name, NS.optional_body_accessory) - - //Reset prosthetics. - active_character.organ_data = list() - active_character.rlimb_data = list() - - if(!(NS.autohiss_basic_map)) - active_character.autohiss_mode = AUTOHISS_OFF + S = NS + active_character.age = clamp(active_character.age, S.min_age, S.max_age) + reset_styles(S) if("species_subtype") if(S.bodyflags & HAS_SPECIES_SUBTYPE) var/new_subtype = tgui_input_list(user, "Choose your character's species subtype:", "Character Preference", S.allowed_species_subtypes) - if(isnull(new_subtype)) + if(isnull(new_subtype) || active_character.species_subtype == new_subtype) return active_character.species_subtype = new_subtype + var/datum/species/NS = GLOB.all_species[active_character.species_subtype] + if(isnull(NS)) + NS = GLOB.all_species[active_character.species] + subtype = NS + reset_styles(subtype, S) if("speciesprefs") active_character.speciesprefs = !active_character.speciesprefs //Starts 0, so if someone clicks the button up top there, this won't be 0 anymore. If they click it again, it'll go back to 0. if("language") @@ -341,7 +287,7 @@ But if the user has a robotic humanoid head and the hairstyle can fit humans, let them use it as a wig. */ valid_hairstyles += hairstyle else //If the user is not a species who can have robotic heads, use the default handling. - if(active_character.species in SA.species_allowed) //If the user's head is of a species the hairstyle allows, add it to the list. + if((active_character.species in SA.species_allowed) || (subtype.name in SA.species_allowed)) //If the user's head is of a species the hairstyle allows, add it to the list. valid_hairstyles += hairstyle sortTim(valid_hairstyles, GLOBAL_PROC_REF(cmp_text_asc)) //this alphabetizes the list @@ -393,7 +339,7 @@ var/list/valid_head_accessory_styles = list() for(var/head_accessory_style in GLOB.head_accessory_styles_list) var/datum/sprite_accessory/H = GLOB.head_accessory_styles_list[head_accessory_style] - if(!(active_character.species in H.species_allowed)) + if(!(active_character.species in H.species_allowed) && !(subtype.name in H.species_allowed)) continue valid_head_accessory_styles += head_accessory_style @@ -410,7 +356,7 @@ var/list/valid_alt_heads = list() for(var/alternate_head in GLOB.alt_heads_list) var/datum/sprite_accessory/alt_heads/head = GLOB.alt_heads_list[alternate_head] - if(!(active_character.species in head.species_allowed)) + if(!(active_character.species in head.species_allowed) && !(subtype.name in head.species_allowed)) continue valid_alt_heads += alternate_head @@ -429,7 +375,7 @@ var/list/valid_markings = list() for(var/markingstyle in GLOB.marking_styles_list) var/datum/sprite_accessory/body_markings/head/M = GLOB.marking_styles_list[markingstyle] - if(!(active_character.species in M.species_allowed)) + if(!(active_character.species in M.species_allowed) && !(subtype.name in M.species_allowed)) continue if(M.marking_location != "head") continue @@ -474,7 +420,7 @@ var/list/valid_markings = list() for(var/markingstyle in GLOB.marking_styles_list) var/datum/sprite_accessory/M = GLOB.marking_styles_list[markingstyle] - if(!(active_character.species in M.species_allowed)) + if(!(active_character.species in M.species_allowed) && !(subtype.name in M.species_allowed)) continue if(M.marking_location != "body") continue @@ -499,7 +445,7 @@ var/datum/sprite_accessory/body_markings/tail/M = GLOB.marking_styles_list[markingstyle] if(M.marking_location != "tail") continue - if(!(active_character.species in M.species_allowed)) + if(!(active_character.species in M.species_allowed) && !(subtype.name in M.species_allowed)) continue if(!active_character.body_accessory) if(M.tails_allowed) @@ -530,7 +476,7 @@ var/datum/body_accessory/accessory = GLOB.body_accessory_by_name[B] if(isnull(accessory)) // None continue - if(active_character.species in accessory.allowed_species) + if(active_character.species in accessory.allowed_species || subtype.name in accessory.allowed_species) possible_body_accessories += B if(S.optional_body_accessory) possible_body_accessories += "None" //the only null entry should be the "None" option @@ -596,7 +542,7 @@ continue if(active_character.body_type == FEMALE && SA.body_type == MALE) continue - if(!(active_character.species in SA.species_allowed)) + if(!(active_character.species in SA.species_allowed) && !(subtype.name in SA.species_allowed)) continue valid_underwear[underwear] = GLOB.underwear_list[underwear] sortTim(valid_underwear, GLOBAL_PROC_REF(cmp_text_asc)) @@ -608,7 +554,7 @@ var/list/valid_undershirts = list() for(var/undershirt in GLOB.undershirt_list) var/datum/sprite_accessory/SA = GLOB.undershirt_list[undershirt] - if(!(active_character.species in SA.species_allowed)) + if(!(active_character.species in SA.species_allowed) && !(subtype.name in SA.species_allowed)) continue if(active_character.body_type == MALE && SA.body_type == FEMALE) continue @@ -625,7 +571,7 @@ var/list/valid_sockstyles = list() for(var/sockstyle in GLOB.socks_list) var/datum/sprite_accessory/SA = GLOB.socks_list[sockstyle] - if(!(active_character.species in SA.species_allowed)) + if(!(active_character.species in SA.species_allowed) && !(subtype.name in SA.species_allowed)) continue if(active_character.body_type == MALE && SA.body_type == FEMALE) continue @@ -1313,3 +1259,74 @@ ShowChoices(user) return TRUE + +/// Reset the styles what is available to the NS (new species) parameter. Parent Species is for subtype changing. +/datum/preferences/proc/reset_styles(datum/species/NS, datum/species/parent_species) + var/datum/robolimb/robohead + if(!isnull(parent_species)) + NS.bodyflags |= parent_species.bodyflags + if(NS.bodyflags & ALL_RPARTS) + var/head_model = "[!active_character.rlimb_data["head"] ? "Morpheus Cyberkinetics" : active_character.rlimb_data["head"]]" + robohead = GLOB.all_robolimbs[head_model] + //grab one of the valid hair styles for the newly chosen species + active_character.h_style = random_hair_style(active_character.gender, NS, robohead) + + //grab one of the valid facial hair styles for the newly chosen species + active_character.f_style = random_facial_hair_style(active_character.gender, NS, robohead) + + if(NS.bodyflags & HAS_HEAD_ACCESSORY) //Species that have head accessories. + active_character.ha_style = random_head_accessory(NS) + else + active_character.ha_style = "None" // No Vulp ears on Unathi + active_character.hacc_colour = rand_hex_color() + + if(NS.bodyflags & HAS_HEAD_MARKINGS) //Species with head markings. + active_character.m_styles["head"] = random_marking_style("head", NS, robohead, null, active_character.alt_head) + else + active_character.m_styles["head"] = "None" + active_character.m_colours["head"] = "#000000" + + if(NS.bodyflags & HAS_BODY_MARKINGS) //Species with body markings/tattoos. + active_character.m_styles["body"] = random_marking_style("body", NS) + else + active_character.m_styles["body"] = "None" + active_character.m_colours["body"] = "#000000" + + if(NS.bodyflags & HAS_TAIL_MARKINGS) //Species with tail markings. + active_character.m_styles["tail"] = random_marking_style("tail", NS, null, active_character.body_accessory) + else + active_character.m_styles["tail"] = "None" + active_character.m_colours["tail"] = "#000000" + + // Don't wear another species' underwear! + var/datum/sprite_accessory/SA = GLOB.underwear_list[active_character.underwear] + if(!SA || !(NS in SA.species_allowed)) + active_character.underwear = random_underwear(active_character.body_type, NS) + + SA = GLOB.undershirt_list[active_character.undershirt] + if(!SA || !(NS in SA.species_allowed)) + active_character.undershirt = random_undershirt(active_character.body_type, NS) + + SA = GLOB.socks_list[active_character.socks] + if(!SA || !(NS in SA.species_allowed)) + active_character.socks = random_socks(active_character.body_type, NS) + + //reset skin tone and colour + if(NS.bodyflags & (HAS_SKIN_TONE|HAS_ICON_SKIN_TONE)) + random_skin_tone(NS) + else + active_character.s_tone = 0 + + if(!(NS.bodyflags & HAS_SKIN_COLOR)) + active_character.s_colour = "#000000" + + active_character.alt_head = "None" //No alt heads on species that don't have them. + active_character.speciesprefs = 0 //My Vox tank shouldn't change how my future Grey talks. + active_character.body_accessory = random_body_accessory(NS.name, NS.optional_body_accessory) + + //Reset prosthetics. + active_character.organ_data = list() + active_character.rlimb_data = list() + + if(!(NS.autohiss_basic_map)) + active_character.autohiss_mode = AUTOHISS_OFF 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 9cbefe064dd8d..118b1dddeadbe 100644 --- a/code/modules/mob/living/carbon/human/human_update_icons.dm +++ b/code/modules/mob/living/carbon/human/human_update_icons.dm @@ -176,8 +176,11 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) if(dna.species.bodyflags & HAS_ICON_SKIN_TONE) dna.species.updatespeciescolor(src) if(dna.species.bodyflags & HAS_SPECIES_SUBTYPE) - dna.species.updatespeciessubtype(src) - + var/datum/species/species_subtype = GLOB.all_species[dna.species.species_subtype] + if(isnull(species_subtype)) + species_subtype = GLOB.all_species[dna.species.name] + if(dna.species.species_subtype != "None" && dna.species.species_subtype != species_subtype.name) + dna.species.updatespeciessubtype(src, new species_subtype.type(), TRUE, FALSE) //CACHING: Generate an index key from visible bodyparts. //0 = destroyed, 1 = normal, 2 = robotic, 3 = necrotic. //Create a new, blank icon for our mob to use. diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm index e084e5ac7817e..ca9a81f715f8e 100644 --- a/code/modules/mob/living/carbon/human/species/_species.dm +++ b/code/modules/mob/living/carbon/human/species/_species.dm @@ -410,7 +410,15 @@ /datum/species/proc/updatespeciescolor(mob/living/carbon/human/H) //Handles changing icobase for species that have multiple skin colors. return -/datum/species/proc/updatespeciessubtype(mob/living/carbon/human/H) // Handles changing icobase for species that can imitate/morph into other species +/** Handles changing icobase for species that can imitate/morph into other species + * Arguments: + * - H: The human of which was are updating. + * - new_subtype: Our imitate species, by datum reference. + * - owner_sensitive: Always leave at TRUE, this is for updating our icon. (change_icobase) + * - reset_styles: If true, resets styles, hair, and other appearance styles. + */ +/// +/datum/species/proc/updatespeciessubtype(mob/living/carbon/human/H, datum/species/new_subtype, owner_sensitive = TRUE, reset_styles = TRUE) return // Do species-specific reagent handling here diff --git a/code/modules/mob/living/carbon/human/species/machine.dm b/code/modules/mob/living/carbon/human/species/machine.dm index 887a58eb3a374..882562ed304bf 100644 --- a/code/modules/mob/living/carbon/human/species/machine.dm +++ b/code/modules/mob/living/carbon/human/species/machine.dm @@ -89,48 +89,52 @@ var/static_bodyflags = HAS_SKIN_COLOR | HAS_HEAD_MARKINGS | HAS_HEAD_ACCESSORY | ALL_RPARTS | SHAVED | HAS_SPECIES_SUBTYPE -/datum/species/slime/updatespeciessubtype(mob/living/carbon/human/H, owner_sensitive = 1) //Handling species-subtype and imitation +/datum/species/machine/updatespeciessubtype(mob/living/carbon/human/H, datum/species/new_subtype, owner_sensitive = TRUE, reset_styles = TRUE) //Handling species-subtype and imitation if(H.dna.species.bodyflags & HAS_SPECIES_SUBTYPE) - var/new_icobase = 'icons/mob/human_races/r_machine.dmi' //Default IPC person. - if(H.species_subtype == species_subtype) // No update, no need to go further. - return - species_subtype = H.species_subtype // Update our species subtype to match the Mob's subtype. - - var/datum/species/s = GLOB.all_species[species_subtype] - if(isnull(s)) - s = GLOB.all_species[name] // Reset species fully to IPC again. - - // Copy over new species variables to our current species. - new_icobase = s.icobase - tail = s.tail - wing = s.wing - default_headacc = s.default_headacc - default_bodyacc = s.default_bodyacc - bodyflags = s.bodyflags - if(species_subtype != "None") // Update our species display and reference to match the subtype. Used for species specific clothing and accessories. - sprite_sheet_name = species_subtype - bodyflags |= static_bodyflags + var/datum/species/temp_species = new type() + if(isnull(new_subtype) || temp_species.name == new_subtype.name) // Back to our original species. + H.species_subtype = "None" + temp_species.species_subtype = "None" // Update our species subtype to match the Mob's subtype. + var/datum/species/S = GLOB.all_species[temp_species.name] + new_subtype = new S.type() // Resets back to original. We use initial in the case the datum is var edited. else - sprite_sheet_name = name // Resets sprite sheet back to IPC. - - H.body_accessory = GLOB.body_accessory_by_name[default_bodyacc] - H.tail = tail - H.wing = wing - for(var/obj/item/organ/external/limb in H.bodyparts) // Update robotic limbs to match new sub species ico base in the case they have robotic limbs - limb.icobase = s.icobase // update their icobase for when we apply the slimfy effect - limb.dna.species = src // Update limb to match our newly modified species - limb.set_company(limb.model, sprite_sheet_name) + H.species_subtype = new_subtype.name + temp_species.species_subtype = H.species_subtype // Update our species subtype to match the Mob's subtype. + + // Copy over new species variables to our temp holder. + temp_species.icobase = new_subtype.icobase + temp_species.tail = new_subtype.tail + temp_species.wing = new_subtype.wing + temp_species.default_headacc = new_subtype.default_headacc + temp_species.default_bodyacc = new_subtype.default_bodyacc + temp_species.bodyflags = new_subtype.bodyflags + temp_species.bodyflags |= static_bodyflags // Add our static bodyflags that slime must always have. + temp_species.sprite_sheet_name = new_subtype.sprite_sheet_name + temp_species.icon_template = new_subtype.icon_template + // Set our DNA to the temp holder. + H.dna.species = temp_species + + for(var/obj/item/organ/external/limb in H.bodyparts) + if(istype(limb.dna.species, src)) // Only update the limb that is part of our original species + limb.icobase = temp_species.icobase // update their icobase for when we apply the slimfy effect + limb.dna.species = temp_species // Update limb to match our newly modified species + limb.set_company(limb.model, temp_species.sprite_sheet_name) // Robotic limbs always update to our new subtype. // Update misc parts that are stored as reference in species and used on the mob. Also resets stylings to none to prevent anything wacky... - var/obj/item/organ/external/head/head = H.get_organ("head") - head.h_style = "Bald" - head.f_style = "Shaved" - head.ha_style = "None" - H.s_tone = 0 - H.m_styles = DEFAULT_MARKING_STYLES //Wipes out markings, setting them all to "None". - H.m_colours = DEFAULT_MARKING_COLOURS //Defaults colour to #00000 for all markings. - H.change_icobase(new_icobase, owner_sensitive) //Update the icobase of all our organs, but make sure we don't mess with frankenstein limbs in doing so. + if(reset_styles) + H.body_accessory = GLOB.body_accessory_by_name[temp_species.default_bodyacc] + H.tail = temp_species.tail + H.wing = temp_species.wing + var/obj/item/organ/external/head/head = H.get_organ("head") + head.h_style = "Bald" + head.f_style = "Shaved" + head.ha_style = "None" + H.s_tone = 0 + H.m_styles = DEFAULT_MARKING_STYLES //Wipes out markings, setting them all to "None". + H.m_colours = DEFAULT_MARKING_COLOURS //Defaults colour to #00000 for all markings. + H.change_head_accessory(GLOB.head_accessory_styles_list[temp_species.default_headacc]) + H.change_icobase(temp_species.icobase, owner_sensitive) //Update the icobase of all our organs, but make sure we don't mess with frankenstein limbs in doing so. /datum/species/machine/on_species_gain(mob/living/carbon/human/H) ..() var/datum/action/innate/change_monitor/monitor = new() diff --git a/code/modules/mob/living/carbon/human/species/slimepeople.dm b/code/modules/mob/living/carbon/human/species/slimepeople.dm index dbc357f338b39..465913cc5c8c1 100644 --- a/code/modules/mob/living/carbon/human/species/slimepeople.dm +++ b/code/modules/mob/living/carbon/human/species/slimepeople.dm @@ -6,6 +6,8 @@ #define SLIMEPERSON_MINHUNGER 250 #define SLIMEPERSON_REGROWTHDELAY 450 // 45 seconds +#define SLIMEPERSON_MORPH_FORM 10 SECONDS + /datum/species/slime name = "Slime People" name_plural = "Slime People" @@ -97,56 +99,59 @@ i.Remove(H) UnregisterSignal(H, COMSIG_HUMAN_UPDATE_DNA) -/datum/species/slime/updatespeciessubtype(mob/living/carbon/human/H, owner_sensitive = 1) //Handling species-subtype and imitation +/datum/species/slime/updatespeciessubtype(mob/living/carbon/human/H, datum/species/new_subtype, owner_sensitive = TRUE, reset_styles = TRUE) //Handling species-subtype and imitation if(H.dna.species.bodyflags & HAS_SPECIES_SUBTYPE) - var/new_icobase = 'icons/mob/human_races/r_slime.dmi' //Default slime person. - if(H.species_subtype == species_subtype) // No update, no need to go further. - return - species_subtype = H.species_subtype // Update our species subtype to match the Mob's subtype. - - var/datum/species/s = GLOB.all_species[species_subtype] - if(isnull(s)) - s = GLOB.all_species[name] // Reset species fully to slime person again. - - // Copy over new species variables to our current species. - new_icobase = s.icobase - tail = s.tail - wing = s.wing - eyes = s.eyes - scream_verb = s.scream_verb - male_scream_sound = s.male_scream_sound - female_scream_sound = s.female_scream_sound - default_headacc = s.default_headacc - default_bodyacc = s.default_bodyacc - male_cough_sounds = s.male_cough_sounds - female_cough_sounds = s.female_cough_sounds - male_sneeze_sound = s.male_sneeze_sound - female_sneeze_sound = s.female_sneeze_sound - bodyflags = s.bodyflags - if(species_subtype != "None") // Update our species display and reference name to match the subtype. Used for species specific clothing and accessories. - sprite_sheet_name = species_subtype - bodyflags |= static_bodyflags + var/datum/species/temp_species = new type() + if(isnull(new_subtype) || temp_species.name == new_subtype.name) // Back to our original species. + H.species_subtype = "None" + temp_species.species_subtype = "None" // Update our species subtype to match the Mob's subtype. + var/datum/species/S = GLOB.all_species[temp_species.name] + new_subtype = new S.type() // Resets back to original. We use initial in the case the datum is var edited. else - sprite_sheet_name = name // Resets sprite sheet back to slime people. + H.species_subtype = new_subtype.name + temp_species.species_subtype = H.species_subtype // Update our species subtype to match the Mob's subtype. - H.body_accessory = GLOB.body_accessory_by_name[default_bodyacc] - H.tail = tail - H.wing = wing - for(var/obj/item/organ/external/limb in H.bodyparts) // Update robotic limbs to match new sub species ico base in the case they have robotic limbs - limb.icobase = s.icobase // update their icobase for when we apply the slimfy effect - limb.dna.species = src // Update limb to match our newly modified species - limb.set_company(limb.model, sprite_sheet_name) + // Copy over new species variables to our current species. + temp_species.icobase = new_subtype.icobase + temp_species.tail = new_subtype.tail + temp_species.wing = new_subtype.wing + temp_species.eyes = new_subtype.eyes + temp_species.scream_verb = new_subtype.scream_verb + temp_species.male_scream_sound = new_subtype.male_scream_sound + temp_species.female_scream_sound = new_subtype.female_scream_sound + temp_species.default_headacc = new_subtype.default_headacc + temp_species.default_bodyacc = new_subtype.default_bodyacc + temp_species.male_cough_sounds = new_subtype.male_cough_sounds + temp_species.female_cough_sounds = new_subtype.female_cough_sounds + temp_species.male_sneeze_sound = new_subtype.male_sneeze_sound + temp_species.female_sneeze_sound = new_subtype.female_sneeze_sound + temp_species.bodyflags = new_subtype.bodyflags + temp_species.bodyflags |= static_bodyflags // Add our static bodyflags that slime must always have. + temp_species.sprite_sheet_name = new_subtype.sprite_sheet_name + temp_species.icon_template = new_subtype.icon_template + H.dna.species = temp_species + + for(var/obj/item/organ/external/limb in H.bodyparts) + if(istype(limb.dna.species, src)) // Only update the limb that is part of our original species + limb.icobase = temp_species.icobase // update their icobase for when we apply the slimfy effect + limb.dna.species = temp_species // Update limb to match our newly modified species + limb.set_company(limb.model, temp_species.sprite_sheet_name) // Robotic limbs always update to our new subtype. // Update misc parts that are stored as reference in species and used on the mob. Also resets stylings to none to prevent anything wacky... - var/obj/item/organ/external/head/head = H.get_organ("head") - head.h_style = "Bald" - head.f_style = "Shaved" - head.ha_style = "None" - H.s_tone = 0 - H.m_styles = DEFAULT_MARKING_STYLES //Wipes out markings, setting them all to "None". - H.m_colours = DEFAULT_MARKING_COLOURS //Defaults colour to #00000 for all markings. - H.change_icobase(new_icobase, owner_sensitive) //Update the icobase of all our organs, but make sure we don't mess with frankenstein limbs in doing so. + if(reset_styles) + H.body_accessory = GLOB.body_accessory_by_name[default_bodyacc] + H.tail = temp_species.tail + H.wing = temp_species.wing + var/obj/item/organ/external/head/head = H.get_organ("head") + head.h_style = "Bald" + head.f_style = "Shaved" + head.ha_style = "None" + H.s_tone = 0 + H.m_styles = DEFAULT_MARKING_STYLES //Wipes out markings, setting them all to "None". + H.m_colours = DEFAULT_MARKING_COLOURS //Defaults colour to #00000 for all markings. + H.change_head_accessory(GLOB.head_accessory_styles_list[default_headacc]) + H.change_icobase(temp_species.icobase, owner_sensitive) //Update the icobase of all our organs, but make sure we don't mess with frankenstein limbs in doing so. /datum/species/slime/proc/blend(mob/living/carbon/human/H) var/new_color = BlendRGB(H.skin_colour, "#acacac", 0.5) // Blends this to make it work better @@ -170,8 +175,6 @@ blend(H) ..() - - /datum/species/slime/can_hear(mob/living/carbon/human/H) // fucking snowflakes . = FALSE if(!HAS_TRAIT(H, TRAIT_DEAF)) @@ -273,18 +276,28 @@ name = "Morph Form" check_flags = AB_CHECK_CONSCIOUS button_overlay_icon = 'icons/effects/effects.dmi' - button_overlay_icon_state = "greenglow" + button_overlay_icon_state = "acid" /datum/action/innate/morphform/Activate() + var/mob/living/carbon/human/H = owner + if(H.nutrition < SLIMEPERSON_MINHUNGER) + to_chat(H, "You're too hungry to morph your form!") + return var/new_subtype = tgui_input_list(H, "Choose a species to imitate", "Select Subtype", H.dna.species.allowed_species_subtypes) if(H.species_subtype == new_subtype) return to_chat(H, "You stand there as your body shifts and then returns to its original form.") - H.visible_message("[H] begins to hold still and concentrate on [H.p_their()] form as it begins to shift and contort...", "You begin to focus on changing your form... (This will take [round(50/10)] seconds, and you must hold still.)") - if(do_after(H, 50, FALSE, H, extra_checks = list(CALLBACK(H, TYPE_PROC_REF(/mob/living, IsStunned))), use_default_checks = FALSE)) // Override the check for weakness, only check for stunned - H.species_subtype = new_subtype - H.dna.species.updatespeciessubtype(H) + H.visible_message("[H] begins to hold still and concentrate on [H.p_their()] form as it begins to shift and contort...", "You begin to focus on changing your form... (This will take [round(SLIMEPERSON_MORPH_FORM/10)] seconds, and you must hold still.)") + if(do_after(H, SLIMEPERSON_MORPH_FORM, FALSE, H, extra_checks = list(CALLBACK(H, TYPE_PROC_REF(/mob/living, IsStunned))), use_default_checks = FALSE)) // Override the check for weakness, only check for stunned + if(H.nutrition < SLIMEPERSON_MINHUNGER) + to_chat(H, "You're too hungry to morph your form!") + return + var/datum/species/species_subtype = GLOB.all_species[new_subtype] + if(isnull(species_subtype)) + species_subtype = GLOB.all_species[H.dna.species.name] + H.dna.species.updatespeciessubtype(H, new species_subtype.type()) H.regenerate_icons() + H.adjust_nutrition(-SLIMEPERSON_HUNGERCOST) else to_chat(H, "You need to hold still in order to shift your form!") @@ -295,3 +308,5 @@ #undef SLIMEPERSON_HUNGERCOST #undef SLIMEPERSON_MINHUNGER #undef SLIMEPERSON_REGROWTHDELAY + +#undef SLIMEPERSON_MORPH_FORM diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm index a80eee90690fd..f67f8dc53dcde 100644 --- a/code/modules/surgery/robotics.dm +++ b/code/modules/surgery/robotics.dm @@ -762,7 +762,6 @@ var/new_gender = gender_list[gender_key] var/old_name = target.real_name target.real_name = new_name - target.species_subtype = new_subtype target.gender = new_gender user.visible_message( "[user] edits [old_name]'s identity parameters with [tool], changing their appearance; [target.p_they()] [target.p_are()] now known as [new_name].", @@ -773,7 +772,10 @@ if(!isnull(target.dna)) for(var/obj/item/organ/external/limb in target.bodyparts) // Update robotic limbs to match new sub species limb.set_company(limb.model, target.dna.species.sprite_sheet_name) // Update the limbs to properly use their new sprite sheet. - target.dna.species.updatespeciessubtype(src) - target.regenerate_icons() + var/datum/species/subtype = GLOB.all_species[new_subtype] + if(isnull(subtype)) + subtype = GLOB.all_species[target.dna.species.name] + target.dna.species.updatespeciessubtype(src, new subtype.type()) + target.regenerate_icons() return SURGERY_STEP_CONTINUE From 9b9683f67dfc7079e2adff78e1a3017259d87acb Mon Sep 17 00:00:00 2001 From: Spaghetti-bit Date: Thu, 30 Jan 2025 04:32:05 -0700 Subject: [PATCH 14/22] Pain2 --- code/modules/client/preference/link_processing.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/client/preference/link_processing.dm b/code/modules/client/preference/link_processing.dm index c0b256e6601ba..2d04e7104f0eb 100644 --- a/code/modules/client/preference/link_processing.dm +++ b/code/modules/client/preference/link_processing.dm @@ -476,7 +476,7 @@ var/datum/body_accessory/accessory = GLOB.body_accessory_by_name[B] if(isnull(accessory)) // None continue - if(active_character.species in accessory.allowed_species || subtype.name in accessory.allowed_species) + if((active_character.species in accessory.allowed_species) || (subtype.name in accessory.allowed_species)) possible_body_accessories += B if(S.optional_body_accessory) possible_body_accessories += "None" //the only null entry should be the "None" option From 19a8910db35fc02c2e1dec59b4d458afaf00ac61 Mon Sep 17 00:00:00 2001 From: Spaghetti-bit Date: Thu, 30 Jan 2025 04:35:10 -0700 Subject: [PATCH 15/22] SQL --- code/modules/client/login_processing/20-load_characters.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/client/login_processing/20-load_characters.dm b/code/modules/client/login_processing/20-load_characters.dm index 641f4c6826077..97432d0e97d0a 100644 --- a/code/modules/client/login_processing/20-load_characters.dm +++ b/code/modules/client/login_processing/20-load_characters.dm @@ -64,7 +64,8 @@ height, cyborg_brain_type, body_type, - pda_ringtone + pda_ringtone, + species_subtype FROM characters WHERE ckey=:ckey"}, list( "ckey" = C.ckey )) From 87aa43b3c1adb7fd11481bd0758efdad42e32bea Mon Sep 17 00:00:00 2001 From: Spaghetti-bit Date: Thu, 30 Jan 2025 04:46:02 -0700 Subject: [PATCH 16/22] Frankenstein monster fix --- code/modules/mob/living/carbon/human/species/machine.dm | 5 ++--- code/modules/mob/living/carbon/human/species/slimepeople.dm | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/code/modules/mob/living/carbon/human/species/machine.dm b/code/modules/mob/living/carbon/human/species/machine.dm index 882562ed304bf..31c0259221cc5 100644 --- a/code/modules/mob/living/carbon/human/species/machine.dm +++ b/code/modules/mob/living/carbon/human/species/machine.dm @@ -115,9 +115,8 @@ H.dna.species = temp_species for(var/obj/item/organ/external/limb in H.bodyparts) - if(istype(limb.dna.species, src)) // Only update the limb that is part of our original species - limb.icobase = temp_species.icobase // update their icobase for when we apply the slimfy effect - limb.dna.species = temp_species // Update limb to match our newly modified species + limb.icobase = temp_species.icobase // update their icobase for when we apply the slimfy effect + limb.dna.species = temp_species // Update limb to match our newly modified species limb.set_company(limb.model, temp_species.sprite_sheet_name) // Robotic limbs always update to our new subtype. // Update misc parts that are stored as reference in species and used on the mob. Also resets stylings to none to prevent anything wacky... diff --git a/code/modules/mob/living/carbon/human/species/slimepeople.dm b/code/modules/mob/living/carbon/human/species/slimepeople.dm index 465913cc5c8c1..b58d76d4990be 100644 --- a/code/modules/mob/living/carbon/human/species/slimepeople.dm +++ b/code/modules/mob/living/carbon/human/species/slimepeople.dm @@ -132,9 +132,8 @@ H.dna.species = temp_species for(var/obj/item/organ/external/limb in H.bodyparts) - if(istype(limb.dna.species, src)) // Only update the limb that is part of our original species - limb.icobase = temp_species.icobase // update their icobase for when we apply the slimfy effect - limb.dna.species = temp_species // Update limb to match our newly modified species + limb.icobase = temp_species.icobase // update their icobase for when we apply the slimfy effect + limb.dna.species = temp_species // Update limb to match our newly modified species limb.set_company(limb.model, temp_species.sprite_sheet_name) // Robotic limbs always update to our new subtype. // Update misc parts that are stored as reference in species and used on the mob. Also resets stylings to none to prevent anything wacky... From 5c159f9b445d30e6042aa32c332b5ea5bd16ff27 Mon Sep 17 00:00:00 2001 From: Spaghetti-bit Date: Thu, 30 Jan 2025 06:03:23 -0700 Subject: [PATCH 17/22] Slimify! ...no longer applies to robotic limbs. --- .../living/carbon/human/human_update_icons.dm | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) 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 118b1dddeadbe..22dfc9c44516e 100644 --- a/code/modules/mob/living/carbon/human/human_update_icons.dm +++ b/code/modules/mob/living/carbon/human/human_update_icons.dm @@ -201,7 +201,7 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) //BEGIN CACHED ICON GENERATION. var/obj/item/organ/external/chest = get_organ("chest") base_icon = chest.get_icon(skeleton) - + var/slimify = istype(src.dna.species, /datum/species/slime) && species_subtype != "None" for(var/obj/item/organ/external/part in bodyparts) var/icon/temp = part.get_icon(skeleton) //That part makes left and right legs drawn topmost and lowermost when human looks WEST or EAST @@ -214,15 +214,19 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) temp2.Insert(new/icon(temp,dir=EAST),dir=EAST) if(!(part.icon_position & RIGHT)) temp2.Insert(new/icon(temp,dir=WEST),dir=WEST) + slimify_limb(part, temp2, slimify) base_icon.Blend(temp2, ICON_OVERLAY) if(part.icon_position & LEFT) temp2.Insert(new/icon(temp,dir=EAST),dir=EAST) if(part.icon_position & RIGHT) temp2.Insert(new/icon(temp,dir=WEST),dir=WEST) + slimify_limb(part, temp2, slimify) base_icon.Blend(temp2, ICON_UNDERLAY) else + slimify_limb(part, temp, slimify) base_icon.Blend(temp, ICON_OVERLAY) + if(!skeleton) if(isgolem(src)) var/datum/species/golem/G = src.dna.species @@ -242,10 +246,6 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) husk_over.Blend(mask, ICON_ADD) base_icon.Blend(husk_over, ICON_OVERLAY) - if(istype(src.dna.species, /datum/species/slime) && species_subtype != "None") // Used for a when slime morphs into another species. Makes them slightly transparent. - base_icon.GrayScale() - base_icon.Blend("[skin_colour]DC", ICON_AND) //DC = 220 alpha. - var/mutable_appearance/new_base = mutable_appearance(base_icon, layer = -LIMBS_LAYER) GLOB.human_icon_cache[icon_key] = new_base standing += new_base @@ -1656,3 +1656,10 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) . += "[part.s_tone]" . = "[.][!!husk][!!hulk][!!skeleton]" + +/mob/living/carbon/human/proc/slimify_limb(obj/item/organ/external/L, icon/I, slimify) + if(slimify) // Used for a when slime morphs into another species. Makes them slightly transparent. + if(!L.is_robotic()) + I.GrayScale() + var/color = sanitize_hexcolor(skin_colour) + I.Blend("[color]DC", ICON_AND) //DC = 220 alpha. From 6fc73d3eec7b8149214308ce9df04f4770d5f1e6 Mon Sep 17 00:00:00 2001 From: Spaghetti-bit Date: Thu, 30 Jan 2025 06:06:48 -0700 Subject: [PATCH 18/22] 220 Alpha to 200 --- code/modules/mob/living/carbon/human/human_update_icons.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 22dfc9c44516e..41635b1d6cf28 100644 --- a/code/modules/mob/living/carbon/human/human_update_icons.dm +++ b/code/modules/mob/living/carbon/human/human_update_icons.dm @@ -1662,4 +1662,4 @@ GLOBAL_LIST_EMPTY(damage_icon_parts) if(!L.is_robotic()) I.GrayScale() var/color = sanitize_hexcolor(skin_colour) - I.Blend("[color]DC", ICON_AND) //DC = 220 alpha. + I.Blend("[color]C8", ICON_AND) //DC = 220 alpha. C8 = 200 From dd4b80ae50cd3737176c5daefb09a9511872021d Mon Sep 17 00:00:00 2001 From: Spaghetti-bit Date: Sat, 1 Feb 2025 22:41:12 -0700 Subject: [PATCH 19/22] Ordering issue fix. --- code/modules/client/preference/character.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/client/preference/character.dm b/code/modules/client/preference/character.dm index 575794b028753..a7b52fa3dcd94 100644 --- a/code/modules/client/preference/character.dm +++ b/code/modules/client/preference/character.dm @@ -216,7 +216,6 @@ "body_type" = body_type, "age" = age, "species" = species, - "species_subtype" = species_subtype, "language" = language, "h_colour" = h_colour, "h_sec_colour" = h_sec_colour, @@ -270,6 +269,7 @@ "runechat_color" = runechat_color, "cyborg_brain_type" = cyborg_brain_type, "pda_ringtone" = pda_ringtone, + "species_subtype" = species_subtype, "ckey" = C.ckey, "slot" = slot_number )) From e44583b07eafc1a435472fa878aa5ad423f39d48 Mon Sep 17 00:00:00 2001 From: Spaghetti-bit Date: Sat, 1 Feb 2025 22:43:40 -0700 Subject: [PATCH 20/22] Last ordering issue. --- code/modules/client/preference/character.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/client/preference/character.dm b/code/modules/client/preference/character.dm index a7b52fa3dcd94..2f41858498f9b 100644 --- a/code/modules/client/preference/character.dm +++ b/code/modules/client/preference/character.dm @@ -151,7 +151,6 @@ body_type=:body_type, age=:age, species=:species, - species_subtype=:species_subtype, language=:language, hair_colour=:h_colour, secondary_hair_colour=:h_sec_colour, @@ -205,7 +204,8 @@ runechat_color=:runechat_color, cyborg_brain_type=:cyborg_brain_type, body_type=:body_type, - pda_ringtone=:pda_ringtone + pda_ringtone=:pda_ringtone, + species_subtype=:species_subtype WHERE ckey=:ckey AND slot=:slot"}, list( // OH GOD SO MANY PARAMETERS From 69f4f7f9649d51d52b3788ed161198321523c03a Mon Sep 17 00:00:00 2001 From: Spaghetti-bit Date: Sat, 8 Feb 2025 10:20:43 -0700 Subject: [PATCH 21/22] aa review, paradise_schema.sql --- SQL/paradise_schema.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql index e41d1abbf6378..4e8c3d9283dcd 100644 --- a/SQL/paradise_schema.sql +++ b/SQL/paradise_schema.sql @@ -83,6 +83,7 @@ CREATE TABLE `characters` ( `runechat_color` VARCHAR(7) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '#FFFFFF', `cyborg_brain_type` ENUM('MMI', 'Robobrain', 'Positronic') NOT NULL DEFAULT 'MMI', `pda_ringtone` VARCHAR(16) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci', + `species_subtype` VARCHAR(7) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'None', PRIMARY KEY (`id`), KEY `ckey` (`ckey`) ) ENGINE=InnoDB AUTO_INCREMENT=125467 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; From c3c96c8ebb5b4bdbae144edb4064b4450645d237 Mon Sep 17 00:00:00 2001 From: Spaghetti-bit Date: Sun, 9 Feb 2025 07:53:42 -0700 Subject: [PATCH 22/22] Apply suggestions from code review Co-authored-by: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com> Signed-off-by: Spaghetti-bit --- SQL/paradise_schema.sql | 2 +- SQL/updates/63-64.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql index 4e8c3d9283dcd..734a45ffbeba1 100644 --- a/SQL/paradise_schema.sql +++ b/SQL/paradise_schema.sql @@ -83,7 +83,7 @@ CREATE TABLE `characters` ( `runechat_color` VARCHAR(7) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '#FFFFFF', `cyborg_brain_type` ENUM('MMI', 'Robobrain', 'Positronic') NOT NULL DEFAULT 'MMI', `pda_ringtone` VARCHAR(16) NULL DEFAULT NULL COLLATE 'utf8mb3_general_ci', - `species_subtype` VARCHAR(7) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'None', + `species_subtype` VARCHAR(45) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'None', PRIMARY KEY (`id`), KEY `ckey` (`ckey`) ) ENGINE=InnoDB AUTO_INCREMENT=125467 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/SQL/updates/63-64.sql b/SQL/updates/63-64.sql index 410d6577ad12c..307d0940eb7ec 100644 --- a/SQL/updates/63-64.sql +++ b/SQL/updates/63-64.sql @@ -2,4 +2,4 @@ # Adds a subtype race to be stored on character saves # Add species_subtype after pda_ringtone ALTER TABLE `characters` - ADD COLUMN `species_subtype` VARCHAR(7) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'None' AFTER `pda_ringtone`; + ADD COLUMN `species_subtype` VARCHAR(45) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'None' AFTER `pda_ringtone`;