Skip to content

Commit

Permalink
Slime People and IPC; Imitating Species Cosmetically. (#27359)
Browse files Browse the repository at this point in the history
* Pain

* More transparency / alpha

* Vulp + Name override

* more transparency alpha stuff

* Reworks species subtype for slimepeople

* Iteration 3...

* Me when initial

* 60 - 61

* Character.dm select query changes.

* 61-62

* The real 61-62

* Update to IPC imitation

* +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.

* Pain2

* SQL

* Frankenstein monster fix

* Slimify! ...no longer applies to robotic limbs.

* 220 Alpha to 200

* Ordering issue fix.

* Last ordering issue.

* aa review, paradise_schema.sql

* Apply suggestions from code review

Co-authored-by: AffectedArc07 <[email protected]>
Signed-off-by: Spaghetti-bit <[email protected]>

---------

Signed-off-by: Spaghetti-bit <[email protected]>
Co-authored-by: AffectedArc07 <[email protected]>
  • Loading branch information
Spaghetti-bit and AffectedArc07 authored Feb 9, 2025
1 parent 59377ad commit 32c9d4d
Show file tree
Hide file tree
Showing 28 changed files with 670 additions and 429 deletions.
1 change: 1 addition & 0 deletions SQL/paradise_schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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(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;
Expand Down
5 changes: 5 additions & 0 deletions SQL/updates/63-64.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Updates the DB from 63 to 64 ~SpaghettiBit
# Adds a subtype race to be stored on character saves
# Add species_subtype after pda_ringtone
ALTER TABLE `characters`
ADD COLUMN `species_subtype` VARCHAR(45) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'None' AFTER `pda_ringtone`;
7 changes: 4 additions & 3 deletions code/__DEFINES/flags.dm
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,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)
Expand Down
2 changes: 1 addition & 1 deletion code/__DEFINES/misc_defines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@
#define INVESTIGATE_HOTMIC "hotmic"

// The SQL version required by this version of the code
#define SQL_VERSION 63
#define SQL_VERSION 64

// Vending machine stuff
#define CAT_NORMAL (1<<0)
Expand Down
6 changes: 3 additions & 3 deletions code/datums/diseases/advance/symptoms/hair.dm
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ BONUS
switch(A.stage)
if(1, 2, 3)
to_chat(H, "<span class='warning'>Your scalp itches.</span>")
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, "<span class='warning'>Hair bursts forth from your scalp!</span>")
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()
2 changes: 1 addition & 1 deletion code/game/dna/dna2_helpers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,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))
Expand Down
4 changes: 2 additions & 2 deletions code/game/gamemodes/miniantags/tourist/tourist_arrivals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
6 changes: 3 additions & 3 deletions code/game/objects/structures/dresser.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions code/modules/awaymissions/mob_spawn.dm
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,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
Expand Down
3 changes: 2 additions & 1 deletion code/modules/client/login_processing/20-load_characters.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
))
Expand Down
96 changes: 60 additions & 36 deletions code/modules/client/preference/character.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -202,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
Expand Down Expand Up @@ -266,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
))
Expand Down Expand Up @@ -306,7 +310,7 @@
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, pda_ringtone)
hair_gradient, hair_gradient_offset, hair_gradient_colour, hair_gradient_alpha, custom_emotes, runechat_color, cyborg_brain_type, body_type, pda_ringtone, species_subtype)
VALUES
(:ckey, :slot, :metadata, :name, :be_random_name, :gender,
:age, :species, :language,
Expand All @@ -333,7 +337,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, :pda_ringtone)
:h_grad_style, :h_grad_offset, :h_grad_colour, :h_grad_alpha, :custom_emotes, :runechat_color, :cyborg_brain_type, :body_type, :pda_ringtone, :species_subtype)
"}, list(
// This has too many params for anyone to look at this without going insae
"ckey" = C.ckey,
Expand Down Expand Up @@ -397,7 +401,8 @@
"custom_emotes" = json_encode(custom_emotes),
"runechat_color" = runechat_color,
"cyborg_brain_type" = cyborg_brain_type,
"pda_ringtone" = pda_ringtone
"pda_ringtone" = pda_ringtone,
"species_subtype" = species_subtype
))

if(!query.warn_execute())
Expand All @@ -422,7 +427,6 @@
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]
Expand Down Expand Up @@ -493,7 +497,7 @@
cyborg_brain_type = query.item[59]
body_type = query.item[60]
pda_ringtone = query.item[61]

species_subtype = query.item[62]
//Sanitize
var/datum/species/SP = GLOB.all_species[species]
if(!SP)
Expand All @@ -507,6 +511,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"

Expand Down Expand Up @@ -830,53 +837,65 @@
//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/fake/H = new
H.dna.species = current_species
var/mob/living/carbon/human/fake/H = new
H.dna.species = current_species
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.
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
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))
Expand Down Expand Up @@ -1831,6 +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
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)

Expand Down
Loading

0 comments on commit 32c9d4d

Please sign in to comment.