"
- 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/client/preferences.dm b/code/modules/client/preferences.dm
index a9f52a0d2b..f99f77a59a 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -116,6 +116,7 @@ datum/preferences
var/communicator_visibility = 0
var/datum/category_collection/player_setup_collection/player_setup
+ var/datum/browser/panel
/datum/preferences/New(client/C)
player_setup = new(src)
@@ -383,7 +384,11 @@ datum/preferences
dat += "
"
dat += ""
- user << browse(dat, "window=saves;size=300x390")
+ //user << browse(dat, "window=saves;size=300x390")
+ panel = new(user, "Character Slots", "Character Slots", 300, 390, src)
+ panel.set_content(dat)
+ panel.open()
/datum/preferences/proc/close_load_dialog(mob/user)
- user << browse(null, "window=saves")
\ No newline at end of file
+ //user << browse(null, "window=saves")
+ panel.close()
\ No newline at end of file
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/materials/materials.dm b/code/modules/materials/materials.dm
index 70f69be834..920b751117 100644
--- a/code/modules/materials/materials.dm
+++ b/code/modules/materials/materials.dm
@@ -195,9 +195,8 @@ var/list/name_to_material
// General wall debris product placement.
// Not particularly necessary aside from snowflakey cult girders.
-/material/proc/place_dismantled_product(var/turf/target,var/is_devastated)
- for(var/x=1;x<(is_devastated?2:3);x++)
- place_sheet(target)
+/material/proc/place_dismantled_product(var/turf/target)
+ place_sheet(target)
// Debris product. Used ALL THE TIME.
/material/proc/place_sheet(var/turf/target)
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 00d02651b7..f9f423de68 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 1114979ffe..61540e990f 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -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 22329cf2be..b313ae0d8a 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,7 +362,7 @@ 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)
@@ -378,6 +374,8 @@ var/global/list/damage_icon_parts = list()
if (ears_s)
face_standing.Blend(ears_s, ICON_OVERLAY)
// VOREStation Edit - END
+ if(head_organ.nonsolid)
+ face_standing += rgb(,,,120)
overlays_standing[HAIR_LAYER] = image(face_standing)
@@ -470,8 +468,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
@@ -492,7 +490,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
@@ -516,8 +514,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
@@ -539,13 +537,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
@@ -553,7 +551,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
@@ -566,8 +564,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]")
@@ -588,9 +586,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]")
@@ -600,9 +598,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]")
@@ -616,20 +614,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
@@ -655,8 +653,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]
@@ -681,13 +679,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]
@@ -707,8 +705,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'
@@ -745,7 +743,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]
@@ -761,7 +759,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
@@ -790,14 +788,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
@@ -818,8 +816,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
@@ -863,8 +861,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
@@ -879,8 +877,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
@@ -977,24 +975,29 @@ var/global/list/damage_icon_parts = list()
return
// VOREStation Edit - END
- 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
@@ -1005,7 +1008,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
@@ -1013,7 +1016,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)
@@ -1030,29 +1033,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/living/living.dm b/code/modules/mob/living/living.dm
index 42ba1968f5..0c81845e2c 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -579,7 +579,7 @@ default behaviour is:
set name = "Resist"
set category = "IC"
- if(!stat && canClick())
+ if(!incapacitated(INCAPACITATION_KNOCKOUT) && canClick())
setClickCooldown(20)
resist_grab()
if(!weakened)
@@ -646,7 +646,9 @@ default behaviour is:
if(GRAB_PASSIVE)
qdel(G)
if(GRAB_AGGRESSIVE)
- if(prob(60)) //same chance of breaking the grab as disarm
+ //Not standing up makes it much harder to break, so it is easier to cuff someone who is down without forcing them into unconsciousness.
+ //Otherwise, it's the same chance of breaking the grab as disarm.
+ if(incapacitated(INCAPACITATION_KNOCKDOWN)? prob(15) : prob(60))
visible_message("[src] has broken free of [G.assailant]'s grip!")
qdel(G)
if(GRAB_NECK)
@@ -877,7 +879,7 @@ default behaviour is:
else
if(istype(buckled, /obj/vehicle))
var/obj/vehicle/V = buckled
- if(cannot_stand())
+ if(is_physically_disabled())
lying = 0
canmove = 1
pixel_y = V.mob_offset_y - 5
@@ -895,18 +897,13 @@ default behaviour is:
anchored = 0
canmove = 1
- else if(cannot_stand())
- lying = 1
- canmove = 0
- else if(stunned)
- canmove = 0
else if(captured)
anchored = 1
canmove = 0
lying = 0
else
- lying = 0
- canmove = 1
+ lying = incapacitated(INCAPACITATION_KNOCKDOWN)
+ canmove = !incapacitated(INCAPACITATION_DISABLED)
if(lying)
density = 0
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index ee45284925..9cbe7e1221 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -151,11 +151,13 @@ var/list/ai_verbs_hidden = list( // For why this exists, refer to https://xkcd.c
add_language("Galactic Common", 1)
add_language("Sol Common", 0)
add_language("Sinta'unathi", 0)
+ add_language("Siik'maas", 0)
add_language("Siik'tajr", 0)
add_language("Skrellian", 0)
add_language("Tradeband", 1)
add_language("Gutter", 0)
add_language("Encoded Audio Language", 1)
+ add_language("Schechi", 0)
if(!safety)//Only used by AIize() to successfully spawn an AI.
if (!B)//If there is no player/brain inside.
diff --git a/code/modules/mob/living/silicon/robot/component.dm b/code/modules/mob/living/silicon/robot/component.dm
index 6f0b3d81bd..7d2848f9bf 100644
--- a/code/modules/mob/living/silicon/robot/component.dm
+++ b/code/modules/mob/living/silicon/robot/component.dm
@@ -75,7 +75,7 @@
/datum/robot_component/armour
name = "armour plating"
external_type = /obj/item/robot_parts/robot_component/armour
- max_damage = 60
+ max_damage = 90
// ACTUATOR
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index 69371109ec..e6c7546e09 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -23,7 +23,7 @@ var/global/list/robot_modules = list(
var/hide_on_manifest = 0
var/channels = list()
var/networks = list()
- var/languages = list(LANGUAGE_SOL_COMMON = 1, LANGUAGE_TRADEBAND = 1, LANGUAGE_UNATHI = 0, LANGUAGE_SIIK_TAJR = 0, LANGUAGE_SKRELLIAN = 0, LANGUAGE_GUTTER = 0)
+ var/languages = list(LANGUAGE_SOL_COMMON = 1, LANGUAGE_TRADEBAND = 1, LANGUAGE_UNATHI = 0, LANGUAGE_SIIK_TAJR = 0, LANGUAGE_SKRELLIAN = 0, LANGUAGE_GUTTER = 0, LANGUAGE_SCHECHI = 0)
var/sprites = list()
var/can_be_pushed = 1
var/no_slip = 0
@@ -479,11 +479,12 @@ var/global/list/robot_modules = list(
LANGUAGE_SOL_COMMON = 1,
LANGUAGE_UNATHI = 1,
LANGUAGE_SIIK_MAAS = 1,
- LANGUAGE_SIIK_TAJR = 0,
+ LANGUAGE_SIIK_TAJR = 1,
LANGUAGE_SKRELLIAN = 1,
LANGUAGE_ROOTSPEAK = 1,
LANGUAGE_TRADEBAND = 1,
- LANGUAGE_GUTTER = 1
+ LANGUAGE_GUTTER = 1,
+ LANGUAGE_SCHECHI = 1
)
/obj/item/weapon/robot_module/clerical/butler
@@ -623,9 +624,12 @@ var/global/list/robot_modules = list(
LANGUAGE_SOL_COMMON = 1,
LANGUAGE_TRADEBAND = 1,
LANGUAGE_UNATHI = 0,
+ LANGUAGE_SIIK_MAAS = 0,
LANGUAGE_SIIK_TAJR = 0,
LANGUAGE_SKRELLIAN = 0,
- LANGUAGE_GUTTER = 1
+ LANGUAGE_ROOTSPEAK = 0,
+ LANGUAGE_GUTTER = 1,
+ LANGUAGE_SCHECHI = 0
)
sprites = list(
"Dread" = "securityrobot",
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 9b60baaa9c..f649648592 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -159,8 +159,20 @@
return UNBUCKLED
return restrained() ? FULLY_BUCKLED : PARTIALLY_BUCKLED
+/mob/proc/is_physically_disabled()
+ return incapacitated(INCAPACITATION_DISABLED)
+
+/mob/proc/cannot_stand()
+ return incapacitated(INCAPACITATION_KNOCKDOWN)
+
/mob/proc/incapacitated(var/incapacitation_flags = INCAPACITATION_DEFAULT)
- if (stat || paralysis || stunned || weakened || resting || sleeping || (status_flags & FAKEDEATH))
+ if ((incapacitation_flags & INCAPACITATION_STUNNED) && stunned)
+ return 1
+
+ if ((incapacitation_flags & INCAPACITATION_FORCELYING) && (weakened || resting))
+ return 1
+
+ if ((incapacitation_flags & INCAPACITATION_KNOCKOUT) && (stat || paralysis || sleeping || (status_flags & FAKEDEATH)))
return 1
if((incapacitation_flags & INCAPACITATION_RESTRAINED) && restrained())
@@ -688,9 +700,6 @@
/mob/proc/can_stand_overridden()
return 0
-/mob/proc/cannot_stand()
- return incapacitated(INCAPACITATION_DEFAULT & (~INCAPACITATION_RESTRAINED))
-
//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
/mob/proc/update_canmove()
return canmove
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 7b7f994e8f..f814ac2b23 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -152,7 +152,7 @@
var/voice_name = "unidentifiable voice"
var/faction = "neutral" //Used for checking whether hostile simple animals will attack you, possibly more stuff later
- var/captured = 0 //Functionally, should give the same effect as being buckled into a chair when true.
+ var/captured = 0 //Functionally, should give the same effect as being buckled into a chair when true. Only used by energy nets, TODO replace with buckling
//Generic list for proc holders. Only way I can see to enable certain verbs/procs. Should be modified if needed.
var/proc_holder_list[] = list()//Right now unused.
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index f660da3c25..ae89a67366 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -175,7 +175,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
@@ -460,11 +460,13 @@
return new_character
/mob/new_player/proc/ViewManifest()
- var/dat = ""
- dat += "Show Crew Manifest
"
+ var/dat = ""
dat += data_core.get_manifest(OOC = 1)
- src << browse(dat, "window=manifest;size=370x420;can_close=1")
+ //src << browse(dat, "window=manifest;size=370x420;can_close=1")
+ var/datum/browser/popup = new(src, "Crew Manifest", "Crew Manifest", 370, 420, src)
+ popup.set_content(dat)
+ popup.open()
/mob/new_player/Move()
return 0
@@ -480,7 +482,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 cebd834a24..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.
@@ -199,11 +200,11 @@
/obj/item/organ/external/replaced(var/mob/living/carbon/human/target)
owner = target
+ forceMove(owner)
if(istype(owner))
owner.organs_by_name[organ_tag] = src
owner.organs |= src
for(var/obj/item/organ/organ in src)
- organ.loc = owner
organ.replaced(owner,src)
if(parent_organ)
@@ -212,6 +213,12 @@
if(!parent.children)
parent.children = list()
parent.children.Add(src)
+ //Remove all stump wounds since limb is not missing anymore
+ for(var/datum/wound/lost_limb/W in parent.wounds)
+ parent.wounds -= W
+ qdel(W)
+ break
+ parent.update_damages()
/****************************************************
DAMAGE PROCS
@@ -249,7 +256,10 @@
if(is_damageable(brute + burn) || !config.limbs_can_break)
if(brute)
if(can_cut)
- createwound( CUT, brute )
+ if(sharp && !edge)
+ createwound( PIERCE, brute )
+ else
+ createwound( CUT, brute )
else
createwound( BRUISE, brute )
if(burn)
@@ -263,7 +273,10 @@
if (brute > 0)
//Inflict all burte damage we can
if(can_cut)
- createwound( CUT, min(brute,can_inflict) )
+ if(sharp && !edge)
+ createwound( PIERCE, min(brute,can_inflict) )
+ else
+ createwound( CUT, min(brute,can_inflict) )
else
createwound( BRUISE, min(brute,can_inflict) )
var/temp = can_inflict
@@ -326,10 +339,10 @@
break
// heal brute damage
- if(W.damage_type == CUT || W.damage_type == BRUISE)
- brute = W.heal_damage(brute)
- else if(W.damage_type == BURN)
+ if(W.damage_type == BURN)
burn = W.heal_damage(burn)
+ else
+ brute = W.heal_damage(brute)
if(internal)
status &= ~ORGAN_BROKEN
@@ -653,10 +666,10 @@ Note that amputating the affected organ does in fact remove the infection from t
//update damage counts
for(var/datum/wound/W in wounds)
if(!W.internal) //so IB doesn't count towards crit/paincrit
- if(W.damage_type == CUT || W.damage_type == BRUISE)
- brute_dam += W.damage
- else if(W.damage_type == BURN)
+ if(W.damage_type == BURN)
burn_dam += W.damage
+ else
+ brute_dam += W.damage
if(!(status & ORGAN_ROBOT) && W.bleeding() && (H && H.should_have_organ(O_HEART)))
W.bleed_timer--
@@ -719,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)
@@ -747,10 +763,13 @@ 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
- wounds.Cut()
if(parent_organ)
var/datum/wound/lost_limb/W = new (src, disintegrate, clean)
if(clean)
@@ -795,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)
@@ -840,15 +857,46 @@ Note that amputating the affected organ does in fact remove the infection from t
"\The [holder.legcuffed.name] falls off you.")
holder.drop_from_inventory(holder.legcuffed)
+// checks if all wounds on the organ are bandaged
+/obj/item/organ/external/proc/is_bandaged()
+ for(var/datum/wound/W in wounds)
+ if(W.internal) continue
+ if(!W.bandaged)
+ return 0
+ return 1
+
+// checks if all wounds on the organ are salved
+/obj/item/organ/external/proc/is_salved()
+ for(var/datum/wound/W in wounds)
+ if(W.internal) continue
+ if(!W.salved)
+ return 0
+ return 1
+
+// checks if all wounds on the organ are disinfected
+/obj/item/organ/external/proc/is_disinfected()
+ for(var/datum/wound/W in wounds)
+ if(W.internal) continue
+ if(!W.disinfected)
+ return 0
+ return 1
+
/obj/item/organ/external/proc/bandage()
var/rval = 0
- src.status &= ~ORGAN_BLEEDING
+ status &= ~ORGAN_BLEEDING
for(var/datum/wound/W in wounds)
if(W.internal) continue
rval |= !W.bandaged
W.bandaged = 1
return rval
+/obj/item/organ/external/proc/salve()
+ var/rval = 0
+ for(var/datum/wound/W in wounds)
+ rval |= !W.salved
+ W.salved = 1
+ return rval
+
/obj/item/organ/external/proc/disinfect()
var/rval = 0
for(var/datum/wound/W in wounds)
@@ -867,13 +915,6 @@ Note that amputating the affected organ does in fact remove the infection from t
W.clamped = 1
return rval
-/obj/item/organ/external/proc/salve()
- var/rval = 0
- for(var/datum/wound/W in wounds)
- rval |= !W.salved
- W.salved = 1
- return rval
-
/obj/item/organ/external/proc/fracture()
if(status & ORGAN_ROBOT)
return //ORGAN_BROKEN doesn't have the same meaning for robot limbs
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/organs/wound.dm b/code/modules/organs/wound.dm
index 850f5114c0..3cf3ecb239 100644
--- a/code/modules/organs/wound.dm
+++ b/code/modules/organs/wound.dm
@@ -38,7 +38,7 @@
var/internal = 0
// maximum stage at which bleeding should still happen. Beyond this stage bleeding is prevented.
var/max_bleeding_stage = 0
- // one of CUT, BRUISE, BURN
+ // one of CUT, PIERCE, BRUISE, BURN
var/damage_type = CUT
// whether this wound needs a bandage/salve to heal at all
// the maximum amount of damage that this wound can have and still autoheal
@@ -140,6 +140,15 @@
return 0
+ proc/bandage()
+ bandaged = 1
+
+ proc/salve()
+ salved = 1
+
+ proc/disinfect()
+ disinfected = 1
+
// heal the given amount of damage, and if the given amount of damage was more
// than what needed to be healed, return how much heal was left
// set @heals_internal to also heal internal organ damage
@@ -202,7 +211,7 @@
if (wound_damage() <= 30 && bleed_timer <= 0)
return 0 //Bleed timer has run out. Wounds with more than 30 damage don't stop bleeding on their own.
- return (damage_type == BRUISE && wound_damage() >= 20 || damage_type == CUT && wound_damage() >= 5)
+ return 1
/** WOUND DEFINITIONS **/
@@ -226,6 +235,18 @@
return /datum/wound/cut/deep
if(0 to 15)
return /datum/wound/cut/small
+ if(PIERCE)
+ switch(damage)
+ if(60 to INFINITY)
+ return /datum/wound/puncture/massive
+ if(50 to 60)
+ return /datum/wound/puncture/gaping_big
+ if(30 to 50)
+ return /datum/wound/puncture/gaping
+ if(15 to 30)
+ return /datum/wound/puncture/flesh
+ if(0 to 15)
+ return /datum/wound/puncture/small
if(BRUISE)
return /datum/wound/bruise
if(BURN)
@@ -243,6 +264,9 @@
return null //no wound
/** CUTS **/
+/datum/wound/cut/bleeding()
+ return ..() || wound_damage() >= 5
+
/datum/wound/cut/small
// link wound descriptions to amounts of damage
// Minor cuts have max_bleeding_stage set to the stage that bears the wound type's name.
@@ -276,7 +300,43 @@ datum/wound/cut/massive
stages = list("massive wound" = 70, "massive healing wound" = 50, "massive blood soaked clot" = 25, "massive angry scar" = 10, "massive jagged scar" = 0)
damage_type = CUT
+/** PUNCTURES **/
+/datum/wound/puncture/can_worsen(damage_type, damage)
+ return 0
+/datum/wound/puncture/can_merge(var/datum/wound/other)
+ return 0
+/datum/wound/puncture/bleeding()
+ return ..() || wound_damage() >= 5
+
+/datum/wound/puncture/small
+ max_bleeding_stage = 2
+ stages = list("puncture" = 5, "healing puncture" = 2, "small scab" = 0)
+ damage_type = PIERCE
+
+/datum/wound/puncture/flesh
+ max_bleeding_stage = 2
+ stages = list("puncture wound" = 15, "blood soaked clot" = 5, "large scab" = 2, "small round scar" = 0)
+ damage_type = PIERCE
+
+/datum/wound/puncture/gaping
+ max_bleeding_stage = 3
+ stages = list("gaping hole" = 30, "large blood soaked clot" = 15, "blood soaked clot" = 10, "small angry scar" = 5, "small round scar" = 0)
+ damage_type = PIERCE
+
+/datum/wound/puncture/gaping_big
+ max_bleeding_stage = 3
+ stages = list("big gaping hole" = 50, "healing gaping hole" = 20, "large blood soaked clot" = 15, "large angry scar" = 10, "large round scar" = 0)
+ damage_type = PIERCE
+
+datum/wound/puncture/massive
+ max_bleeding_stage = 3
+ stages = list("massive wound" = 60, "massive healing wound" = 30, "massive blood soaked clot" = 25, "massive angry scar" = 10, "massive jagged scar" = 0)
+ damage_type = PIERCE
+
/** BRUISES **/
+/datum/wound/bruise/bleeding()
+ return ..() || wound_damage() >= 20
+
/datum/wound/bruise
stages = list("monumental bruise" = 80, "huge bruise" = 50, "large bruise" = 30,
"moderate bruise" = 20, "small bruise" = 10, "tiny bruise" = 5)
@@ -285,6 +345,11 @@ datum/wound/cut/massive
damage_type = BRUISE
/** BURNS **/
+/datum/wound/burn
+ max_bleeding_stage = 0
+/datum/wound/burn/bleeding()
+ return 0
+
/datum/wound/burn/moderate
stages = list("ripped burn" = 10, "moderate burn" = 5, "healing moderate burn" = 2, "fresh skin" = 0)
damage_type = BURN
@@ -318,15 +383,15 @@ datum/wound/cut/massive
/datum/wound/lost_limb/New(var/obj/item/organ/external/lost_limb, var/losstype, var/clean)
var/damage_amt = lost_limb.max_damage
if(clean) damage_amt /= 2
-
+
switch(losstype)
if(DROPLIMB_EDGE, DROPLIMB_BLUNT)
damage_type = CUT
max_bleeding_stage = 3 //clotted stump and above can bleed.
stages = list(
"ripped stump" = damage_amt*1.3,
- "bloody stump" = damage_amt,
- "clotted stump" = damage_amt*0.5,
+ "bloody stump" = damage_amt,
+ "clotted stump" = damage_amt*0.5,
"scarred stump" = 0
)
if(DROPLIMB_BURN)
@@ -337,7 +402,7 @@ datum/wound/cut/massive
"scarred stump" = damage_amt*0.5,
"scarred stump" = 0
)
-
+
..(damage_amt)
/datum/wound/lost_limb/can_merge(var/datum/wound/other)
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/projectiles/guns/energy/pulse.dm b/code/modules/projectiles/guns/energy/pulse.dm
index 98817fede3..ab134d3406 100644
--- a/code/modules/projectiles/guns/energy/pulse.dm
+++ b/code/modules/projectiles/guns/energy/pulse.dm
@@ -13,12 +13,12 @@
firemodes = list(
list(mode_name="stun", projectile_type=/obj/item/projectile/beam/stun, fire_sound='sound/weapons/Taser.ogg', fire_delay=null, charge_cost=null),
list(mode_name="lethal", projectile_type=/obj/item/projectile/beam, fire_sound='sound/weapons/Laser.ogg', fire_delay=null, charge_cost=null),
- list(mode_name="DESTROY", projectile_type=/obj/item/projectile/beam/pulse, fire_sound='sound/weapons/pulse.ogg', fire_delay=25, charge_cost=400),
+ list(mode_name="DESTROY", projectile_type=/obj/item/projectile/beam/pulse, fire_sound='sound/weapons/pulse.ogg', fire_delay=null, charge_cost=100),
)
/obj/item/weapon/gun/energy/pulse_rifle/mounted
self_recharge = 1
- use_external_power = 1
+ use_external_power = 1
/obj/item/weapon/gun/energy/pulse_rifle/destroyer
name = "pulse destroyer"
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/code/modules/reagents/reagent_containers/food/drinks/drinkingglass.dm b/code/modules/reagents/reagent_containers/food/drinks/drinkingglass.dm
index 63a467dcfd..9141efbc1e 100644
--- a/code/modules/reagents/reagent_containers/food/drinks/drinkingglass.dm
+++ b/code/modules/reagents/reagent_containers/food/drinks/drinkingglass.dm
@@ -8,6 +8,7 @@
volume = 30
unacidable = 1 //glass
center_of_mass = list("x"=16, "y"=10)
+ matter = list("glass" = 500)
on_reagent_change()
/*if(reagents.reagent_list.len > 1 )
diff --git a/code/modules/surgery/limb_reattach.dm b/code/modules/surgery/limb_reattach.dm
index aee13ede83..eadd4db655 100644
--- a/code/modules/surgery/limb_reattach.dm
+++ b/code/modules/surgery/limb_reattach.dm
@@ -32,7 +32,6 @@
"You have attached [target]'s [E.name] to the [E.amputation_point].")
user.drop_from_inventory(E)
E.replaced(target)
- E.loc = target
target.update_body()
target.updatehealth()
target.UpdateDamageIcon()
diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm
index cc56b311b5..e582d1222f 100644
--- a/code/modules/surgery/surgery.dm
+++ b/code/modules/surgery/surgery.dm
@@ -110,7 +110,6 @@ proc/do_surgery(mob/living/carbon/M, mob/living/user, obj/item/tool)
if (user.a_intent == I_HELP)
user << "You can't see any useful way to use [tool] on [M]."
- return 1
return 0
proc/sort_surgeries()
diff --git a/html/changelogs/Yoshax - carpetfix.yml b/html/changelogs/Yoshax - carpetfix.yml
new file mode 100644
index 0000000000..c295d9a0d2
--- /dev/null
+++ b/html/changelogs/Yoshax - carpetfix.yml
@@ -0,0 +1,37 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Yoshax
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - bugfix: "Processing strata floor can now be pried up with a crowbar."
+ - bugfix: "Blue carpet can now also be removed with a crowbar, and has had it's ability to burn and have corners restored."
diff --git a/html/changelogs/Yoshax - featuresandfixes.txt b/html/changelogs/Yoshax - featuresandfixes.txt
new file mode 100644
index 0000000000..14389bfc92
--- /dev/null
+++ b/html/changelogs/Yoshax - featuresandfixes.txt
@@ -0,0 +1,40 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# maptweak
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name.
+author: Yoshax
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
+# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - tweak: "Doubles the maximum length of records and names to 6144 & 52, resptively. Also increases book nelngth to 12288. (All numbers are in charatcers.)
+ - bugfix: "Makes various services in the antag uplink purchasable once again. This includes the fake crew arrival."
+ - bugifx: "Neckgrabs will no longer force people to the ground. In addition, weakened people can no longer resist."
+ - rscadd: "All vending machines now have a small chance of vending an additional item."
+
diff --git a/icons/mob/items/lefthand.dmi b/icons/mob/items/lefthand.dmi
index f8d3c1c23f..b3f56e6ab3 100644
Binary files a/icons/mob/items/lefthand.dmi and b/icons/mob/items/lefthand.dmi differ
diff --git a/icons/mob/items/righthand.dmi b/icons/mob/items/righthand.dmi
index 265df7a2ad..cc0895827a 100644
Binary files a/icons/mob/items/righthand.dmi and b/icons/mob/items/righthand.dmi differ
diff --git a/icons/mob/ties.dmi b/icons/mob/ties.dmi
index 72c63543ab..a2239630b8 100644
Binary files a/icons/mob/ties.dmi and b/icons/mob/ties.dmi differ
diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi
index 8ceefe32cb..2fa64c7ade 100644
Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ
diff --git a/icons/obj/forensics.dmi b/icons/obj/forensics.dmi
index 63225c3012..f91d974309 100644
Binary files a/icons/obj/forensics.dmi and b/icons/obj/forensics.dmi differ
diff --git a/icons/obj/lighting.dmi b/icons/obj/lighting.dmi
index c5f91d2ab2..5b453fbfb4 100644
Binary files a/icons/obj/lighting.dmi and b/icons/obj/lighting.dmi differ
diff --git a/vorestation.dme b/vorestation.dme
index 90ec35d3cf..9520d6fa1b 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -1010,7 +1010,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"
@@ -1383,13 +1382,16 @@
#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_vr.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\human\species\station\station_vr.dm"
#include "code\modules\mob\living\carbon\metroid\death.dm"