diff --git a/code/__defines/chemistry.dm b/code/__defines/chemistry.dm
index 4fbdebf6f1..31f0233b23 100644
--- a/code/__defines/chemistry.dm
+++ b/code/__defines/chemistry.dm
@@ -24,6 +24,7 @@
#define IS_TAJARA 5
#define IS_XENOS 6
#define IS_TESHARI 7
+#define IS_SLIME 8
#define CE_STABLE "stable" // Inaprovaline
#define CE_ANTIBIOTIC "antibiotic" // Spaceacilin
diff --git a/code/__defines/species_languages.dm b/code/__defines/species_languages.dm
index b3d0703d91..27fc17055c 100644
--- a/code/__defines/species_languages.dm
+++ b/code/__defines/species_languages.dm
@@ -8,9 +8,9 @@
// unused: 0x8000 - higher than this will overflow
// Species spawn flags
-#define IS_WHITELISTED 0x1 // Must be whitelisted to play.
-#define CAN_JOIN 0x2 // Species is selectable in chargen.
-#define IS_RESTRICTED 0x4 // Is not a core/normally playable species. (castes, mutantraces)
+#define SPECIES_IS_WHITELISTED 0x1 // Must be whitelisted to play.
+#define SPECIES_IS_RESTRICTED 0x2 // Is not a core/normally playable species. (castes, mutantraces)
+#define SPECIES_CAN_JOIN 0x4 // Species is selectable in chargen.
// Species appearance flags
#define HAS_SKIN_TONE 0x1 // Skin tone selectable in chargen. (0-255)
@@ -19,6 +19,7 @@
#define HAS_UNDERWEAR 0x8 // Underwear is drawn onto the mob icon.
#define HAS_EYE_COLOR 0x10 // Eye colour selectable in chargen. (RGB)
#define HAS_HAIR_COLOR 0x20 // Hair colour selectable in chargen. (RGB)
+#define RADIATION_GLOWS 0x40 // Radiation causes this character to glow.
// Languages.
#define LANGUAGE_SOL_COMMON "Sol Common"
diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm
index 9c0d80e5eb..f00e97d484 100644
--- a/code/_helpers/global_lists.dm
+++ b/code/_helpers/global_lists.dm
@@ -194,16 +194,22 @@ var/global/list/string_slot_flags = list(
language_keys[lowertext(L.key)] = L
var/rkey = 0
- paths = typesof(/datum/species)-/datum/species
+ paths = typesof(/datum/species)
for(var/T in paths)
+
rkey++
- var/datum/species/S = new T
+
+ var/datum/species/S = T
+ if(!initial(S.name))
+ continue
+
+ S = new T
S.race_key = rkey //Used in mob icon caching.
all_species[S.name] = S
- if(!(S.spawn_flags & IS_RESTRICTED))
+ if(!(S.spawn_flags & SPECIES_IS_RESTRICTED))
playable_species += S.name
- if(S.spawn_flags & IS_WHITELISTED)
+ if(S.spawn_flags & SPECIES_IS_WHITELISTED)
whitelisted_species += S.name
//Posters
diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm
index c0a0cac8b3..ac07b8d075 100644
--- a/code/_onclick/other_mobs.dm
+++ b/code/_onclick/other_mobs.dm
@@ -92,7 +92,7 @@
if (powerlevel > 0 && !istype(A, /mob/living/carbon/slime))
if(ishuman(M))
var/mob/living/carbon/human/H = M
- stunprob *= H.species.siemens_coefficient
+ stunprob *= max(H.species.siemens_coefficient,0)
switch(power * 10)
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index 4f211b930e..99788428fb 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -258,8 +258,9 @@
preview_icon.Blend(E.get_icon(), ICON_OVERLAY)
//Tail
- if(H.species.tail)
- temp = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[H.species.tail]_s")
+ var/use_species_tail = H.species.get_tail(H)
+ if(use_species_tail)
+ temp = new/icon("icon" = 'icons/effects/species.dmi', "icon_state" = "[use_species_tail]_s")
preview_icon.Blend(temp, ICON_OVERLAY)
// Skin tone
diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm
index 17899026a0..ef9b419d97 100644
--- a/code/modules/client/preference_setup/general/03_body.dm
+++ b/code/modules/client/preference_setup/general/03_body.dm
@@ -540,9 +540,9 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
dat += "
"
dat += "Language: [current_species.language]
"
dat += ""
- if(current_species.spawn_flags & CAN_JOIN)
+ if(current_species.spawn_flags & SPECIES_CAN_JOIN)
dat += "Often present on human stations."
- if(current_species.spawn_flags & IS_WHITELISTED)
+ if(current_species.spawn_flags & SPECIES_IS_WHITELISTED)
dat += "Whitelist restricted."
if(!current_species.has_organ[O_HEART])
dat += "Does not have a circulatory system."
@@ -570,9 +570,9 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
var/restricted = 0
if(config.usealienwhitelist) //If we're using the whitelist, make sure to check it!
- if(!(current_species.spawn_flags & CAN_JOIN))
+ if(!(current_species.spawn_flags & SPECIES_CAN_JOIN))
restricted = 2
- else if((current_species.spawn_flags & IS_WHITELISTED) && !is_alien_whitelisted(preference_mob(),current_species))
+ else if((current_species.spawn_flags & SPECIES_IS_WHITELISTED) && !is_alien_whitelisted(preference_mob(),current_species))
restricted = 1
if(restricted)
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index 88ef03dda2..8c6fd55c69 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -337,11 +337,11 @@
overlays |= light_overlay_cache["[light_overlay]_icon"]
// Generate and cache the on-mob icon, which is used in update_inv_head().
- var/cache_key = "[light_overlay][H ? "_[H.species.get_bodytype()]" : ""]"
+ var/cache_key = "[light_overlay][H ? "_[H.species.get_bodytype(H)]" : ""]"
if(!light_overlay_cache[cache_key])
var/use_icon = 'icons/mob/light_overlays.dmi'
- if(H && sprite_sheets[H.species.get_bodytype()])
- use_icon = sprite_sheets[H.species.get_bodytype()]
+ if(H && sprite_sheets[H.species.get_bodytype(H)])
+ use_icon = sprite_sheets[H.species.get_bodytype(H)]
light_overlay_cache[cache_key] = image("icon" = use_icon, "icon_state" = "[light_overlay]")
if(H)
@@ -535,8 +535,8 @@
var/icon/under_icon
if(icon_override)
under_icon = icon_override
- else if(H && sprite_sheets && sprite_sheets[H.species.get_bodytype()])
- under_icon = sprite_sheets[H.species.get_bodytype()]
+ else if(H && sprite_sheets && sprite_sheets[H.species.get_bodytype(H)])
+ under_icon = sprite_sheets[H.species.get_bodytype(H)]
else if(item_icons && item_icons[slot_w_uniform_str])
under_icon = item_icons[slot_w_uniform_str]
else
@@ -558,8 +558,8 @@
var/icon/under_icon
if(icon_override)
under_icon = icon_override
- else if(H && sprite_sheets && sprite_sheets[H.species.get_bodytype()])
- under_icon = sprite_sheets[H.species.get_bodytype()]
+ else if(H && sprite_sheets && sprite_sheets[H.species.get_bodytype(H)])
+ under_icon = sprite_sheets[H.species.get_bodytype(H)]
else if(item_icons && item_icons[slot_w_uniform_str])
under_icon = item_icons[slot_w_uniform_str]
else
diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm
index ba50f29cf5..26d7de9082 100644
--- a/code/modules/clothing/spacesuits/rig/rig.dm
+++ b/code/modules/clothing/spacesuits/rig/rig.dm
@@ -472,8 +472,8 @@
var/species_icon = 'icons/mob/rig_back.dmi'
// Since setting mob_icon will override the species checks in
// update_inv_wear_suit(), handle species checks here.
- if(wearer && sprite_sheets && sprite_sheets[wearer.species.get_bodytype()])
- species_icon = sprite_sheets[wearer.species.get_bodytype()]
+ if(wearer && sprite_sheets && sprite_sheets[wearer.species.get_bodytype(wearer)])
+ species_icon = sprite_sheets[wearer.species.get_bodytype(wearer)]
mob_icon = image("icon" = species_icon, "icon_state" = "[icon_state]")
if(installed_modules.len)
diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm
index ac63e4e582..dc8dbccb01 100644
--- a/code/modules/mob/holder.dm
+++ b/code/modules/mob/holder.dm
@@ -138,7 +138,7 @@ var/list/holder_mob_icon_cache = list()
var/skin_colour = rgb(owner.r_skin, owner.g_skin, owner.b_skin)
var/hair_colour = rgb(owner.r_hair, owner.g_hair, owner.b_hair)
var/eye_colour = rgb(owner.r_eyes, owner.g_eyes, owner.b_eyes)
- var/species_name = lowertext(owner.species.get_bodytype())
+ var/species_name = lowertext(owner.species.get_bodytype(owner))
for(var/cache_entry in generate_for_slots)
var/cache_key = "[owner.species]-[cache_entry]-[skin_colour]-[hair_colour]"
diff --git a/code/modules/mob/living/carbon/human/appearance.dm b/code/modules/mob/living/carbon/human/appearance.dm
index 823ac808ec..c3813000bb 100644
--- a/code/modules/mob/living/carbon/human/appearance.dm
+++ b/code/modules/mob/living/carbon/human/appearance.dm
@@ -143,13 +143,13 @@
var/datum/species/current_species = all_species[current_species_name]
if(check_whitelist && config.usealienwhitelist && !check_rights(R_ADMIN, 0, src)) //If we're using the whitelist, make sure to check it!
- if(!(current_species.spawn_flags & CAN_JOIN))
+ if(!(current_species.spawn_flags & SPECIES_CAN_JOIN))
continue
if(whitelist.len && !(current_species_name in whitelist))
continue
if(blacklist.len && (current_species_name in blacklist))
continue
- if((current_species.spawn_flags & IS_WHITELISTED) && !is_alien_whitelisted(src, current_species_name))
+ if((current_species.spawn_flags & SPECIES_IS_WHITELISTED) && !is_alien_whitelisted(src, current_species_name))
continue
valid_species += current_species_name
@@ -158,9 +158,9 @@
/mob/living/carbon/human/proc/generate_valid_hairstyles(var/check_gender = 1)
- var/use_species = species.get_bodytype()
+ var/use_species = species.get_bodytype(src)
var/obj/item/organ/external/head/H = get_organ(BP_HEAD)
- if(H) use_species = H.species.get_bodytype()
+ if(H) use_species = H.species.get_bodytype(src)
var/list/valid_hairstyles = new()
for(var/hairstyle in hair_styles_list)
@@ -180,9 +180,9 @@
/mob/living/carbon/human/proc/generate_valid_facial_hairstyles()
- var/use_species = species.get_bodytype()
+ var/use_species = species.get_bodytype(src)
var/obj/item/organ/external/head/H = get_organ(BP_HEAD)
- if(H) use_species = H.species.get_bodytype()
+ if(H) use_species = H.species.get_bodytype(src)
var/list/valid_facial_hairstyles = new()
for(var/facialhairstyle in facial_hair_styles_list)
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index ba9f03579d..a68ba56dd4 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -51,7 +51,12 @@
msg += ", [use_gender]!"
else if(species.name != "Human")
- msg += ", \a [species.name]!"
+ msg += ", \a [species.get_examine_name()]!"
+
+ var/extra_species_text = species.get_additional_examine_text(src)
+ if(extra_species_text)
+ msg += "[extra_species_text]
"
+
msg += "
"
//uniform
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 0c11ada074..56482186b4 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -326,11 +326,19 @@
//Removed the horrible safety parameter. It was only being used by ninja code anyways.
//Now checks siemens_coefficient of the affected area by default
/mob/living/carbon/human/electrocute_act(var/shock_damage, var/obj/source, var/base_siemens_coeff = 1.0, var/def_zone = null)
+
if(status_flags & GODMODE) return 0 //godmode
if (!def_zone)
def_zone = pick("l_hand", "r_hand")
+ if(species.siemens_coefficient == -1)
+ if(stored_shock_by_ref["\ref[src]"])
+ stored_shock_by_ref["\ref[src]"] += shock_damage
+ else
+ stored_shock_by_ref["\ref[src]"] = shock_damage
+ return
+
var/obj/item/organ/external/affected_organ = get_organ(check_zone(def_zone))
var/siemens_coeff = base_siemens_coeff * get_siemens_coefficient_organ(affected_organ)
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 1c09c04c70..cfb5058c0a 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -92,7 +92,7 @@ emp_act
if (!def_zone)
return 1.0
- var/siemens_coefficient = species.siemens_coefficient
+ var/siemens_coefficient = max(species.siemens_coefficient,0)
var/list/clothing_items = list(head, wear_mask, wear_suit, w_uniform, gloves, shoes) // What all are we checking?
for(var/obj/item/clothing/C in clothing_items)
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index b0a45faff6..36e418418e 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -164,8 +164,8 @@
eye_blind = 0
blinded = 0
eye_blurry = 0
-
-
+
+
if (disabilities & EPILEPSY)
if ((prob(1) && paralysis < 1))
src << "\red You have a seizure!"
@@ -241,7 +241,13 @@
radiation = Clamp(radiation,0,100)
- if (radiation)
+ if(!radiation)
+ if(species.appearance_flags & RADIATION_GLOWS)
+ set_light(0)
+ else
+ if(species.appearance_flags & RADIATION_GLOWS)
+ set_light(max(1,min(10,radiation/10)), max(1,min(20,radiation/20)), species.get_flesh_colour(src))
+ // END DOGSHIT SNOWFLAKE
var/obj/item/organ/internal/diona/nutrients/rad_organ = locate() in internal_organs
if(rad_organ && !rad_organ.is_broken())
diff --git a/code/modules/mob/living/carbon/human/species/outsider/shadow.dm b/code/modules/mob/living/carbon/human/species/outsider/shadow.dm
index ba7d4d1d0a..58a967c809 100644
--- a/code/modules/mob/living/carbon/human/species/outsider/shadow.dm
+++ b/code/modules/mob/living/carbon/human/species/outsider/shadow.dm
@@ -19,7 +19,7 @@
death_message = "dissolves into ash..."
flags = NO_SCAN | NO_SLIP | NO_POISON | NO_MINOR_CUT
- spawn_flags = IS_RESTRICTED
+ spawn_flags = SPECIES_IS_RESTRICTED
genders = list(NEUTER)
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index e9c63918c5..25a8149e48 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -21,10 +21,12 @@
var/prone_icon // If set, draws this from icobase when mob is prone.
var/blood_color = "#A10808" // Red.
var/flesh_color = "#FFC896" // Pink.
- var/base_color // Used by changelings. Should also be used for icon previes..
+ var/base_color // Used by changelings. Should also be used for icon previews.
+
var/tail // Name of tail state in species effects icon file.
var/tail_animation // If set, the icon to obtain tail animation states from.
var/tail_hair
+
var/race_key = 0 // Used for mob icon cache string.
var/icon/icon_template // Used for mob icon generation for non-32x32 species.
var/mob_size = MOB_MEDIUM
@@ -175,71 +177,9 @@
inherent_verbs = list()
inherent_verbs |= /mob/living/carbon/human/proc/regurgitate
-/datum/species/proc/get_station_variant()
- return name
-
-/datum/species/proc/get_bodytype()
- return name
-
-/datum/species/proc/get_knockout_message(var/mob/living/carbon/human/H)
- return ((H && H.isSynthetic()) ? "encounters a hardware fault and suddenly reboots!" : knockout_message)
-
-/datum/species/proc/get_death_message(var/mob/living/carbon/human/H)
- if(config.show_human_death_message)
- return ((H && H.isSynthetic()) ? "gives one shrill beep before falling lifeless." : death_message)
- else
- return "no message"
-
-/datum/species/proc/get_ssd(var/mob/living/carbon/human/H)
- return ((H && H.isSynthetic()) ? "flashing a 'system offline' glyph on their monitor" : show_ssd)
-
-/datum/species/proc/get_blood_colour(var/mob/living/carbon/human/H)
- return ((H && H.isSynthetic()) ? SYNTH_BLOOD_COLOUR : blood_color)
-
-/datum/species/proc/get_virus_immune(var/mob/living/carbon/human/H)
- return ((H && H.isSynthetic()) ? 1 : virus_immune)
-
-/datum/species/proc/get_flesh_colour(var/mob/living/carbon/human/H)
- return ((H && H.isSynthetic()) ? SYNTH_FLESH_COLOUR : flesh_color)
-
-/datum/species/proc/get_environment_discomfort(var/mob/living/carbon/human/H, var/msg_type)
-
- if(!prob(5))
- return
-
- var/covered = 0 // Basic coverage can help.
- for(var/obj/item/clothing/clothes in H)
- if(H.item_is_in_hands(clothes))
- continue
- if((clothes.body_parts_covered & UPPER_TORSO) && (clothes.body_parts_covered & LOWER_TORSO))
- covered = 1
- break
-
- switch(msg_type)
- if("cold")
- if(!covered)
- H << "[pick(cold_discomfort_strings)]"
- if("heat")
- if(covered)
- H << "[pick(heat_discomfort_strings)]"
-
/datum/species/proc/sanitize_name(var/name)
return sanitizeName(name)
-/datum/species/proc/get_random_name(var/gender)
- if(!name_language)
- if(gender == FEMALE)
- return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names))
- else
- return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names))
-
- var/datum/language/species_language = all_languages[name_language]
- if(!species_language)
- species_language = all_languages[default_language]
- if(!species_language)
- return "unknown"
- return species_language.get_random_name(gender)
-
/datum/species/proc/equip_survival_gear(var/mob/living/carbon/human/H,var/extendedtank = 1)
if(H.backbag == 1)
if (extendedtank) H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/engineer(H), slot_r_hand)
@@ -351,6 +291,3 @@
// Called in life() when the mob has no client.
/datum/species/proc/handle_npc(var/mob/living/carbon/human/H)
return
-
-/datum/species/proc/get_vision_flags(var/mob/living/carbon/human/H)
- return vision_flags
diff --git a/code/modules/mob/living/carbon/human/species/species_attack.dm b/code/modules/mob/living/carbon/human/species/species_attack.dm
index cd4ca21e00..018dbafa84 100644
--- a/code/modules/mob/living/carbon/human/species/species_attack.dm
+++ b/code/modules/mob/living/carbon/human/species/species_attack.dm
@@ -67,9 +67,9 @@
attack_noun = list("body")
damage = 2
-/datum/unarmed_attack/slime_glomp/apply_effects()
- //Todo, maybe have a chance of causing an electrical shock?
- return
+/datum/unarmed_attack/slime_glomp/apply_effects(var/mob/living/carbon/human/user,var/mob/living/carbon/human/target,var/armour,var/attack_damage,var/zone)
+ ..()
+ user.apply_stored_shock_to(target)
/datum/unarmed_attack/stomp/weak
attack_verb = list("jumped on")
diff --git a/code/modules/mob/living/carbon/human/species/species_getters.dm b/code/modules/mob/living/carbon/human/species/species_getters.dm
new file mode 100644
index 0000000000..625d555943
--- /dev/null
+++ b/code/modules/mob/living/carbon/human/species/species_getters.dm
@@ -0,0 +1,97 @@
+/datum/species/proc/get_valid_shapeshifter_forms(var/mob/living/carbon/human/H)
+ return list()
+
+/datum/species/proc/get_additional_examine_text(var/mob/living/carbon/human/H)
+ return
+
+/datum/species/proc/get_tail(var/mob/living/carbon/human/H)
+ return tail
+
+/datum/species/proc/get_tail_animation(var/mob/living/carbon/human/H)
+ return tail_animation
+
+/datum/species/proc/get_tail_hair(var/mob/living/carbon/human/H)
+ return tail_hair
+
+/datum/species/proc/get_blood_mask(var/mob/living/carbon/human/H)
+ return blood_mask
+
+/datum/species/proc/get_damage_overlays(var/mob/living/carbon/human/H)
+ return damage_overlays
+
+/datum/species/proc/get_damage_mask(var/mob/living/carbon/human/H)
+ return damage_mask
+
+/datum/species/proc/get_examine_name(var/mob/living/carbon/human/H)
+ return name
+
+/datum/species/proc/get_icobase(var/mob/living/carbon/human/H, var/get_deform)
+ return (get_deform ? deform : icobase)
+
+/datum/species/proc/get_station_variant()
+ return name
+
+/datum/species/proc/get_race_key(var/mob/living/carbon/human/H)
+ return race_key
+
+/datum/species/proc/get_bodytype(var/mob/living/carbon/human/H)
+ return name
+
+/datum/species/proc/get_knockout_message(var/mob/living/carbon/human/H)
+ return ((H && H.isSynthetic()) ? "encounters a hardware fault and suddenly reboots!" : knockout_message)
+
+/datum/species/proc/get_death_message(var/mob/living/carbon/human/H)
+ if(config.show_human_death_message)
+ return ((H && H.isSynthetic()) ? "gives one shrill beep before falling lifeless." : death_message)
+ else
+ return "no message"
+
+/datum/species/proc/get_ssd(var/mob/living/carbon/human/H)
+ return ((H && H.isSynthetic()) ? "flashing a 'system offline' glyph on their monitor" : show_ssd)
+
+/datum/species/proc/get_blood_colour(var/mob/living/carbon/human/H)
+ return ((H && H.isSynthetic()) ? SYNTH_BLOOD_COLOUR : blood_color)
+
+/datum/species/proc/get_virus_immune(var/mob/living/carbon/human/H)
+ return ((H && H.isSynthetic()) ? 1 : virus_immune)
+
+/datum/species/proc/get_flesh_colour(var/mob/living/carbon/human/H)
+ return ((H && H.isSynthetic()) ? SYNTH_FLESH_COLOUR : flesh_color)
+
+/datum/species/proc/get_environment_discomfort(var/mob/living/carbon/human/H, var/msg_type)
+
+ if(!prob(5))
+ return
+
+ var/covered = 0 // Basic coverage can help.
+ for(var/obj/item/clothing/clothes in H)
+ if(H.item_is_in_hands(clothes))
+ continue
+ if((clothes.body_parts_covered & UPPER_TORSO) && (clothes.body_parts_covered & LOWER_TORSO))
+ covered = 1
+ break
+
+ switch(msg_type)
+ if("cold")
+ if(!covered)
+ H << "[pick(cold_discomfort_strings)]"
+ if("heat")
+ if(covered)
+ H << "[pick(heat_discomfort_strings)]"
+
+/datum/species/proc/get_random_name(var/gender)
+ if(!name_language)
+ if(gender == FEMALE)
+ return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names))
+ else
+ return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names))
+
+ var/datum/language/species_language = all_languages[name_language]
+ if(!species_language)
+ species_language = all_languages[default_language]
+ if(!species_language)
+ return "unknown"
+ return species_language.get_random_name(gender)
+
+/datum/species/proc/get_vision_flags(var/mob/living/carbon/human/H)
+ return vision_flags
diff --git a/code/modules/mob/living/carbon/human/species/species_helpers.dm b/code/modules/mob/living/carbon/human/species/species_helpers.dm
new file mode 100644
index 0000000000..3152312f1c
--- /dev/null
+++ b/code/modules/mob/living/carbon/human/species/species_helpers.dm
@@ -0,0 +1,6 @@
+var/list/stored_shock_by_ref = list()
+
+/mob/living/proc/apply_stored_shock_to(var/mob/living/target)
+ if(stored_shock_by_ref["\ref[src]"])
+ target.electrocute_act(stored_shock_by_ref["\ref[src]"]*0.9, src)
+ stored_shock_by_ref["\ref[src]"] = 0
diff --git a/code/modules/mob/living/carbon/human/species/species_shapeshift.dm b/code/modules/mob/living/carbon/human/species/species_shapeshift.dm
new file mode 100644
index 0000000000..293df93215
--- /dev/null
+++ b/code/modules/mob/living/carbon/human/species/species_shapeshift.dm
@@ -0,0 +1,187 @@
+// This is something of an intermediary species used for species that
+// need to emulate the appearance of another race. Currently it is only
+// used for slimes but it may be useful for changelings later.
+var/list/wrapped_species_by_ref = list()
+
+/datum/species/shapeshifter
+
+ inherent_verbs = list(
+ /mob/living/carbon/human/proc/shapeshifter_select_shape,
+ /mob/living/carbon/human/proc/shapeshifter_select_hair,
+ /mob/living/carbon/human/proc/shapeshifter_select_gender
+ )
+
+ var/list/valid_transform_species = list()
+ var/monochromatic
+ var/default_form = "Human"
+
+/datum/species/shapeshifter/get_valid_shapeshifter_forms(var/mob/living/carbon/human/H)
+ return valid_transform_species
+
+/datum/species/shapeshifter/get_icobase(var/mob/living/carbon/human/H, var/get_deform)
+ if(!H) return ..(null, get_deform)
+ var/datum/species/S = all_species[wrapped_species_by_ref["\ref[H]"]]
+ return S.get_icobase(H, get_deform)
+
+/datum/species/shapeshifter/get_race_key(var/mob/living/carbon/human/H)
+ return "[..()]-[wrapped_species_by_ref["\ref[H]"]]"
+
+/datum/species/shapeshifter/get_bodytype(var/mob/living/carbon/human/H)
+ if(!H) return ..()
+ var/datum/species/S = all_species[wrapped_species_by_ref["\ref[H]"]]
+ return S.get_bodytype(H)
+
+/datum/species/shapeshifter/get_blood_mask(var/mob/living/carbon/human/H)
+ if(!H) return ..()
+ var/datum/species/S = all_species[wrapped_species_by_ref["\ref[H]"]]
+ return S.get_blood_mask(H)
+
+/datum/species/shapeshifter/get_damage_mask(var/mob/living/carbon/human/H)
+ if(!H) return ..()
+ var/datum/species/S = all_species[wrapped_species_by_ref["\ref[H]"]]
+ return S.get_damage_mask(H)
+
+/datum/species/shapeshifter/get_damage_overlays(var/mob/living/carbon/human/H)
+ if(!H) return ..()
+ var/datum/species/S = all_species[wrapped_species_by_ref["\ref[H]"]]
+ return S.get_damage_overlays(H)
+
+/datum/species/shapeshifter/get_tail(var/mob/living/carbon/human/H)
+ if(!H) return ..()
+ var/datum/species/S = all_species[wrapped_species_by_ref["\ref[H]"]]
+ return S.get_tail(H)
+
+/datum/species/shapeshifter/get_tail_animation(var/mob/living/carbon/human/H)
+ if(!H) return ..()
+ var/datum/species/S = all_species[wrapped_species_by_ref["\ref[H]"]]
+ return S.get_tail_animation(H)
+
+/datum/species/shapeshifter/get_tail_hair(var/mob/living/carbon/human/H)
+ if(!H) return ..()
+ var/datum/species/S = all_species[wrapped_species_by_ref["\ref[H]"]]
+ return S.get_tail_hair(H)
+
+/datum/species/shapeshifter/handle_post_spawn(var/mob/living/carbon/human/H)
+ ..()
+ wrapped_species_by_ref["\ref[H]"] = default_form
+ if(monochromatic)
+ H.r_hair = H.r_skin
+ H.g_hair = H.g_skin
+ H.b_hair = H.b_skin
+ H.r_facial = H.r_skin
+ H.g_facial = H.g_skin
+ H.b_facial = H.b_skin
+
+ for(var/obj/item/organ/external/E in H.organs)
+ E.sync_colour_to_human(H)
+
+// Verbs follow.
+/mob/living/carbon/human/proc/shapeshifter_select_hair()
+
+ set name = "Select Hair"
+ set category = "Abilities"
+
+ if(stat || world.time < last_special)
+ return
+
+ last_special = world.time + 10
+
+ var/list/valid_hairstyles = list()
+ var/list/valid_facialhairstyles = list()
+ for(var/hairstyle in hair_styles_list)
+ var/datum/sprite_accessory/S = hair_styles_list[hairstyle]
+ if(gender == MALE && S.gender == FEMALE)
+ continue
+ if(gender == FEMALE && S.gender == MALE)
+ continue
+ if(!(species.get_bodytype(src) in S.species_allowed))
+ continue
+ valid_hairstyles += hairstyle
+ for(var/facialhairstyle in facial_hair_styles_list)
+ var/datum/sprite_accessory/S = facial_hair_styles_list[facialhairstyle]
+ if(gender == MALE && S.gender == FEMALE)
+ continue
+ if(gender == FEMALE && S.gender == MALE)
+ continue
+ if(!(species.get_bodytype(src) in S.species_allowed))
+ continue
+ valid_facialhairstyles += facialhairstyle
+
+
+ visible_message("\The [src]'s form contorts subtly.")
+ if(valid_hairstyles.len)
+ var/new_hair = input("Select a hairstyle.", "Shapeshifter Hair") as null|anything in valid_hairstyles
+ change_hair(new_hair ? new_hair : "Bald")
+ if(valid_facialhairstyles.len)
+ var/new_hair = input("Select a facial hair style.", "Shapeshifter Hair") as null|anything in valid_facialhairstyles
+ change_facial_hair(new_hair ? new_hair : "Shaved")
+
+/mob/living/carbon/human/proc/shapeshifter_select_gender()
+
+ set name = "Select Gender"
+ set category = "Abilities"
+
+ if(stat || world.time < last_special)
+ return
+
+ last_special = world.time + 50
+
+ var/new_gender = input("Please select a gender.", "Shapeshifter Gender") as null|anything in list(FEMALE, MALE, NEUTER, PLURAL)
+ if(!new_gender)
+ return
+
+ visible_message("\The [src]'s form contorts subtly.")
+ change_gender(new_gender)
+
+/mob/living/carbon/human/proc/shapeshifter_select_shape()
+
+ set name = "Select Body Shape"
+ set category = "Abilities"
+
+ if(stat || world.time < last_special)
+ return
+
+ last_special = world.time + 50
+
+ var/new_species = input("Please select a species to emulate.", "Shapeshifter Body") as null|anything in species.get_valid_shapeshifter_forms(src)
+ if(!new_species || !all_species[new_species] || wrapped_species_by_ref["\ref[src]"] == new_species)
+ return
+
+ wrapped_species_by_ref["\ref[src]"] = new_species
+ visible_message("\The [src] shifts and contorts, taking the form of \a [new_species]!")
+ regenerate_icons()
+
+/mob/living/carbon/human/proc/shapeshifter_select_colour()
+
+ set name = "Select Body Colour"
+ set category = "Abilities"
+
+ if(stat || world.time < last_special)
+ return
+
+ last_special = world.time + 50
+
+ var/new_skin = input("Please select a new body color.", "Shapeshifter Colour") as color
+ if(!new_skin)
+ return
+ shapeshifter_set_colour(new_skin)
+
+/mob/living/carbon/human/proc/shapeshifter_set_colour(var/new_skin)
+
+ r_skin = hex2num(copytext(new_skin, 2, 4))
+ g_skin = hex2num(copytext(new_skin, 4, 6))
+ b_skin = hex2num(copytext(new_skin, 6, 8))
+
+ var/datum/species/shapeshifter/S = species
+ if(S.monochromatic)
+ r_hair = r_skin
+ g_hair = g_skin
+ b_hair = b_skin
+ r_facial = r_skin
+ g_facial = g_skin
+ b_facial = b_skin
+
+ for(var/obj/item/organ/external/E in organs)
+ E.sync_colour_to_human(src)
+
+ regenerate_icons()
diff --git a/code/modules/mob/living/carbon/human/species/station/golem.dm b/code/modules/mob/living/carbon/human/species/station/golem.dm
index 83d5f6f8f0..bccafdde14 100644
--- a/code/modules/mob/living/carbon/human/species/station/golem.dm
+++ b/code/modules/mob/living/carbon/human/species/station/golem.dm
@@ -8,7 +8,7 @@
language = "Sol Common" //todo?
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch)
flags = NO_PAIN | NO_SCAN | NO_POISON | NO_MINOR_CUT
- spawn_flags = IS_RESTRICTED
+ spawn_flags = SPECIES_IS_RESTRICTED
siemens_coefficient = 0
breath_type = null
diff --git a/code/modules/mob/living/carbon/human/species/station/monkey.dm b/code/modules/mob/living/carbon/human/species/station/monkey.dm
index 85890f4de6..6074934cec 100644
--- a/code/modules/mob/living/carbon/human/species/station/monkey.dm
+++ b/code/modules/mob/living/carbon/human/species/station/monkey.dm
@@ -30,7 +30,7 @@
brute_mod = 1.5
burn_mod = 1.5
- spawn_flags = IS_RESTRICTED
+ spawn_flags = SPECIES_IS_RESTRICTED
bump_flag = MONKEY
swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL
diff --git a/code/modules/mob/living/carbon/human/species/station/prometheans.dm b/code/modules/mob/living/carbon/human/species/station/prometheans.dm
new file mode 100644
index 0000000000..2ada0dd7c7
--- /dev/null
+++ b/code/modules/mob/living/carbon/human/species/station/prometheans.dm
@@ -0,0 +1,188 @@
+var/datum/species/shapeshifter/promethean/prometheans
+
+// Species definition follows.
+/datum/species/shapeshifter/promethean
+
+ name = "Promethean"
+ name_plural = "Prometheans"
+ blurb = "What has Science done?"
+ show_ssd = "totally quiescent"
+ death_message = "rapidly loses cohesion, splattering across the ground..."
+ knockout_message = "collapses inwards, forming a disordered puddle of goo."
+ remains_type = /obj/effect/decal/cleanable/ash
+
+ blood_color = "#05FF9B"
+ flesh_color = "#05FFFB"
+
+ hunger_factor = DEFAULT_HUNGER_FACTOR //todo
+ reagent_tag = IS_SLIME
+ mob_size = MOB_SMALL
+ bump_flag = SLIME
+ swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL
+ push_flags = MONKEY|SLIME|SIMPLE_ANIMAL
+ flags = NO_SCAN | NO_SLIP | NO_MINOR_CUT
+ appearance_flags = HAS_SKIN_COLOR | HAS_EYE_COLOR | HAS_HAIR_COLOR | RADIATION_GLOWS
+ spawn_flags = SPECIES_IS_RESTRICTED
+
+ breath_type = null
+ poison_type = null
+
+ gluttonous = 2
+ virus_immune = 1
+ blood_volume = 600
+ min_age = 1
+ max_age = 5
+ brute_mod = 0.5
+ burn_mod = 2
+ oxy_mod = 0
+ total_health = 120
+
+ cold_level_1 = 260
+ cold_level_2 = 200
+ cold_level_3 = 120
+
+ heat_level_1 = 360
+ heat_level_2 = 400
+ heat_level_3 = 1000
+
+ body_temperature = 310.15
+
+ siemens_coefficient = -1
+ rarity_value = 5
+
+ unarmed_types = list(/datum/unarmed_attack/slime_glomp)
+ has_organ = list(O_BRAIN = /obj/item/organ/internal/brain/slime) // Slime core.
+ has_limbs = list(
+ BP_TORSO = list("path" = /obj/item/organ/external/chest/unbreakable/slime),
+ BP_GROIN = list("path" = /obj/item/organ/external/groin/unbreakable/slime),
+ BP_HEAD = list("path" = /obj/item/organ/external/head/unbreakable/slime),
+ BP_L_ARM = list("path" = /obj/item/organ/external/arm/unbreakable/slime),
+ BP_R_ARM = list("path" = /obj/item/organ/external/arm/right/unbreakable/slime),
+ BP_L_LEG = list("path" = /obj/item/organ/external/leg/unbreakable/slime),
+ BP_R_LEG = list("path" = /obj/item/organ/external/leg/right/unbreakable/slime),
+ BP_L_HAND = list("path" = /obj/item/organ/external/hand/unbreakable/slime),
+ BP_R_HAND = list("path" = /obj/item/organ/external/hand/right/unbreakable/slime),
+ BP_L_FOOT = list("path" = /obj/item/organ/external/foot/unbreakable/slime),
+ BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right/unbreakable/slime)
+ )
+ heat_discomfort_strings = list("You feel too warm.")
+ cold_discomfort_strings = list("You feel too cool.")
+
+ inherent_verbs = list(
+ /mob/living/carbon/human/proc/shapeshifter_select_shape,
+ /mob/living/carbon/human/proc/shapeshifter_select_colour,
+ /mob/living/carbon/human/proc/shapeshifter_select_hair,
+ /mob/living/carbon/human/proc/shapeshifter_select_gender
+ )
+
+ valid_transform_species = list("Human", "Unathi", "Tajara", "Skrell", "Diona", "Teshari", "Monkey")
+ monochromatic = 1
+
+ var/heal_rate = 5 // Temp. Regen per tick.
+
+/datum/species/shapeshifter/promethean/New()
+ ..()
+ prometheans = src
+
+/datum/species/shapeshifter/promethean/equip_survival_gear(var/mob/living/carbon/human/H)
+ var/boxtype = pick(typesof(/obj/item/weapon/storage/toolbox/lunchbox))
+ var/obj/item/weapon/storage/toolbox/lunchbox/L = new boxtype(get_turf(H))
+ var/mob/living/simple_animal/mouse/mouse = new (L)
+ var/obj/item/weapon/holder/holder = new (L)
+ mouse.forceMove(holder)
+ holder.sync(mouse)
+ if(H.backbag == 1)
+ H.equip_to_slot_or_del(L, slot_r_hand)
+ else
+ H.equip_to_slot_or_del(L, slot_in_backpack)
+
+/datum/species/shapeshifter/promethean/hug(var/mob/living/carbon/human/H,var/mob/living/target)
+
+ var/t_him = "them"
+ switch(target.gender)
+ if(MALE)
+ t_him = "him"
+ if(FEMALE)
+ t_him = "her"
+
+ H.visible_message("\The [H] glomps [target] to make [t_him] feel better!", \
+ "You glomps [target] to make [t_him] feel better!")
+ H.apply_stored_shock_to(target)
+
+/datum/species/shapeshifter/promethean/handle_death(var/mob/living/carbon/human/H)
+ spawn(1)
+ if(H)
+ H.gib()
+
+/datum/species/shapeshifter/promethean/handle_environment_special(var/mob/living/carbon/human/H)
+
+ var/turf/T = H.loc
+ if(istype(T))
+ var/obj/effect/decal/cleanable/C = locate() in T
+ if(C)
+ qdel(C)
+ //TODO: gain nutriment
+
+ // Regenerate limbs and heal damage if we have any. Copied from Bay xenos code.
+
+ // Theoretically the only internal organ a slime will have
+ // is the slime core. but we might as well be thorough.
+ for(var/obj/item/organ/I in H.internal_organs)
+ if(I.damage > 0)
+ I.damage = max(I.damage - heal_rate, 0)
+ if (prob(5))
+ H << "You feel a soothing sensation within your [I.name]..."
+ return 1
+
+ // Replace completely missing limbs.
+ for(var/limb_type in has_limbs)
+ var/obj/item/organ/external/E = H.organs_by_name[limb_type]
+ if(E && (E.is_stump() || (E.status & (ORGAN_DESTROYED|ORGAN_DEAD|ORGAN_MUTATED))))
+ E.removed()
+ qdel(E)
+ E = null
+ if(!E)
+ var/list/organ_data = has_limbs[limb_type]
+ var/limb_path = organ_data["path"]
+ var/obj/item/organ/O = new limb_path(H)
+ organ_data["descriptor"] = O.name
+ H << "You feel a slithering sensation as your [O.name] reforms."
+ H.update_body()
+ return 1
+
+ // Heal remaining damage.
+ if (H.getBruteLoss() || H.getFireLoss() || H.getOxyLoss() || H.getToxLoss())
+ H.adjustBruteLoss(-heal_rate)
+ H.adjustFireLoss(-heal_rate)
+ H.adjustOxyLoss(-heal_rate)
+ H.adjustToxLoss(-heal_rate)
+ return 1
+
+/datum/species/shapeshifter/promethean/get_blood_colour(var/mob/living/carbon/human/H)
+ return (H ? rgb(H.r_skin, H.g_skin, H.b_skin) : ..())
+
+/datum/species/shapeshifter/promethean/get_flesh_colour(var/mob/living/carbon/human/H)
+ return (H ? rgb(H.r_skin, H.g_skin, H.b_skin) : ..())
+
+/datum/species/shapeshifter/promethean/get_additional_examine_text(var/mob/living/carbon/human/H)
+
+ if(!stored_shock_by_ref["\ref[H]"])
+ return
+
+ var/t_she = "She is"
+ if(H.gender == MALE)
+ t_she = "He is"
+ else if(H.gender == PLURAL)
+ t_she = "They are"
+ else if(H.gender == NEUTER)
+ t_she = "It is"
+
+ switch(stored_shock_by_ref["\ref[H]"])
+ if(1 to 10)
+ return "[t_she] flickering gently with a little electrical activity."
+ if(11 to 20)
+ return "[t_she] glowing gently with moderate levels of electrical activity.\n"
+ if(21 to 35)
+ return "[t_she] glowing brightly with high levels of electrical activity."
+ if(35 to INFINITY)
+ return "[t_she] radiating massive levels of electrical activity!"
diff --git a/code/modules/mob/living/carbon/human/species/station/seromi.dm b/code/modules/mob/living/carbon/human/species/station/seromi.dm
index 2f931a38f7..27541c2773 100644
--- a/code/modules/mob/living/carbon/human/species/station/seromi.dm
+++ b/code/modules/mob/living/carbon/human/species/station/seromi.dm
@@ -36,7 +36,7 @@
blood_volume = 400
hunger_factor = 0.2
- spawn_flags = CAN_JOIN | IS_WHITELISTED
+ spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED
appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_COLOR | HAS_EYE_COLOR
bump_flag = MONKEY
swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL
diff --git a/code/modules/mob/living/carbon/human/species/station/slime.dm b/code/modules/mob/living/carbon/human/species/station/slime.dm
deleted file mode 100644
index 769b1a2f35..0000000000
--- a/code/modules/mob/living/carbon/human/species/station/slime.dm
+++ /dev/null
@@ -1,52 +0,0 @@
-/datum/species/slime
- name = "Slime"
- name_plural = "slimes"
- mob_size = MOB_SMALL
-
- icobase = 'icons/mob/human_races/r_slime.dmi'
- deform = 'icons/mob/human_races/r_slime.dmi'
-
- language = null //todo?
- unarmed_types = list(/datum/unarmed_attack/slime_glomp)
- flags = NO_SCAN | NO_SLIP | NO_MINOR_CUT
- spawn_flags = IS_RESTRICTED
- siemens_coefficient = 3 //conductive
- darksight = 3
-
- blood_color = "#05FF9B"
- flesh_color = "#05FFFB"
-
- remains_type = /obj/effect/decal/cleanable/ash
- death_message = "rapidly loses cohesion, splattering across the ground..."
-
- has_organ = list(
- "brain" = /obj/item/organ/internal/brain/slime
- )
-
- breath_type = null
- poison_type = null
-
- bump_flag = SLIME
- swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL
- push_flags = MONKEY|SLIME|SIMPLE_ANIMAL
-
- has_limbs = list(
- BP_TORSO = list("path" = /obj/item/organ/external/chest/unbreakable),
- BP_GROIN = list("path" = /obj/item/organ/external/groin/unbreakable),
- BP_HEAD = list("path" = /obj/item/organ/external/head/unbreakable),
- BP_L_ARM = list("path" = /obj/item/organ/external/arm/unbreakable),
- BP_R_ARM = list("path" = /obj/item/organ/external/arm/right/unbreakable),
- BP_L_LEG = list("path" = /obj/item/organ/external/leg/unbreakable),
- BP_R_LEG = list("path" = /obj/item/organ/external/leg/right/unbreakable),
- BP_L_HAND = list("path" = /obj/item/organ/external/hand/unbreakable),
- BP_R_HAND = list("path" = /obj/item/organ/external/hand/right/unbreakable),
- BP_L_FOOT = list("path" = /obj/item/organ/external/foot/unbreakable),
- BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right/unbreakable)
- )
-
- genders = list(NEUTER)
-
-/datum/species/slime/handle_death(var/mob/living/carbon/human/H)
- spawn(1)
- if(H)
- H.gib()
diff --git a/code/modules/mob/living/carbon/human/species/station/station.dm b/code/modules/mob/living/carbon/human/species/station/station.dm
index d3e3a314bc..246b684ca4 100644
--- a/code/modules/mob/living/carbon/human/species/station/station.dm
+++ b/code/modules/mob/living/carbon/human/species/station/station.dm
@@ -14,10 +14,10 @@
min_age = 17
max_age = 110
- spawn_flags = CAN_JOIN
+ spawn_flags = SPECIES_CAN_JOIN
appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_TONE | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR
-/datum/species/human/get_bodytype()
+/datum/species/human/get_bodytype(var/mob/living/carbon/human/H)
return "Human"
/datum/species/unathi
@@ -54,7 +54,7 @@
heat_level_2 = 480 //Default 400
heat_level_3 = 1100 //Default 1000
- spawn_flags = CAN_JOIN | IS_WHITELISTED
+ spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
flesh_color = "#34AF10"
@@ -116,7 +116,7 @@
primitive_form = "Farwa"
- spawn_flags = CAN_JOIN | IS_WHITELISTED
+ spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
flesh_color = "#AFA59E"
@@ -155,7 +155,7 @@
min_age = 19
max_age = 80
- spawn_flags = CAN_JOIN | IS_WHITELISTED
+ spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR
flesh_color = "#8CD7A3"
@@ -246,7 +246,7 @@
body_temperature = T0C + 15 //make the plant people have a bit lower body temperature, why not
flags = NO_SCAN | IS_PLANT | NO_PAIN | NO_SLIP | NO_MINOR_CUT
- spawn_flags = CAN_JOIN | IS_WHITELISTED
+ spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED
blood_color = "#004400"
flesh_color = "#907E4A"
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index b073f8ccf6..7f0489b90f 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -174,9 +174,6 @@ var/global/list/damage_icon_parts = list()
for(var/obj/item/organ/external/O in organs)
if(O.is_stump())
continue
- //if(O.status & ORGAN_DESTROYED) damage_appearance += "d" //what is this?
- //else
- // damage_appearance += O.damage_state
damage_appearance += O.damage_state
if(damage_appearance == previous_damage_appearance)
@@ -194,15 +191,14 @@ var/global/list/damage_icon_parts = list()
if(O.is_stump())
continue
-
O.update_icon()
if(O.damage_state == "00") continue
var/icon/DI
- var/cache_index = "[O.damage_state]/[O.icon_name]/[species.blood_color]/[species.get_bodytype()]"
+ var/cache_index = "[O.damage_state]/[O.icon_name]/[species.get_blood_colour(src)]/[species.get_bodytype(src)]"
if(damage_icon_parts[cache_index] == null)
- DI = new /icon(species.damage_overlays, O.damage_state) // the damage icon for whole human
- DI.Blend(new /icon(species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels
- DI.Blend(species.blood_color, ICON_MULTIPLY)
+ DI = new /icon(species.get_damage_overlays(src), O.damage_state) // the damage icon for whole human
+ DI.Blend(new /icon(species.get_damage_mask(src), O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels
+ DI.Blend(species.get_blood_colour(src), ICON_MULTIPLY)
damage_icon_parts[cache_index] = DI
else
DI = damage_icon_parts[cache_index]
@@ -236,7 +232,7 @@ var/global/list/damage_icon_parts = list()
if(gender == FEMALE)
g = "female"
- var/icon_key = "[species.race_key][g][s_tone][r_skin][g_skin][b_skin]"
+ var/icon_key = "[species.get_race_key(src)][g][s_tone][r_skin][g_skin][b_skin]"
if(lip_style)
icon_key += "[lip_style]"
else
@@ -258,7 +254,7 @@ var/global/list/damage_icon_parts = list()
else
icon_key += "1"
if(part)
- icon_key += "[part.species.race_key]"
+ icon_key += "[part.species.get_race_key(part.owner)]"
icon_key += "[part.dna.GetUIState(DNA_UI_GENDER)]"
icon_key += "[part.dna.GetUIValue(DNA_UI_SKIN_TONE)]"
if(part.s_col && part.s_col.len >= 3)
@@ -357,7 +353,7 @@ var/global/list/damage_icon_parts = list()
if(f_style)
var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[f_style]
- if(facial_hair_style && facial_hair_style.species_allowed && (src.species.get_bodytype() in facial_hair_style.species_allowed))
+ if(facial_hair_style && facial_hair_style.species_allowed && (src.species.get_bodytype(src) in facial_hair_style.species_allowed))
var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
if(facial_hair_style.do_colouration)
facial_s.Blend(rgb(r_facial, g_facial, b_facial), ICON_ADD)
@@ -366,13 +362,16 @@ var/global/list/damage_icon_parts = list()
if(h_style && !(head && (head.flags_inv & BLOCKHEADHAIR)))
var/datum/sprite_accessory/hair_style = hair_styles_list[h_style]
- if(hair_style && (src.species.get_bodytype() in hair_style.species_allowed))
+ if(hair_style && (src.species.get_bodytype(src) in hair_style.species_allowed))
var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
if(hair_style.do_colouration)
hair_s.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD)
face_standing.Blend(hair_s, ICON_OVERLAY)
+ if(head_organ.nonsolid)
+ face_standing += rgb(,,,120)
+
overlays_standing[HAIR_LAYER] = image(face_standing)
if(update_icons) update_icons()
@@ -464,8 +463,8 @@ var/global/list/damage_icon_parts = list()
var/icon/under_icon
if(w_uniform.icon_override)
under_icon = w_uniform.icon_override
- else if(w_uniform.sprite_sheets && w_uniform.sprite_sheets[species.get_bodytype()])
- under_icon = w_uniform.sprite_sheets[species.get_bodytype()]
+ else if(w_uniform.sprite_sheets && w_uniform.sprite_sheets[species.get_bodytype(src)])
+ under_icon = w_uniform.sprite_sheets[species.get_bodytype(src)]
else if(w_uniform.item_icons && w_uniform.item_icons[slot_w_uniform_str])
under_icon = w_uniform.item_icons[slot_w_uniform_str]
else
@@ -486,7 +485,7 @@ var/global/list/damage_icon_parts = list()
//apply blood overlay
if(w_uniform.blood_DNA)
- var/image/bloodsies = image(icon = species.blood_mask, icon_state = "uniformblood")
+ var/image/bloodsies = image(icon = species.get_blood_mask(src), icon_state = "uniformblood")
bloodsies.color = w_uniform.blood_color
standing.overlays += bloodsies
@@ -510,8 +509,8 @@ var/global/list/damage_icon_parts = list()
var/image/standing
if(wear_id.icon_override)
standing = image("icon" = wear_id.icon_override, "icon_state" = "[icon_state]")
- else if(wear_id.sprite_sheets && wear_id.sprite_sheets[species.get_bodytype()])
- standing = image("icon" = wear_id.sprite_sheets[species.get_bodytype()], "icon_state" = "[icon_state]")
+ else if(wear_id.sprite_sheets && wear_id.sprite_sheets[species.get_bodytype(src)])
+ standing = image("icon" = wear_id.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[icon_state]")
else
standing = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "id")
overlays_standing[ID_LAYER] = standing
@@ -533,13 +532,13 @@ var/global/list/damage_icon_parts = list()
var/image/standing
if(gloves.icon_override)
standing = image("icon" = gloves.icon_override, "icon_state" = "[t_state]")
- else if(gloves.sprite_sheets && gloves.sprite_sheets[species.get_bodytype()])
- standing = image("icon" = gloves.sprite_sheets[species.get_bodytype()], "icon_state" = "[t_state]")
+ else if(gloves.sprite_sheets && gloves.sprite_sheets[species.get_bodytype(src)])
+ standing = image("icon" = gloves.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[t_state]")
else
standing = image("icon" = 'icons/mob/hands.dmi', "icon_state" = "[t_state]")
if(gloves.blood_DNA)
- var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "bloodyhands")
+ var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "bloodyhands")
bloodsies.color = gloves.blood_color
standing.overlays += bloodsies
gloves.screen_loc = ui_gloves
@@ -547,7 +546,7 @@ var/global/list/damage_icon_parts = list()
overlays_standing[GLOVES_LAYER] = standing
else
if(blood_DNA)
- var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "bloodyhands")
+ var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "bloodyhands")
bloodsies.color = hand_blood_color
overlays_standing[GLOVES_LAYER] = bloodsies
else
@@ -560,8 +559,8 @@ var/global/list/damage_icon_parts = list()
if(glasses.icon_override)
overlays_standing[GLASSES_LAYER] = image("icon" = glasses.icon_override, "icon_state" = "[glasses.icon_state]")
- else if(glasses.sprite_sheets && glasses.sprite_sheets[species.get_bodytype()])
- overlays_standing[GLASSES_LAYER]= image("icon" = glasses.sprite_sheets[species.get_bodytype()], "icon_state" = "[glasses.icon_state]")
+ else if(glasses.sprite_sheets && glasses.sprite_sheets[species.get_bodytype(src)])
+ overlays_standing[GLASSES_LAYER]= image("icon" = glasses.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[glasses.icon_state]")
else
overlays_standing[GLASSES_LAYER]= image("icon" = 'icons/mob/eyes.dmi', "icon_state" = "[glasses.icon_state]")
@@ -582,9 +581,9 @@ var/global/list/damage_icon_parts = list()
if(l_ear.icon_override)
t_type = "[t_type]_l"
overlays_standing[EARS_LAYER] = image("icon" = l_ear.icon_override, "icon_state" = "[t_type]")
- else if(l_ear.sprite_sheets && l_ear.sprite_sheets[species.get_bodytype()])
+ else if(l_ear.sprite_sheets && l_ear.sprite_sheets[species.get_bodytype(src)])
t_type = "[t_type]_l"
- overlays_standing[EARS_LAYER] = image("icon" = l_ear.sprite_sheets[species.get_bodytype()], "icon_state" = "[t_type]")
+ overlays_standing[EARS_LAYER] = image("icon" = l_ear.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[t_type]")
else
overlays_standing[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[t_type]")
@@ -594,9 +593,9 @@ var/global/list/damage_icon_parts = list()
if(r_ear.icon_override)
t_type = "[t_type]_r"
overlays_standing[EARS_LAYER] = image("icon" = r_ear.icon_override, "icon_state" = "[t_type]")
- else if(r_ear.sprite_sheets && r_ear.sprite_sheets[species.get_bodytype()])
+ else if(r_ear.sprite_sheets && r_ear.sprite_sheets[species.get_bodytype(src)])
t_type = "[t_type]_r"
- overlays_standing[EARS_LAYER] = image("icon" = r_ear.sprite_sheets[species.get_bodytype()], "icon_state" = "[t_type]")
+ overlays_standing[EARS_LAYER] = image("icon" = r_ear.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[t_type]")
else
overlays_standing[EARS_LAYER] = image("icon" = 'icons/mob/ears.dmi', "icon_state" = "[t_type]")
@@ -610,20 +609,20 @@ var/global/list/damage_icon_parts = list()
var/image/standing
if(shoes.icon_override)
standing = image("icon" = shoes.icon_override, "icon_state" = "[shoes.icon_state]")
- else if(shoes.sprite_sheets && shoes.sprite_sheets[species.get_bodytype()])
- standing = image("icon" = shoes.sprite_sheets[species.get_bodytype()], "icon_state" = "[shoes.icon_state]")
+ else if(shoes.sprite_sheets && shoes.sprite_sheets[species.get_bodytype(src)])
+ standing = image("icon" = shoes.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[shoes.icon_state]")
else
standing = image("icon" = 'icons/mob/feet.dmi', "icon_state" = "[shoes.icon_state]")
if(shoes.blood_DNA)
- var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "shoeblood")
+ var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "shoeblood")
bloodsies.color = shoes.blood_color
standing.overlays += bloodsies
standing.color = shoes.color
overlays_standing[SHOES_LAYER] = standing
else
if(feet_blood_DNA)
- var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "shoeblood")
+ var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "shoeblood")
bloodsies.color = feet_blood_color
overlays_standing[SHOES_LAYER] = bloodsies
else
@@ -649,8 +648,8 @@ var/global/list/damage_icon_parts = list()
var/t_icon
if(head.icon_override)
t_icon = head.icon_override
- else if(head.sprite_sheets && head.sprite_sheets[species.get_bodytype()])
- t_icon = head.sprite_sheets[species.get_bodytype()]
+ else if(head.sprite_sheets && head.sprite_sheets[species.get_bodytype(src)])
+ t_icon = head.sprite_sheets[species.get_bodytype(src)]
else if(head.item_icons && (slot_head_str in head.item_icons))
t_icon = head.item_icons[slot_head_str]
@@ -675,13 +674,13 @@ var/global/list/damage_icon_parts = list()
var/image/standing = image(icon = t_icon, icon_state = t_state)
if(head.blood_DNA)
- var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "helmetblood")
+ var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "helmetblood")
bloodsies.color = head.blood_color
standing.overlays += bloodsies
if(istype(head,/obj/item/clothing/head))
var/obj/item/clothing/head/hat = head
- var/cache_key = "[hat.light_overlay]_[species.get_bodytype()]"
+ var/cache_key = "[hat.light_overlay]_[species.get_bodytype(src)]"
if(hat.on && light_overlay_cache[cache_key])
standing.overlays |= light_overlay_cache[cache_key]
@@ -701,8 +700,8 @@ var/global/list/damage_icon_parts = list()
if(belt.icon_override)
standing.icon = belt.icon_override
- else if(belt.sprite_sheets && belt.sprite_sheets[species.get_bodytype()])
- standing.icon = belt.sprite_sheets[species.get_bodytype()]
+ else if(belt.sprite_sheets && belt.sprite_sheets[species.get_bodytype(src)])
+ standing.icon = belt.sprite_sheets[species.get_bodytype(src)]
else
standing.icon = 'icons/mob/belt.dmi'
@@ -739,7 +738,7 @@ var/global/list/damage_icon_parts = list()
var/t_icon = INV_SUIT_DEF_ICON
if(wear_suit.icon_override)
t_icon = wear_suit.icon_override
- else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[species.get_bodytype()])
+ else if(wear_suit.sprite_sheets && wear_suit.sprite_sheets[species.get_bodytype(src)])
t_icon = wear_suit.sprite_sheets[species.name]
else if(wear_suit.item_icons && wear_suit.item_icons[slot_wear_suit_str])
t_icon = wear_suit.item_icons[slot_wear_suit_str]
@@ -755,7 +754,7 @@ var/global/list/damage_icon_parts = list()
if(wear_suit.blood_DNA)
var/obj/item/clothing/suit/S = wear_suit
if(istype(S)) //You can put non-suits in your suit slot (diona nymphs etc).
- var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "[S.blood_overlay_type]blood")
+ var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "[S.blood_overlay_type]blood")
bloodsies.color = wear_suit.blood_color
standing.overlays += bloodsies
@@ -784,14 +783,14 @@ var/global/list/damage_icon_parts = list()
var/image/standing
if(wear_mask.icon_override)
standing = image("icon" = wear_mask.icon_override, "icon_state" = "[wear_mask.icon_state]")
- else if(wear_mask.sprite_sheets && wear_mask.sprite_sheets[species.get_bodytype()])
- standing = image("icon" = wear_mask.sprite_sheets[species.get_bodytype()], "icon_state" = "[wear_mask.icon_state]")
+ else if(wear_mask.sprite_sheets && wear_mask.sprite_sheets[species.get_bodytype(src)])
+ standing = image("icon" = wear_mask.sprite_sheets[species.get_bodytype(src)], "icon_state" = "[wear_mask.icon_state]")
else
standing = image("icon" = 'icons/mob/mask.dmi', "icon_state" = "[wear_mask.icon_state]")
standing.color = wear_mask.color
if( !istype(wear_mask, /obj/item/clothing/mask/smokable/cigarette) && wear_mask.blood_DNA )
- var/image/bloodsies = image("icon" = species.blood_mask, "icon_state" = "maskblood")
+ var/image/bloodsies = image("icon" = species.get_blood_mask(src), "icon_state" = "maskblood")
bloodsies.color = wear_mask.blood_color
standing.overlays += bloodsies
overlays_standing[FACEMASK_LAYER] = standing
@@ -812,8 +811,8 @@ var/global/list/damage_icon_parts = list()
//If this is a rig and a mob_icon is set, it will take species into account in the rig update_icon() proc.
var/obj/item/weapon/rig/rig = back
overlay_icon = rig.mob_icon
- else if(back.sprite_sheets && back.sprite_sheets[species.get_bodytype()])
- overlay_icon = back.sprite_sheets[species.get_bodytype()]
+ else if(back.sprite_sheets && back.sprite_sheets[species.get_bodytype(src)])
+ overlay_icon = back.sprite_sheets[species.get_bodytype(src)]
else if(back.item_icons && (slot_back_str in back.item_icons))
overlay_icon = back.item_icons[slot_back_str]
else
@@ -857,8 +856,8 @@ var/global/list/damage_icon_parts = list()
var/image/standing
if(handcuffed.icon_override)
standing = image("icon" = handcuffed.icon_override, "icon_state" = "handcuff1")
- else if(handcuffed.sprite_sheets && handcuffed.sprite_sheets[species.get_bodytype()])
- standing = image("icon" = handcuffed.sprite_sheets[species.get_bodytype()], "icon_state" = "handcuff1")
+ else if(handcuffed.sprite_sheets && handcuffed.sprite_sheets[species.get_bodytype(src)])
+ standing = image("icon" = handcuffed.sprite_sheets[species.get_bodytype(src)], "icon_state" = "handcuff1")
else
standing = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "handcuff1")
overlays_standing[HANDCUFF_LAYER] = standing
@@ -873,8 +872,8 @@ var/global/list/damage_icon_parts = list()
var/image/standing
if(legcuffed.icon_override)
standing = image("icon" = legcuffed.icon_override, "icon_state" = "legcuff1")
- else if(legcuffed.sprite_sheets && legcuffed.sprite_sheets[species.get_bodytype()])
- standing = image("icon" = legcuffed.sprite_sheets[species.get_bodytype()], "icon_state" = "legcuff1")
+ else if(legcuffed.sprite_sheets && legcuffed.sprite_sheets[species.get_bodytype(src)])
+ standing = image("icon" = legcuffed.sprite_sheets[species.get_bodytype(src)], "icon_state" = "legcuff1")
else
standing = image("icon" = 'icons/mob/mob.dmi', "icon_state" = "legcuff1")
overlays_standing[LEGCUFF_LAYER] = standing
@@ -963,24 +962,29 @@ var/global/list/damage_icon_parts = list()
/mob/living/carbon/human/proc/update_tail_showing(var/update_icons=1)
overlays_standing[TAIL_LAYER] = null
- if(species.tail && !(wear_suit && wear_suit.flags_inv & HIDETAIL))
+ var/species_tail = species.get_tail(src)
+
+ if(species_tail && !(wear_suit && wear_suit.flags_inv & HIDETAIL))
var/icon/tail_s = get_tail_icon()
- overlays_standing[TAIL_LAYER] = image(tail_s, icon_state = "[species.tail]_s")
+ overlays_standing[TAIL_LAYER] = image(tail_s, icon_state = "[species_tail]_s")
animate_tail_reset(0)
if(update_icons)
update_icons()
/mob/living/carbon/human/proc/get_tail_icon()
- var/icon_key = "[species.race_key][r_skin][g_skin][b_skin][r_hair][g_hair][b_hair]"
+ var/icon_key = "[species.get_race_key(src)][r_skin][g_skin][b_skin][r_hair][g_hair][b_hair]"
var/icon/tail_icon = tail_icon_cache[icon_key]
if(!tail_icon)
//generate a new one
- tail_icon = new/icon(icon = (species.tail_animation? species.tail_animation : 'icons/effects/species.dmi'))
+ var/species_tail_anim = species.get_tail_animation(src)
+ if(!species_tail_anim) species_tail_anim = 'icons/effects/species.dmi'
+ tail_icon = new/icon(species_tail_anim)
tail_icon.Blend(rgb(r_skin, g_skin, b_skin), ICON_ADD)
// The following will not work with animated tails.
- if(species.tail_hair)
- var/icon/hair_icon = icon('icons/effects/species.dmi', "[species.tail]_[species.tail_hair]")
+ var/use_species_tail = species.get_tail_hair(src)
+ if(use_species_tail)
+ var/icon/hair_icon = icon('icons/effects/species.dmi', "[species.get_tail(src)]_[use_species_tail]")
hair_icon.Blend(rgb(r_hair, g_hair, b_hair), ICON_ADD)
tail_icon.Blend(hair_icon, ICON_OVERLAY)
tail_icon_cache[icon_key] = tail_icon
@@ -991,7 +995,7 @@ var/global/list/damage_icon_parts = list()
/mob/living/carbon/human/proc/set_tail_state(var/t_state)
var/image/tail_overlay = overlays_standing[TAIL_LAYER]
- if(tail_overlay && species.tail_animation)
+ if(tail_overlay && species.get_tail_animation(src))
tail_overlay.icon_state = t_state
return tail_overlay
return null
@@ -999,7 +1003,7 @@ var/global/list/damage_icon_parts = list()
//Not really once, since BYOND can't do that.
//Update this if the ability to flick() images or make looping animation start at the first frame is ever added.
/mob/living/carbon/human/proc/animate_tail_once(var/update_icons=1)
- var/t_state = "[species.tail]_once"
+ var/t_state = "[species.get_tail(src)]_once"
var/image/tail_overlay = overlays_standing[TAIL_LAYER]
if(tail_overlay && tail_overlay.icon_state == t_state)
@@ -1016,29 +1020,28 @@ var/global/list/damage_icon_parts = list()
update_icons()
/mob/living/carbon/human/proc/animate_tail_start(var/update_icons=1)
- set_tail_state("[species.tail]_slow[rand(0,9)]")
+ set_tail_state("[species.get_tail(src)]_slow[rand(0,9)]")
if(update_icons)
update_icons()
/mob/living/carbon/human/proc/animate_tail_fast(var/update_icons=1)
- set_tail_state("[species.tail]_loop[rand(0,9)]")
+ set_tail_state("[species.get_tail(src)]_loop[rand(0,9)]")
if(update_icons)
update_icons()
/mob/living/carbon/human/proc/animate_tail_reset(var/update_icons=1)
if(stat != DEAD)
- set_tail_state("[species.tail]_idle[rand(0,9)]")
+ set_tail_state("[species.get_tail(src)]_idle[rand(0,9)]")
else
- set_tail_state("[species.tail]_static")
-
+ set_tail_state("[species.get_tail(src)]_static")
if(update_icons)
update_icons()
/mob/living/carbon/human/proc/animate_tail_stop(var/update_icons=1)
- set_tail_state("[species.tail]_static")
+ set_tail_state("[species.get_tail(src)]_static")
if(update_icons)
update_icons()
diff --git a/code/modules/mob/living/carbon/metroid/life.dm b/code/modules/mob/living/carbon/metroid/life.dm
index 7db2bcf5c8..69ddb59038 100644
--- a/code/modules/mob/living/carbon/metroid/life.dm
+++ b/code/modules/mob/living/carbon/metroid/life.dm
@@ -217,7 +217,7 @@
if(istype(L, /mob/living/carbon/human) && dna) //Ignore slime(wo)men
var/mob/living/carbon/human/H = L
- if(H.species.name == "Slime")
+ if(H.species.name == "Promethean")
continue
if(!L.canmove) // Only one slime can latch on at a time.
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 0c3c3a7621..e13914272e 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -155,7 +155,7 @@
return 0
var/datum/species/S = all_species[client.prefs.species]
- if(!(S.spawn_flags & IS_WHITELISTED))
+ if(!(S.spawn_flags & SPECIES_IS_WHITELISTED))
src << alert("Your current species,[client.prefs.species], is not available for play on the station.")
return 0
@@ -179,7 +179,7 @@
return 0
var/datum/species/S = all_species[client.prefs.species]
- if(!(S.spawn_flags & CAN_JOIN))
+ if(!(S.spawn_flags & SPECIES_CAN_JOIN))
src << alert("Your current species, [client.prefs.species], is not available for play on the station.")
return 0
@@ -484,7 +484,7 @@
/mob/new_player/proc/is_species_whitelisted(datum/species/S)
if(!S) return 1
- return is_alien_whitelisted(src, S.name) || !config.usealienwhitelist || !(S.spawn_flags & IS_WHITELISTED)
+ return is_alien_whitelisted(src, S.name) || !config.usealienwhitelist || !(S.spawn_flags & SPECIES_IS_WHITELISTED)
/mob/new_player/get_species()
var/datum/species/chosen_species
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index 5930e49a68..28d054b377 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -26,6 +26,7 @@
var/last_dam = -1 // used in healing/processing calculations.
// Appearance vars.
+ var/nonsolid // Snowflake warning, reee. Used for slime limbs.
var/icon_name = null // Icon state base.
var/body_part = null // Part flag
var/icon_position = 0 // Used in mob overlay layering calculations.
@@ -731,6 +732,9 @@ Note that amputating the affected organ does in fact remove the infection from t
if(cannot_amputate || !owner)
return
+ if(disintegrate == DROPLIMB_EDGE && nonsolid)
+ disintegrate = DROPLIMB_BLUNT //splut
+
switch(disintegrate)
if(DROPLIMB_EDGE)
if(!clean)
@@ -759,6 +763,10 @@ Note that amputating the affected organ does in fact remove the infection from t
var/mob/living/carbon/human/victim = owner //Keep a reference for post-removed().
var/obj/item/organ/external/parent_organ = parent
+
+ var/use_flesh_colour = species.get_flesh_colour(owner)
+ var/use_blood_colour = species.get_blood_colour(owner)
+
removed(null, ignore_children)
victim.traumatic_shock += 60
@@ -806,10 +814,8 @@ Note that amputating the affected organ does in fact remove the infection from t
else
gore = new /obj/effect/decal/cleanable/blood/gibs(get_turf(victim))
if(species)
- if(species.get_flesh_colour())
- gore.fleshcolor = species.get_flesh_colour()
- if(species.get_blood_colour())
- gore.basecolor = species.get_blood_colour()
+ gore.fleshcolor = use_flesh_colour
+ gore.basecolor = use_blood_colour
gore.update_icon()
gore.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),30)
diff --git a/code/modules/organs/organ_icon.dm b/code/modules/organs/organ_icon.dm
index ffcb3f32e1..21e1e337b8 100644
--- a/code/modules/organs/organ_icon.dm
+++ b/code/modules/organs/organ_icon.dm
@@ -71,7 +71,7 @@ var/global/list/limb_icon_cache = list()
if(owner.f_style)
var/datum/sprite_accessory/facial_hair_style = facial_hair_styles_list[owner.f_style]
- if(facial_hair_style && facial_hair_style.species_allowed && (species.get_bodytype() in facial_hair_style.species_allowed))
+ if(facial_hair_style && facial_hair_style.species_allowed && (species.get_bodytype(owner) in facial_hair_style.species_allowed))
var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
if(facial_hair_style.do_colouration)
facial_s.Blend(rgb(owner.r_facial, owner.g_facial, owner.b_facial), ICON_ADD)
@@ -79,7 +79,7 @@ var/global/list/limb_icon_cache = list()
if(owner.h_style && !(owner.head && (owner.head.flags_inv & BLOCKHEADHAIR)))
var/datum/sprite_accessory/hair_style = hair_styles_list[owner.h_style]
- if(hair_style && (species.get_bodytype() in hair_style.species_allowed))
+ if(hair_style && (species.get_bodytype(owner) in hair_style.species_allowed))
var/icon/hair_s = new/icon("icon" = hair_style.icon, "icon_state" = "[hair_style.icon_state]_s")
if(hair_style.do_colouration && islist(h_col) && h_col.len >= 3)
hair_s.Blend(rgb(h_col[1], h_col[2], h_col[3]), ICON_ADD)
@@ -113,36 +113,47 @@ var/global/list/limb_icon_cache = list()
else if (status & ORGAN_ROBOT)
mob_icon = new /icon('icons/mob/human_races/robotic.dmi', "[icon_name][gender ? "_[gender]" : ""]")
else
- if (status & ORGAN_MUTATED)
- mob_icon = new /icon(species.deform, "[icon_name][gender ? "_[gender]" : ""]")
- else
- mob_icon = new /icon(species.icobase, "[icon_name][gender ? "_[gender]" : ""]")
-
- if(status & ORGAN_DEAD)
- mob_icon.ColorTone(rgb(10,50,0))
- mob_icon.SetIntensity(0.7)
-
- if(!isnull(s_tone))
- if(s_tone >= 0)
- mob_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD)
- else
- mob_icon.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT)
- else if(s_col && s_col.len >= 3)
- mob_icon.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_ADD)
+ mob_icon = new /icon(species.get_icobase(owner, (status & ORGAN_MUTATED)), "[icon_name][gender ? "_[gender]" : ""]")
+ apply_colouration(mob_icon)
if(body_hair && islist(h_col) && h_col.len >= 3)
var/cache_key = "[body_hair]-[icon_name]-[h_col[1]][h_col[2]][h_col[3]]"
if(!limb_icon_cache[cache_key])
- var/icon/I = icon(species.icobase, "[icon_name]_[body_hair]")
+ var/icon/I = icon(species.get_icobase(owner), "[icon_name]_[body_hair]")
I.Blend(rgb(h_col[1],h_col[2],h_col[3]), ICON_ADD)
limb_icon_cache[cache_key] = I
mob_icon.Blend(limb_icon_cache[cache_key], ICON_OVERLAY)
dir = EAST
icon = mob_icon
-
return mob_icon
+/obj/item/organ/external/proc/apply_colouration(var/icon/applying)
+
+ if(nonsolid)
+ applying.MapColors("#4D4D4D","#969696","#1C1C1C", "#000000")
+ if(species && species.get_bodytype(owner) != "Human")
+ applying.SetIntensity(1.5) // Unathi, Taj and Skrell have -very- dark base icons.
+ else
+ applying.SetIntensity(0.7)
+
+ else if(status & ORGAN_DEAD)
+ applying.ColorTone(rgb(10,50,0))
+ applying.SetIntensity(0.7)
+
+ if(!isnull(s_tone))
+ if(s_tone >= 0)
+ applying.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD)
+ else
+ applying.Blend(rgb(-s_tone, -s_tone, -s_tone), ICON_SUBTRACT)
+ else if(s_col && s_col.len >= 3)
+ applying.Blend(rgb(s_col[1], s_col[2], s_col[3]), ICON_ADD)
+
+ // Translucency.
+ if(nonsolid) applying += rgb(,,,180) // SO INTUITIVE TY BYOND
+
+ return applying
+
// new damage icon system
// adjusted to set damage_state to brute/burn code only (without r_name0 as before)
/obj/item/organ/external/update_icon()
diff --git a/code/modules/organs/subtypes/unbreakable.dm b/code/modules/organs/subtypes/unbreakable.dm
index 137249e747..9492d330e1 100644
--- a/code/modules/organs/subtypes/unbreakable.dm
+++ b/code/modules/organs/subtypes/unbreakable.dm
@@ -1,4 +1,3 @@
-// Slime limbs.
/obj/item/organ/external/chest/unbreakable
cannot_break = 1
dislocated = -1
@@ -42,3 +41,48 @@
/obj/item/organ/external/head/unbreakable
cannot_break = 1
dislocated = -1
+
+// Slime limbs.
+/obj/item/organ/external/chest/unbreakable/slime
+ nonsolid = 1
+ max_damage = 50
+
+/obj/item/organ/external/groin/unbreakable/slime
+ nonsolid = 1
+ max_damage = 30
+
+/obj/item/organ/external/arm/unbreakable/slime
+ nonsolid = 1
+ max_damage = 15
+
+/obj/item/organ/external/arm/right/unbreakable/slime
+ nonsolid = 1
+ max_damage = 15
+
+/obj/item/organ/external/leg/unbreakable/slime
+ nonsolid = 1
+ max_damage = 15
+
+/obj/item/organ/external/leg/right/unbreakable/slime
+ nonsolid = 1
+ max_damage = 15
+
+/obj/item/organ/external/foot/unbreakable/slime
+ nonsolid = 1
+ max_damage = 5
+
+/obj/item/organ/external/foot/right/unbreakable/slime
+ nonsolid = 1
+ max_damage = 5
+
+/obj/item/organ/external/hand/unbreakable/slime
+ nonsolid = 1
+ max_damage = 5
+
+/obj/item/organ/external/hand/right/unbreakable/slime
+ nonsolid = 1
+ max_damage = 5
+
+/obj/item/organ/external/head/unbreakable/slime
+ nonsolid = 1
+ max_damage = 15
diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm
index 540e5a3367..4f34cd7eff 100644
--- a/code/modules/power/power.dm
+++ b/code/modules/power/power.dm
@@ -344,7 +344,7 @@
PN.trigger_warning(5)
if(istype(M,/mob/living/carbon/human))
var/mob/living/carbon/human/H = M
- if(H.species.siemens_coefficient == 0)
+ if(H.species.siemens_coefficient <= 0)
return
if(H.gloves)
var/obj/item/clothing/gloves/G = H.gloves
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm
index 8a6d50ab29..0022026a67 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm
@@ -476,9 +476,11 @@
/datum/reagent/slimetoxin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(ishuman(M))
var/mob/living/carbon/human/H = M
- if(H.species.name != "Slime")
+ if(H.species.name != "Promethean")
M << "Your flesh rapidly mutates!"
- H.set_species("Slime")
+ H.set_species("Promethean")
+ H.shapeshifter_set_colour("#05FF9B")
+ H.verbs -= /mob/living/carbon/human/proc/shapeshifter_select_colour
/datum/reagent/aslimetoxin
name = "Advanced Mutation Toxin"
diff --git a/polaris.dme b/polaris.dme
index 2dc731c0ef..8412712f64 100644
--- a/polaris.dme
+++ b/polaris.dme
@@ -998,7 +998,6 @@
#include "code\modules\client\preference_setup\global\02_settings.dm"
#include "code\modules\client\preference_setup\global\03_pai.dm"
#include "code\modules\client\preference_setup\global\04_communicators.dm"
-#include "code\modules\client\preference_setup\global\05_ooc.dm"
#include "code\modules\client\preference_setup\global\setting_datums.dm"
#include "code\modules\client\preference_setup\loadout\gear_tweaks.dm"
#include "code\modules\client\preference_setup\loadout\loadout.dm"
@@ -1367,12 +1366,15 @@
#include "code\modules\mob\living\carbon\human\whisper.dm"
#include "code\modules\mob\living\carbon\human\species\species.dm"
#include "code\modules\mob\living\carbon\human\species\species_attack.dm"
+#include "code\modules\mob\living\carbon\human\species\species_getters.dm"
+#include "code\modules\mob\living\carbon\human\species\species_helpers.dm"
#include "code\modules\mob\living\carbon\human\species\species_hud.dm"
+#include "code\modules\mob\living\carbon\human\species\species_shapeshift.dm"
#include "code\modules\mob\living\carbon\human\species\outsider\shadow.dm"
#include "code\modules\mob\living\carbon\human\species\station\golem.dm"
#include "code\modules\mob\living\carbon\human\species\station\monkey.dm"
+#include "code\modules\mob\living\carbon\human\species\station\prometheans.dm"
#include "code\modules\mob\living\carbon\human\species\station\seromi.dm"
-#include "code\modules\mob\living\carbon\human\species\station\slime.dm"
#include "code\modules\mob\living\carbon\human\species\station\station.dm"
#include "code\modules\mob\living\carbon\metroid\death.dm"
#include "code\modules\mob\living\carbon\metroid\emote.dm"