From c9f02d97a195e3eb1699cf5489b8517ffea8139a Mon Sep 17 00:00:00 2001
From: Ghommie <42542238+Ghommie@users.noreply.github.com>
Date: Wed, 25 Mar 2020 02:47:16 +0100
Subject: [PATCH 01/75] Privates Visibility Preferences. Also Undergarments
having a purpose.
---
code/__DEFINES/citadel_defines.dm | 8 +++
code/__DEFINES/misc.dm | 19 ++---
code/__HELPERS/_cit_helpers.dm | 9 ++-
code/__HELPERS/global_lists.dm | 5 --
code/__HELPERS/mobs.dm | 11 ++-
.../configuration/entries/game_options.dm | 5 ++
code/game/gamemodes/changeling/changeling.dm | 4 +-
code/game/objects/structures/dresser.dm | 2 +-
.../objects/structures/ghost_role_spawners.dm | 2 +-
code/modules/admin/create_mob.dm | 2 +-
.../antagonists/bloodsucker/powers/veil.dm | 4 +-
code/modules/antagonists/devil/devil.dm | 4 +-
code/modules/awaymissions/corpse.dm | 2 +-
code/modules/client/preferences.dm | 47 ++++++++-----
.../sprite_accessories/_sprite_accessories.dm | 6 +-
.../sprite_accessories/undershirt.dm | 4 ++
.../sprite_accessories/underwear.dm | 7 ++
code/modules/mob/living/carbon/human/human.dm | 3 +-
.../mob/living/carbon/human/update_icons.dm | 6 +-
.../code/modules/arousal/arousal.dm | 2 +-
.../code/modules/arousal/genitals.dm | 70 ++++++++++++-------
.../arousal/genitals_sprite_accessories.dm | 6 +-
.../code/modules/arousal/organs/breasts.dm | 6 +-
.../code/modules/arousal/organs/penis.dm | 10 ++-
.../code/modules/arousal/organs/testicles.dm | 8 +--
.../code/modules/arousal/organs/vagina.dm | 3 +-
.../code/modules/client/preferences.dm | 6 --
27 files changed, 148 insertions(+), 113 deletions(-)
diff --git a/code/__DEFINES/citadel_defines.dm b/code/__DEFINES/citadel_defines.dm
index 01355173d2..8b4ef2aca4 100644
--- a/code/__DEFINES/citadel_defines.dm
+++ b/code/__DEFINES/citadel_defines.dm
@@ -35,6 +35,8 @@
#define MASTURBATE_LINKED_ORGAN (1<<6) //used to pass our mission to the linked organ
#define CAN_CLIMAX_WITH (1<<7)
#define GENITAL_CAN_AROUSE (1<<8)
+#define GENITAL_UNDIES_HIDDEN (1<<9)
+#define UPDATE_OWNER_APPEARANCE (1<<10)
#define DEF_VAGINA_SHAPE "Human"
@@ -71,6 +73,12 @@
#define MILK_RATE_MULT 1
#define MILK_EFFICIENCY 1
+//visibility toggles defines to avoid errors typos code errors.
+#define GEN_VISIBLE_ALWAYS "Always visible"
+#define GEN_VISIBLE_NO_CLOTHES "Hidden by clothes"
+#define GEN_VISIBLE_NO_UNDIES "Hidden by underwear"
+#define GEN_VISIBLE_NEVER "Always hidden"
+
//Individual logging define
#define INDIVIDUAL_LOOC_LOG "LOOC log"
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 89cacc1c7b..3a1e44f053 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -27,14 +27,15 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
//Human Overlays Indexes/////////
//LOTS OF CIT CHANGES HERE. BE CAREFUL WHEN UPSTREAM ADDS MORE LAYERS
-#define MUTATIONS_LAYER 32 //mutations. Tk headglows, cold resistance glow, etc
-#define GENITALS_BEHIND_LAYER 31 //Some genitalia needs to be behind everything, such as with taurs (Taurs use body_behind_layer
-#define BODY_BEHIND_LAYER 30 //certain mutantrace features (tail when looking south) that must appear behind the body parts
-#define BODYPARTS_LAYER 29 //Initially "AUGMENTS", this was repurposed to be a catch-all bodyparts flag
-#define MARKING_LAYER 28 //Matrixed body markings because clashing with snouts?
-#define BODY_ADJ_LAYER 27 //certain mutantrace features (snout, body markings) that must appear above the body parts
-#define GENITALS_FRONT_LAYER 26 //Draws some genitalia above clothes and the TAUR body if need be.
-#define BODY_LAYER 25 //underwear, undershirts, socks, eyes, lips(makeup)
+#define MUTATIONS_LAYER 33 //mutations. Tk headglows, cold resistance glow, etc
+#define GENITALS_BEHIND_LAYER 32 //Some genitalia needs to be behind everything, such as with taurs (Taurs use body_behind_layer
+#define BODY_BEHIND_LAYER 31 //certain mutantrace features (tail when looking south) that must appear behind the body parts
+#define BODYPARTS_LAYER 30 //Initially "AUGMENTS", this was repurposed to be a catch-all bodyparts flag
+#define MARKING_LAYER 29 //Matrixed body markings because clashing with snouts?
+#define BODY_ADJ_LAYER 28 //certain mutantrace features (snout, body markings) that must appear above the body parts
+#define GENITALS_FRONT_LAYER 27 //Draws some genitalia above clothes and the TAUR body if need be.
+#define BODY_LAYER 26 //underwear, undershirts, socks, eyes, lips(makeup)
+#define GENITALS_NO_UNDIE_LAYER 25 //found above undergarments.
#define FRONT_MUTATIONS_LAYER 24 //mutations that should appear above body, body_adj and bodyparts layer (e.g. laser eyes)
#define DAMAGE_LAYER 23 //damage indicators (cuts and burns)
#define UNIFORM_LAYER 22
@@ -59,7 +60,7 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
#define HANDS_LAYER 3
#define BODY_FRONT_LAYER 2
#define FIRE_LAYER 1 //If you're on fire
-#define TOTAL_LAYERS 32 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_;
+#define TOTAL_LAYERS 33 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_;
//Human Overlay Index Shortcuts for alternate_worn_layer, layers
//Because I *KNOW* somebody will think layer+1 means "above"
diff --git a/code/__HELPERS/_cit_helpers.dm b/code/__HELPERS/_cit_helpers.dm
index cc8ab0d250..9afae12c30 100644
--- a/code/__HELPERS/_cit_helpers.dm
+++ b/code/__HELPERS/_cit_helpers.dm
@@ -58,14 +58,13 @@ GLOBAL_LIST_EMPTY(ipc_antennas_list)
//Genitals and Arousal Lists
GLOBAL_LIST_EMPTY(genitals_list)
GLOBAL_LIST_EMPTY(cock_shapes_list)
-GLOBAL_LIST_EMPTY(gentlemans_organ_names)
GLOBAL_LIST_EMPTY(balls_shapes_list)
GLOBAL_LIST_EMPTY(breasts_shapes_list)
GLOBAL_LIST_EMPTY(vagina_shapes_list)
-GLOBAL_LIST_INIT(cum_into_containers_list, list(/obj/item/reagent_containers/food/snacks/pie)) //Yer fuggin snowflake name list jfc
-GLOBAL_LIST_INIT(dick_nouns, list("dick","cock","member","shaft"))
-GLOBAL_LIST_INIT(cum_id_list,"semen")
-GLOBAL_LIST_INIT(milk_id_list,"milk")
+//longcat memes.
+GLOBAL_LIST_INIT(dick_nouns, list("phallus", "willy", "dick", "prick", "member", "tool", "gentleman's organ", "cock", "wang", "knob", "dong", "joystick", "pecker", "johnson", "weenie", "tadger", "schlong", "thirsty ferret", "One eyed trouser trout", "Ding dong", "ankle spanker", "Pork sword", "engine cranker", "Harry hot dog", "Davy Crockett", "Kidney cracker", "Heat seeking moisture missile", "Giggle stick", "love whistle", "Tube steak", "Uncle Dick", "Purple helmet warrior"))
+
+GLOBAL_LIST_INIT(genitals_visibility_toggles, list(GEN_VISIBLE_ALWAYS, GEN_VISIBLE_NO_CLOTHES, GEN_VISIBLE_NO_UNDIES, GEN_VISIBLE_NEVER))
GLOBAL_LIST_INIT(dildo_shapes, list(
"Human" = "human",
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index ff2559b661..38e25b04c5 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -54,11 +54,6 @@
init_sprite_accessory_subtypes(/datum/sprite_accessory/vagina, GLOB.vagina_shapes_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, GLOB.breasts_shapes_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/testicles, GLOB.balls_shapes_list)
- GLOB.gentlemans_organ_names = list("phallus", "willy", "dick", "prick", "member", "tool", "gentleman's organ",
- "cock", "wang", "knob", "dong", "joystick", "pecker", "johnson", "weenie", "tadger", "schlong", "thirsty ferret",
- "baloney pony", "schlanger", "Mutton dagger", "old blind bob","Hanging Johnny", "fishing rod", "Tally whacker", "polly rocket",
- "One eyed trouser trout", "Ding dong", "ankle spanker", "Pork sword", "engine cranker", "Harry hot dog", "Davy Crockett",
- "Kidney cracker", "Heat seeking moisture missile", "Giggle stick", "love whistle", "Tube steak", "Uncle Dick", "Purple helmet warrior")
for(var/gpath in subtypesof(/obj/item/organ/genital))
var/obj/item/organ/genital/G = gpath
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
index b8edf3b0f4..f7546193aa 100644
--- a/code/__HELPERS/mobs.dm
+++ b/code/__HELPERS/mobs.dm
@@ -185,7 +185,6 @@
"cock_diameter_ratio" = COCK_DIAMETER_RATIO_DEF,
"cock_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
"has_balls" = FALSE,
- "balls_internal" = FALSE,
"balls_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
"balls_size" = BALLS_SIZE_DEF,
"balls_shape" = DEF_BALLS_SHAPE,
@@ -200,13 +199,11 @@
"has_vag" = FALSE,
"vag_shape" = pick(GLOB.vagina_shapes_list),
"vag_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"),
- "vag_clits" = 1,
- "vag_clit_diam" = 0.25,
- "vag_clit_len" = 0.25,
"has_womb" = FALSE,
- "womb_cum_rate" = CUM_RATE,
- "womb_cum_mult" = CUM_RATE_MULT,
- "womb_efficiency" = CUM_EFFICIENCY,
+ "balls_visibility" = GEN_VISIBLE_NO_UNDIES,
+ "breasts_visibility"= GEN_VISIBLE_NO_UNDIES,
+ "cock_visibility" = GEN_VISIBLE_NO_UNDIES,
+ "vag_visibility" = GEN_VISIBLE_NO_UNDIES,
"ipc_screen" = snowflake_ipc_antenna_list ? pick(snowflake_ipc_antenna_list) : "None",
"ipc_antenna" = "None",
"flavor_text" = "",
diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm
index bc290bedb9..b233e92007 100644
--- a/code/controllers/configuration/entries/game_options.dm
+++ b/code/controllers/configuration/entries/game_options.dm
@@ -436,3 +436,8 @@
/datum/config_entry/number/penis_max_inches_prefs
config_entry_value = 20
min_val = 0
+
+/datum/config_entry/keyed_list/safe_visibility_toggles
+ key_mode = KEY_MODE_TEXT
+ value_mode = VALUE_MODE_FLAG
+ config_entry_value = list(GEN_VISIBLE_NO_CLOTHES, GEN_VISIBLE_NO_UNDIES, GEN_VISIBLE_NEVER) //refer to cit_helpers for all toggles.
diff --git a/code/game/gamemodes/changeling/changeling.dm b/code/game/gamemodes/changeling/changeling.dm
index 14fe960422..4db8f4129a 100644
--- a/code/game/gamemodes/changeling/changeling.dm
+++ b/code/game/gamemodes/changeling/changeling.dm
@@ -88,13 +88,13 @@ GLOBAL_VAR(changeling_team_objective_type) //If this is not null, we hand our th
user.underwear = chosen_prof.underwear
user.undie_color = chosen_prof.undie_color
user.undershirt = chosen_prof.undershirt
- user.shirt_color =chosen_prof.shirt_color
+ user.shirt_color = chosen_prof.shirt_color
user.socks = chosen_prof.socks
user.socks_color =chosen_prof.socks_color
chosen_dna.transfer_identity(user, 1)
user.updateappearance(mutcolor_update=1)
- user.update_body()
+ user.update_body(TRUE)
user.domutcheck()
//vars hackery. not pretty, but better than the alternative.
diff --git a/code/game/objects/structures/dresser.dm b/code/game/objects/structures/dresser.dm
index ecacf49fc2..528153324d 100644
--- a/code/game/objects/structures/dresser.dm
+++ b/code/game/objects/structures/dresser.dm
@@ -73,7 +73,7 @@
H.socks_color = recolor_undergarment(H, "socks", H.socks_color)
add_fingerprint(H)
- H.update_body()
+ H.update_body(TRUE)
/obj/structure/dresser/proc/recolor_undergarment(mob/living/carbon/human/H, garment_type = "underwear", default_color)
var/n_color = input(H, "Choose your [garment_type]'\s color.", "Character Preference", default_color) as color|null
diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm
index 7469bd2e72..65145c0eed 100644
--- a/code/game/objects/structures/ghost_role_spawners.dm
+++ b/code/game/objects/structures/ghost_role_spawners.dm
@@ -31,7 +31,7 @@
new_spawn.underwear = "Nude" //You're a plant, partner
new_spawn.undershirt = "Nude" //changing underwear/shirt/socks doesn't seem to function correctly right now because of some bug elsewhere?
new_spawn.socks = "Nude"
- new_spawn.update_body()
+ new_spawn.update_body(TRUE)
//Ash walker eggs: Spawns in ash walker dens in lavaland. Ghosts become unbreathing lizards that worship the Necropolis and are advised to retrieve corpses to create more ash walkers.
diff --git a/code/modules/admin/create_mob.dm b/code/modules/admin/create_mob.dm
index 3336da7267..3e604856c5 100644
--- a/code/modules/admin/create_mob.dm
+++ b/code/modules/admin/create_mob.dm
@@ -45,6 +45,6 @@
SEND_SIGNAL(H, COMSIG_HUMAN_ON_RANDOMIZE)
- H.update_body()
+ H.update_body(TRUE)
H.update_hair()
H.update_body_parts()
diff --git a/code/modules/antagonists/bloodsucker/powers/veil.dm b/code/modules/antagonists/bloodsucker/powers/veil.dm
index 0b3cded832..ecb0611940 100644
--- a/code/modules/antagonists/bloodsucker/powers/veil.dm
+++ b/code/modules/antagonists/bloodsucker/powers/veil.dm
@@ -95,7 +95,7 @@
H.dna.features = random_features(H.dna.species?.id)
// Apply Appearance
- H.update_body() // Outfit and underware, also body.
+ H.update_body(TRUE) // Outfit and underwear, also body and privates.
//H.update_mutant_bodyparts() // Lizard tails etc
H.update_hair()
H.update_body_parts()
@@ -140,7 +140,7 @@
ADD_TRAIT(H, TRAIT_DISFIGURED, "husk") // NOTE: We are ASSUMING husk. // H.status_flags |= DISFIGURED // Restore "Unknown" disfigurement
H.dna.features = prev_features
// Apply Appearance
- H.update_body() // Outfit and underware, also body.
+ H.update_body(TRUE) // Outfit and underwear, also body and privates.
H.update_hair()
H.update_body_parts() // Body itself, maybe skin color?
cast_effect() // POOF
diff --git a/code/modules/antagonists/devil/devil.dm b/code/modules/antagonists/devil/devil.dm
index 1d0bfde322..26e6283f09 100644
--- a/code/modules/antagonists/devil/devil.dm
+++ b/code/modules/antagonists/devil/devil.dm
@@ -244,7 +244,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
H.undershirt = "Nude"
H.socks = "Nude"
H.dna.features["mcolor"] = "511" //A deep red
- H.regenerate_icons()
+ H.update_body(TRUE)
else //Did the devil get hit by a staff of transmutation?
owner.current.color = "#501010"
give_appropriate_spells()
@@ -466,7 +466,7 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
H.undershirt = "Nude"
H.socks = "Nude"
H.dna.features["mcolor"] = "511"
- H.regenerate_icons()
+ H.update_body(TRUE)
if(SOULVALUE >= TRUE_THRESHOLD) //Yes, BOTH this and the above if statement are to run if soulpower is high enough.
var/mob/living/carbon/true_devil/A = new /mob/living/carbon/true_devil(targetturf)
A.faction |= "hell"
diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm
index f740ed27dd..50dd1e5608 100644
--- a/code/modules/awaymissions/corpse.dm
+++ b/code/modules/awaymissions/corpse.dm
@@ -208,7 +208,7 @@
else
H.skin_tone = random_skin_tone()
H.update_hair()
- H.update_body()
+ H.update_body() //update_genitals arg FALSE because these don't quite require/have them most times.
if(outfit)
var/static/list/slots = list("uniform", "r_hand", "l_hand", "suit", "shoes", "gloves", "ears", "glasses", "mask", "head", "belt", "r_pocket", "l_pocket", "back", "id", "neck", "backpack_contents", "suit_store")
for(var/slot in slots)
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 87330ce42c..1b280baa56 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -126,7 +126,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
"cock_diameter_ratio" = COCK_DIAMETER_RATIO_DEF,
"cock_color" = "fff",
"has_balls" = FALSE,
- "balls_internal" = FALSE,
"balls_color" = "fff",
"balls_shape" = DEF_BALLS_SHAPE,
"balls_size" = BALLS_SIZE_DEF,
@@ -141,12 +140,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
"has_vag" = FALSE,
"vag_shape" = DEF_VAGINA_SHAPE,
"vag_color" = "fff",
- "vag_clits" = 1,
- "vag_clit_diam" = 0.25,
"has_womb" = FALSE,
- "womb_cum_rate" = CUM_RATE,
- "womb_cum_mult" = CUM_RATE_MULT,
- "womb_efficiency" = CUM_EFFICIENCY,
+ "balls_visibility" = GEN_VISIBLE_NO_UNDIES,
+ "breasts_visibility"= GEN_VISIBLE_NO_UNDIES,
+ "cock_visibility" = GEN_VISIBLE_NO_UNDIES,
+ "vag_visibility" = GEN_VISIBLE_NO_UNDIES,
"ipc_screen" = "Sunburst",
"ipc_antenna" = "None",
"flavor_text" = "",
@@ -763,6 +761,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += " Change
"
dat += "Penis Shape: [features["cock_shape"]]"
dat += "Penis Length: [features["cock_length"]] inch(es)"
+ dat += "Penis Visibility:[features["cock_visibility"]]"
dat += "Has Testicles:[features["has_balls"] == TRUE ? "Yes" : "No"]"
if(features["has_balls"])
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
@@ -771,7 +770,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
dat += "Testicles Color:
"
dat += " Change
"
- dat += "Testicles showing:[features["balls_shape"]]"
+ dat += "Testicles Visibility:[features["balls_visibility"]]"
dat += APPEARANCE_CATEGORY_COLUMN
dat += "
Vagina
"
dat += "[features["has_vag"] == TRUE ? "Yes" : "No"]"
@@ -783,6 +782,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
dat += "Vagina Color:
"
dat += " Change
"
+ dat += "Vagina Visibility:[features["vag_visibility"]]"
dat += "Has Womb:[features["has_womb"] == TRUE ? "Yes" : "No"]"
dat += ""
dat += APPEARANCE_CATEGORY_COLUMN
@@ -796,7 +796,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "Color:
"
dat += " Change
"
dat += "Cup Size:[features["breasts_size"]]"
- dat += "Breast Shape:[features["breasts_shape"]]"
+ dat += "Breasts Shape:[features["breasts_shape"]]"
+ dat += "Breasts Visibility:[features["breasts_visibility"]]"
dat += "Lactates:[features["breasts_producing"] == TRUE ? "Yes" : "No"]"
dat += ""
dat += ""
@@ -1939,8 +1940,13 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(new_shape)
features["cock_shape"] = new_shape
+ if("cock_visibility")
+ var/n_vis = input(user, "Penis Visibility", "Character Preference") as null|anything in CONFIG_GET(keyed_list/safe_visibility_toggles)
+ if(n_vis)
+ features["cock_visibility"] = n_vis
+
if("balls_color")
- var/new_ballscolor = input(user, "Testicle Color:", "Character Preference") as color|null
+ var/new_ballscolor = input(user, "Testicles Color:", "Character Preference") as color|null
if(new_ballscolor)
var/temp_hsv = RGBtoHSV(new_ballscolor)
if(new_ballscolor == "#000000")
@@ -1950,11 +1956,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
to_chat(user,"Invalid color. Your color is not bright enough.")
- if("balls_shape")
- var/new_shape
- new_shape = input(user, "Testicle Type:", "Character Preference") as null|anything in GLOB.balls_shapes_list
- if(new_shape)
- features["balls_shape"] = new_shape
+ if("balls_visibility")
+ var/n_vis = input(user, "Testicles Visibility", "Character Preference") as null|anything in CONFIG_GET(keyed_list/safe_visibility_toggles)
+ if(n_vis)
+ features["balls_visibility"] = n_vis
if("breasts_size")
var/new_size = input(user, "Breast Size", "Character Preference") as null|anything in CONFIG_GET(keyed_list/breasts_cups_prefs)
@@ -1978,6 +1983,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
to_chat(user,"Invalid color. Your color is not bright enough.")
+ if("breasts_visibility")
+ var/n_vis = input(user, "Breasts Visibility", "Character Preference") as null|anything in CONFIG_GET(keyed_list/safe_visibility_toggles)
+ if(n_vis)
+ features["breasts_visibility"] = n_vis
+
if("vag_shape")
var/new_shape
new_shape = input(user, "Vagina Type", "Character Preference") as null|anything in GLOB.vagina_shapes_list
@@ -1995,6 +2005,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
to_chat(user,"Invalid color. Your color is not bright enough.")
+ if("vag_visibility")
+ var/n_vis = input(user, "Vagina Visibility", "Character Preference") as null|anything in CONFIG_GET(keyed_list/safe_visibility_toggles)
+ if(n_vis)
+ features["vag_visibility"] = n_vis
+
if("ooccolor")
var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference",ooccolor) as color|null
if(new_ooccolor)
@@ -2088,8 +2103,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
features["has_balls"] = FALSE
if("has_balls")
features["has_balls"] = !features["has_balls"]
- if("balls_internal")
- features["balls_internal"] = !features["balls_internal"]
if("has_breasts")
features["has_breasts"] = !features["has_breasts"]
if(features["has_breasts"] == FALSE)
@@ -2409,6 +2422,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
character.Digitigrade_Leg_Swap(TRUE)
+ character.give_genitals(TRUE) //character.update_genitals() is already called on genital.update_appearance()
+
SEND_SIGNAL(character, COMSIG_HUMAN_PREFS_COPIED_TO, src, icon_updates, roundstart_checks)
//let's be sure the character updates
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm b/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm
index abe51bf486..4365e59a7a 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/_sprite_accessories.dm
@@ -71,11 +71,13 @@
//for snowflake/donor specific sprites
var/list/ckeys_allowed
-
+
//For soft-restricting markings to species IDs
var/list/recommended_species
/datum/sprite_accessory/underwear
icon = 'icons/mob/underwear.dmi'
var/has_color = FALSE
- var/has_digitigrade = FALSE
\ No newline at end of file
+ var/has_digitigrade = FALSE
+ var/covers_groin = FALSE
+ var/covers_chest = FALSE
\ No newline at end of file
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm b/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm
index 58c64dc7d0..73233f3e09 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/undershirt.dm
@@ -2,9 +2,13 @@
// Undershirt Definitions //
////////////////////////////
+/datum/sprite_accessory/underwear/top
+ covers_chest = TRUE
+
/datum/sprite_accessory/underwear/top/nude
name = "Nude"
icon_state = null
+ covers_chest = FALSE
// please make sure they're sorted alphabetically and categorized
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm b/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm
index 9441b5120a..58d5e1ba88 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/underwear.dm
@@ -2,9 +2,13 @@
// Underwear Definitions //
///////////////////////////
+/datum/sprite_accessory/underwear/bottom
+ covers_groin = TRUE
+
/datum/sprite_accessory/underwear/bottom/nude
name = "Nude"
icon_state = null
+ covers_groin = FALSE
/datum/sprite_accessory/underwear/bottom/mankini
name = "Mankini"
@@ -155,16 +159,19 @@
name = "Swimsuit, One Piece - Red"
icon_state = "swimming_red"
gender = FEMALE
+ covers_chest = TRUE
/datum/sprite_accessory/underwear/bottom/swimsuit
name = "Swimsuit, One Piece - Black"
icon_state = "swimming_black"
gender = FEMALE
+ covers_chest = TRUE
/datum/sprite_accessory/underwear/bottom/swimsuit_blue
name = "Swimsuit, One Piece - Striped Blue"
icon_state = "swimming_blue"
gender = FEMALE
+ covers_chest = TRUE
/datum/sprite_accessory/underwear/bottom/thong
name = "Thong"
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 57667293e7..bbc109ab38 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -629,9 +629,8 @@
underwear = "Nude"
undershirt = "Nude"
socks = "Nude"
- update_body()
+ update_body(TRUE)
update_hair()
- update_genitals()
/mob/living/carbon/human/singularity_pull(S, current_size)
..()
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 66233f7243..bb80f7555c 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -57,10 +57,12 @@ There are several things that need to be remembered:
dna.species.handle_mutant_bodyparts(src)
-/mob/living/carbon/human/update_body()
+/mob/living/carbon/human/update_body(update_genitals = FALSE)
remove_overlay(BODY_LAYER)
dna.species.handle_body(src)
..()
+ if(update_genitals)
+ update_genitals()
/mob/living/carbon/human/update_fire()
..((fire_stacks > 3) ? "Standing" : "Generic_mob_burning")
@@ -72,7 +74,7 @@ There are several things that need to be remembered:
if(!..())
icon_render_key = null //invalidate bodyparts cache
- update_body()
+ update_body(TRUE)
update_hair()
update_inv_w_uniform()
update_inv_wear_id()
diff --git a/modular_citadel/code/modules/arousal/arousal.dm b/modular_citadel/code/modules/arousal/arousal.dm
index 5c7d5a39e9..843672877e 100644
--- a/modular_citadel/code/modules/arousal/arousal.dm
+++ b/modular_citadel/code/modules/arousal/arousal.dm
@@ -33,7 +33,7 @@
hidden_underwear = on_off
hidden_socks = on_off
- update_body()
+ update_body(TRUE)
/mob/living/carbon/human/proc/adjust_arousal(strength,aphro = FALSE,maso = FALSE) // returns all genitals that were adjust
diff --git a/modular_citadel/code/modules/arousal/genitals.dm b/modular_citadel/code/modules/arousal/genitals.dm
index 6f0588f76e..87379274b6 100644
--- a/modular_citadel/code/modules/arousal/genitals.dm
+++ b/modular_citadel/code/modules/arousal/genitals.dm
@@ -41,6 +41,9 @@
return
update_size()
update_appearance()
+ if(genital_flags & UPDATE_OWNER_APPEARANCE && owner && ishuman(owner))
+ var/mob/living/carbon/human/H = owner
+ H.update_genitals()
if(linked_organ_slot || (linked_organ && !owner))
update_link()
@@ -49,9 +52,16 @@
var/list/exposed_genitals = list() //Keeping track of them so we don't have to iterate through every genitalia and see if exposed
/obj/item/organ/genital/proc/is_exposed()
- if(!owner || CHECK_BITFIELD(genital_flags, GENITAL_INTERNAL) || CHECK_BITFIELD(genital_flags, GENITAL_HIDDEN))
+ if(!owner || genital_flags & (GENITAL_INTERNAL|GENITAL_HIDDEN))
return FALSE
- if(CHECK_BITFIELD(genital_flags, GENITAL_THROUGH_CLOTHES))
+ if(genital_flags & GENITAL_UNDIES_HIDDEN && ishuman(owner))
+ var/mob/living/carbon/human/H = owner
+ if(!(NO_UNDERWEAR in H.dna.species.species_traits))
+ var/datum/sprite_accessory/underwear/top/T = GLOB.undershirt_list[H.undershirt]
+ var/datum/sprite_accessory/underwear/bottom/B = GLOB.underwear_list[H.underwear]
+ if(zone == BODY_ZONE_CHEST ? (H.hidden_undershirt || T?.covers_chest || B?.covers_chest) : (H.hidden_underwear || T?.covers_groin || B?.covers_groin))
+ return FALSE
+ if(genital_flags & GENITAL_THROUGH_CLOTHES)
return TRUE
switch(zone) //update as more genitals are added
@@ -60,25 +70,19 @@
if(BODY_ZONE_PRECISE_GROIN)
return owner.is_groin_exposed()
-/obj/item/organ/genital/proc/toggle_visibility(visibility)
+/obj/item/organ/genital/proc/toggle_visibility(visibility, update = TRUE)
+ genital_flags &= ~(GENITAL_THROUGH_CLOTHES|GENITAL_HIDDEN|GENITAL_UNDIES_HIDDEN)
+ owner.exposed_genitals -= src
switch(visibility)
- if("Always visible")
- ENABLE_BITFIELD(genital_flags, GENITAL_THROUGH_CLOTHES)
- DISABLE_BITFIELD(genital_flags, GENITAL_HIDDEN)
- if(!(src in owner.exposed_genitals))
- owner.exposed_genitals += src
- if("Hidden by clothes")
- DISABLE_BITFIELD(genital_flags, GENITAL_THROUGH_CLOTHES)
- DISABLE_BITFIELD(genital_flags, GENITAL_HIDDEN)
- if(src in owner.exposed_genitals)
- owner.exposed_genitals -= src
- if("Always hidden")
- DISABLE_BITFIELD(genital_flags, GENITAL_THROUGH_CLOTHES)
- ENABLE_BITFIELD(genital_flags, GENITAL_HIDDEN)
- if(src in owner.exposed_genitals)
- owner.exposed_genitals -= src
+ if(GEN_VISIBLE_ALWAYS)
+ genital_flags |= GENITAL_THROUGH_CLOTHES
+ owner.exposed_genitals += src
+ if(GEN_VISIBLE_NO_UNDIES)
+ genital_flags |= GENITAL_UNDIES_HIDDEN
+ if(GEN_VISIBLE_NEVER)
+ genital_flags |= GENITAL_HIDDEN
- if(ishuman(owner)) //recast to use update genitals proc
+ if(update && ishuman(owner)) //recast to use update genitals proc
var/mob/living/carbon/human/H = owner
H.update_genitals()
@@ -87,6 +91,10 @@
set name = "Expose/Hide genitals"
set desc = "Allows you to toggle which genitals should show through clothes or not."
+ if(stat != CONSCIOUS)
+ to_chat(usr, "You can toggle genitals visibility right now...")
+ return
+
var/list/genital_list = list()
for(var/obj/item/organ/genital/G in internal_organs)
if(!CHECK_BITFIELD(G.genital_flags, GENITAL_INTERNAL))
@@ -95,10 +103,11 @@
return
//Full list of exposable genitals created
var/obj/item/organ/genital/picked_organ
- picked_organ = input(src, "Choose which genitalia to expose/hide", "Expose/Hide genitals", null) in genital_list
- if(picked_organ)
- var/picked_visibility = input(src, "Choose visibility setting", "Expose/Hide genitals", "Hidden by clothes") in list("Always visible", "Hidden by clothes", "Always hidden")
- picked_organ.toggle_visibility(picked_visibility)
+ picked_organ = input(src, "Choose which genitalia to expose/hide", "Expose/Hide genitals") as null|anything in genital_list
+ if(picked_organ && (picked_organ in internal_organs))
+ var/picked_visibility = input(src, "Choose visibility setting", "Expose/Hide genitals") as null|anything in GLOB.genitals_visibility_toggles
+ if(picked_visibility && picked_organ && (picked_organ in internal_organs))
+ picked_organ.toggle_visibility(picked_visibility)
return
/mob/living/carbon/verb/toggle_arousal_state()
@@ -256,6 +265,7 @@
var/list/gen_index[GENITAL_LAYER_INDEX_LENGTH]
var/list/genitals_to_add
var/list/fully_exposed
+ var/list/somewhat_exposed
for(var/obj/item/organ/genital/G in internal_organs)
if(G.is_exposed()) //Checks appropriate clothing slot and if it's through_clothes
LAZYADD(gen_index[G.layer_index], G)
@@ -306,9 +316,13 @@
genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size][dna.species.use_skintones ? "_s" : ""]_[aroused_state]_[layertext]"
- if(layers_num[layer] == GENITALS_FRONT_LAYER && CHECK_BITFIELD(G.genital_flags, GENITAL_THROUGH_CLOTHES))
- genital_overlay.layer = -GENITALS_EXPOSED_LAYER
- LAZYADD(fully_exposed, genital_overlay) // to be added to a layer with higher priority than clothes, hence the name of the bitflag.
+ if(layers_num[layer] == GENITALS_FRONT_LAYER)
+ if(G.genital_flags & GENITAL_THROUGH_CLOTHES)
+ genital_overlay.layer = -GENITALS_EXPOSED_LAYER
+ LAZYADD(fully_exposed, genital_overlay)
+ else if(!(G.genital_flags & GENITAL_UNDIES_HIDDEN))
+ genital_overlay.layer = -GENITALS_NO_UNDIE_LAYER
+ LAZYADD(somewhat_exposed, genital_overlay)
else
genital_overlay.layer = -layers_num[layer]
standing += genital_overlay
@@ -320,6 +334,10 @@
overlays_standing[GENITALS_EXPOSED_LAYER] = fully_exposed
apply_overlay(GENITALS_EXPOSED_LAYER)
+ if(LAZYLEN(somewhat_exposed))
+ overlays_standing[GENITALS_NO_UNDIE_LAYER] = somewhat_exposed
+ apply_overlay(GENITALS_NO_UNDIE_LAYER)
+
for(var/L in relevant_layers)
apply_overlay(layers_num[L])
diff --git a/modular_citadel/code/modules/arousal/genitals_sprite_accessories.dm b/modular_citadel/code/modules/arousal/genitals_sprite_accessories.dm
index 07453facdf..92c643c4bd 100644
--- a/modular_citadel/code/modules/arousal/genitals_sprite_accessories.dm
+++ b/modular_citadel/code/modules/arousal/genitals_sprite_accessories.dm
@@ -74,13 +74,9 @@
name = "testicle" //the preview name of the accessory
color_src = "balls_color"
-/datum/sprite_accessory/testicles/hidden
- icon_state = "none"
- name = "Hidden"
-
/datum/sprite_accessory/testicles/single
icon_state = "single"
- name = "Single"
+ name = "Single" //Single as "single pair", for clarity.
//Vaginas
/datum/sprite_accessory/vagina
diff --git a/modular_citadel/code/modules/arousal/organs/breasts.dm b/modular_citadel/code/modules/arousal/organs/breasts.dm
index bfa506da6d..8183ba92bc 100644
--- a/modular_citadel/code/modules/arousal/organs/breasts.dm
+++ b/modular_citadel/code/modules/arousal/organs/breasts.dm
@@ -12,7 +12,7 @@
fluid_id = /datum/reagent/consumable/milk
fluid_rate = MILK_RATE
shape = DEF_BREASTS_SHAPE
- genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH|GENITAL_FUID_PRODUCTION|GENITAL_CAN_AROUSE
+ genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH|GENITAL_FUID_PRODUCTION|GENITAL_CAN_AROUSE|UPDATE_OWNER_APPEARANCE|GENITAL_UNDIES_HIDDEN
masturbation_verb = "massage"
arousal_verb = "Your breasts start feeling sensitive"
unarousal_verb = "Your breasts no longer feel sensitive"
@@ -64,9 +64,6 @@
icon_state += "_s"
else
color = "#[owner.dna.features["breasts_color"]]"
- if(ishuman(owner))
- var/mob/living/carbon/human/H = owner
- H.update_genitals()
//Allows breasts to grow and change size, with sprite changes too.
//maximum wah
@@ -133,6 +130,7 @@
cached_size = size
size = breast_values[size]
prev_size = cached_size
+ toggle_visibility(D.features["breasts_visibility"], FALSE)
#undef BREASTS_ICON_MIN_SIZE
#undef BREASTS_ICON_MAX_SIZE
\ No newline at end of file
diff --git a/modular_citadel/code/modules/arousal/organs/penis.dm b/modular_citadel/code/modules/arousal/organs/penis.dm
index 294ac6c877..ded05134a9 100644
--- a/modular_citadel/code/modules/arousal/organs/penis.dm
+++ b/modular_citadel/code/modules/arousal/organs/penis.dm
@@ -8,7 +8,7 @@
masturbation_verb = "stroke"
arousal_verb = "You pop a boner"
unarousal_verb = "Your boner goes down"
- genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH|GENITAL_CAN_AROUSE
+ genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH|GENITAL_CAN_AROUSE|UPDATE_OWNER_APPEARANCE|GENITAL_UNDIES_HIDDEN
linked_organ_slot = ORGAN_SLOT_TESTICLES
fluid_transfer_factor = 0.5
shape = DEF_COCK_SHAPE
@@ -66,9 +66,9 @@
if(owner)
if (round(length) > round(prev_length))
- to_chat(owner, "Your [pick(GLOB.gentlemans_organ_names)] [pick("swells up to", "flourishes into", "expands into", "bursts forth into", "grows eagerly into", "amplifys into")] a [uppertext(round(length))] inch penis.")
+ to_chat(owner, "Your [pick(GLOB.dick_nouns)] [pick("swells up to", "flourishes into", "expands into", "bursts forth into", "grows eagerly into", "amplifys into")] a [uppertext(round(length))] inch penis.")
else if ((round(length) < round(prev_length)) && (length > 0.5))
- to_chat(owner, "Your [pick(GLOB.gentlemans_organ_names)] [pick("shrinks down to", "decreases into", "diminishes into", "deflates into", "shrivels regretfully into", "contracts into")] a [uppertext(round(length))] inch penis.")
+ to_chat(owner, "Your [pick(GLOB.dick_nouns)] [pick("shrinks down to", "decreases into", "diminishes into", "deflates into", "shrivels regretfully into", "contracts into")] a [uppertext(round(length))] inch penis.")
icon_state = sanitize_text("penis_[shape]_[size]")
diameter = (length * diameter_ratio)//Is it just me or is this ludicous, why not make it exponentially decay?
@@ -89,9 +89,6 @@
icon_state += "_s"
else
color = "#[owner.dna.features["cock_color"]]"
- if(ishuman(owner))
- var/mob/living/carbon/human/H = owner
- H.update_genitals()
/obj/item/organ/genital/penis/get_features(mob/living/carbon/human/H)
var/datum/dna/D = H.dna
@@ -103,3 +100,4 @@
diameter_ratio = D.features["cock_diameter_ratio"]
shape = D.features["cock_shape"]
prev_length = length
+ toggle_visibility(D.features["cock_visibility"], FALSE)
\ No newline at end of file
diff --git a/modular_citadel/code/modules/arousal/organs/testicles.dm b/modular_citadel/code/modules/arousal/organs/testicles.dm
index cf4480ff1f..4264cf5e48 100644
--- a/modular_citadel/code/modules/arousal/organs/testicles.dm
+++ b/modular_citadel/code/modules/arousal/organs/testicles.dm
@@ -9,7 +9,7 @@
arousal_verb = "Your balls ache a little"
unarousal_verb = "Your balls finally stop aching, again"
linked_organ_slot = ORGAN_SLOT_PENIS
- genital_flags = CAN_MASTURBATE_WITH|MASTURBATE_LINKED_ORGAN|GENITAL_FUID_PRODUCTION
+ genital_flags = CAN_MASTURBATE_WITH|MASTURBATE_LINKED_ORGAN|GENITAL_FUID_PRODUCTION|UPDATE_OWNER_APPEARANCE|GENITAL_UNDIES_HIDDEN
var/size_name = "average"
shape = DEF_BALLS_SHAPE
fluid_id = /datum/reagent/consumable/semen
@@ -53,9 +53,6 @@
icon_state += "_s"
else
color = "#[owner.dna.features["balls_color"]]"
- if(ishuman(owner))
- var/mob/living/carbon/human/H = owner
- H.update_genitals()
/obj/item/organ/genital/testicles/get_features(mob/living/carbon/human/H)
var/datum/dna/D = H.dna
@@ -64,8 +61,7 @@
else
color = "#[D.features["balls_color"]]"
shape = D.features["balls_shape"]
- if(D.features["balls_shape"] == "Hidden")
- ENABLE_BITFIELD(genital_flags, GENITAL_INTERNAL)
fluid_rate = D.features["balls_cum_rate"]
fluid_mult = D.features["balls_cum_mult"]
fluid_efficiency = D.features["balls_efficiency"]
+ toggle_visibility(D.features["balls_visibility"], FALSE)
\ No newline at end of file
diff --git a/modular_citadel/code/modules/arousal/organs/vagina.dm b/modular_citadel/code/modules/arousal/organs/vagina.dm
index 91c3b8b8e9..f7e8eddcbd 100644
--- a/modular_citadel/code/modules/arousal/organs/vagina.dm
+++ b/modular_citadel/code/modules/arousal/organs/vagina.dm
@@ -7,7 +7,7 @@
slot = "vagina"
size = 1 //There is only 1 size right now
shape = DEF_VAGINA_SHAPE
- genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH|GENITAL_CAN_AROUSE
+ genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH|GENITAL_CAN_AROUSE|GENITAL_UNDIES_HIDDEN
masturbation_verb = "finger"
arousal_verb = "You feel wetness on your crotch"
unarousal_verb = "You no longer feel wet"
@@ -70,3 +70,4 @@
else
color = "[D.features["vag_color"]]"
shape = "[D.features["vag_shape"]]"
+ toggle_visibility(D.features["vag_visibility"], FALSE)
diff --git a/modular_citadel/code/modules/client/preferences.dm b/modular_citadel/code/modules/client/preferences.dm
index f1dbe31d02..8c55f2d9a8 100644
--- a/modular_citadel/code/modules/client/preferences.dm
+++ b/modular_citadel/code/modules/client/preferences.dm
@@ -45,9 +45,3 @@
else
if(L[slot_to_string(slot)] < DEFAULT_SLOT_AMT)
return TRUE
-
-/datum/preferences/copy_to(mob/living/carbon/human/character, icon_updates = 1)
- ..()
- character.give_genitals(TRUE)
- if(icon_updates)
- character.update_genitals()
From c1e13a83fbba9c814e863ff754e9bb3dab92ccaa Mon Sep 17 00:00:00 2001
From: Ghommie <42542238+Ghommie@users.noreply.github.com>
Date: Wed, 25 Mar 2020 03:35:29 +0100
Subject: [PATCH 02/75] Boom.
---
code/__DEFINES/misc.dm | 19 ++++---
code/modules/client/preferences_savefile.dm | 51 +++++++++++++++++--
.../code/modules/arousal/genitals.dm | 15 ++----
.../modules/client/preferences_savefile.dm | 23 ---------
4 files changed, 58 insertions(+), 50 deletions(-)
diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 3a1e44f053..89cacc1c7b 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -27,15 +27,14 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
//Human Overlays Indexes/////////
//LOTS OF CIT CHANGES HERE. BE CAREFUL WHEN UPSTREAM ADDS MORE LAYERS
-#define MUTATIONS_LAYER 33 //mutations. Tk headglows, cold resistance glow, etc
-#define GENITALS_BEHIND_LAYER 32 //Some genitalia needs to be behind everything, such as with taurs (Taurs use body_behind_layer
-#define BODY_BEHIND_LAYER 31 //certain mutantrace features (tail when looking south) that must appear behind the body parts
-#define BODYPARTS_LAYER 30 //Initially "AUGMENTS", this was repurposed to be a catch-all bodyparts flag
-#define MARKING_LAYER 29 //Matrixed body markings because clashing with snouts?
-#define BODY_ADJ_LAYER 28 //certain mutantrace features (snout, body markings) that must appear above the body parts
-#define GENITALS_FRONT_LAYER 27 //Draws some genitalia above clothes and the TAUR body if need be.
-#define BODY_LAYER 26 //underwear, undershirts, socks, eyes, lips(makeup)
-#define GENITALS_NO_UNDIE_LAYER 25 //found above undergarments.
+#define MUTATIONS_LAYER 32 //mutations. Tk headglows, cold resistance glow, etc
+#define GENITALS_BEHIND_LAYER 31 //Some genitalia needs to be behind everything, such as with taurs (Taurs use body_behind_layer
+#define BODY_BEHIND_LAYER 30 //certain mutantrace features (tail when looking south) that must appear behind the body parts
+#define BODYPARTS_LAYER 29 //Initially "AUGMENTS", this was repurposed to be a catch-all bodyparts flag
+#define MARKING_LAYER 28 //Matrixed body markings because clashing with snouts?
+#define BODY_ADJ_LAYER 27 //certain mutantrace features (snout, body markings) that must appear above the body parts
+#define GENITALS_FRONT_LAYER 26 //Draws some genitalia above clothes and the TAUR body if need be.
+#define BODY_LAYER 25 //underwear, undershirts, socks, eyes, lips(makeup)
#define FRONT_MUTATIONS_LAYER 24 //mutations that should appear above body, body_adj and bodyparts layer (e.g. laser eyes)
#define DAMAGE_LAYER 23 //damage indicators (cuts and burns)
#define UNIFORM_LAYER 22
@@ -60,7 +59,7 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
#define HANDS_LAYER 3
#define BODY_FRONT_LAYER 2
#define FIRE_LAYER 1 //If you're on fire
-#define TOTAL_LAYERS 33 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_;
+#define TOTAL_LAYERS 32 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_;
//Human Overlay Index Shortcuts for alternate_worn_layer, layers
//Because I *KNOW* somebody will think layer+1 means "above"
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index 69b8b5685f..76fc40b115 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -5,7 +5,7 @@
// You do not need to raise this if you are adding new values that have sane defaults.
// Only raise this value when changing the meaning/format/name/layout of an existing value
// where you would want the updater procs below to run
-#define SAVEFILE_VERSION_MAX 26
+#define SAVEFILE_VERSION_MAX 27
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
@@ -145,6 +145,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(features["meat_type"] == "Inesct")
features["meat_type"] = "Insect"
+ if(current_version < 27)
+ var/tennis
+ S["feature_balls_shape"] >> tennis
+ if(tennis == "Hidden")
+ features["balls_visibility"] = GEN_VISIBLE_NEVER
+
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
if(!ckey)
return
@@ -447,22 +453,24 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["feature_cock_color"] >> features["cock_color"]
S["feature_cock_length"] >> features["cock_length"]
S["feature_cock_diameter"] >> features["cock_diameter"]
- S["feature_has_sheath"] >> features["sheath_color"]
+ S["feature_cock_visibility"] >> features["cock_visibility"]
//balls features
S["feature_has_balls"] >> features["has_balls"]
S["feature_balls_color"] >> features["balls_color"]
S["feature_balls_size"] >> features["balls_size"]
- S["feature_balls_shape"] >> features["balls_shape"]
+ S["feature_balls_visibility"] >> features["balls_visibility"]
//breasts features
S["feature_has_breasts"] >> features["has_breasts"]
S["feature_breasts_size"] >> features["breasts_size"]
S["feature_breasts_shape"] >> features["breasts_shape"]
S["feature_breasts_color"] >> features["breasts_color"]
S["feature_breasts_producing"] >> features["breasts_producing"]
+ S["feature_breasts_visibility"] >> features["breasts_visibility"]
//vagina features
S["feature_has_vag"] >> features["has_vag"]
S["feature_vag_shape"] >> features["vag_shape"]
S["feature_vag_color"] >> features["vag_color"]
+ S["feature_vag_visibility"] >> features["vag_visibility"]
//womb features
S["feature_has_womb"] >> features["has_womb"]
//flavor text
@@ -549,14 +557,18 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
var/static/list/B_sizes
if(!B_sizes)
- B_sizes = CONFIG_GET(keyed_list/breasts_cups_prefs)
- B_sizes = B_sizes.Copy()
+ var/list/L = CONFIG_GET(keyed_list/breasts_cups_prefs)
+ B_sizes = L.Copy()
var/static/min_D
if(!min_D)
min_D = CONFIG_GET(number/penis_min_inches_prefs)
var/static/max_D
if(!max_D)
max_D = CONFIG_GET(number/penis_max_inches_prefs)
+ var/static/safe_visibilities
+ if(!safe_visibilities)
+ var/list/L = CONFIG_GET(keyed_list/safe_visibility_toggles)
+ safe_visibilities = L.Copy()
features["breasts_size"] = sanitize_inlist(features["breasts_size"], B_sizes, BREASTS_SIZE_DEF)
features["cock_length"] = sanitize_integer(features["cock_length"], min_D, max_D, COCK_SIZE_DEF)
@@ -568,6 +580,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
features["cock_color"] = sanitize_hexcolor(features["cock_color"], 3, FALSE, "FFF")
features["balls_color"] = sanitize_hexcolor(features["balls_color"], 3, FALSE, "FFF")
features["vag_color"] = sanitize_hexcolor(features["vag_color"], 3, FALSE, "FFF")
+ features["breasts_visibility"] = sanitize_inlist(features["breasts_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES)
+ features["cock_visibility"] = sanitize_inlist(features["cock_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES)
+ features["balls_visibility"] = sanitize_inlist(features["balls_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES)
+ features["vag_visibility"] = sanitize_inlist(features["vag_visibility"], safe_visibilities, GEN_VISIBLE_NO_UNDIES)
+
features["flavor_text"] = copytext(features["flavor_text"], 1, MAX_FLAVOR_LEN)
@@ -648,6 +665,30 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["feature_insect_markings"] , features["insect_markings"])
WRITE_FILE(S["feature_meat"] , features["meat_type"])
+ WRITE_FILE(S["feature_has_cock"], features["has_cock"])
+ WRITE_FILE(S["feature_cock_shape"], features["cock_shape"])
+ WRITE_FILE(S["feature_cock_color"], features["cock_color"])
+ WRITE_FILE(S["feature_cock_length"], features["cock_length"])
+ WRITE_FILE(S["feature_cock_visibility"], features["cock_visibility"])
+
+ WRITE_FILE(S["feature_has_balls"], features["has_balls"])
+ WRITE_FILE(S["feature_balls_color"], features["balls_color"])
+ WRITE_FILE(S["feature_balls_size"], features["balls_size"])
+ WRITE_FILE(S["feature_balls_visibility"], features["balls_visibility"])
+
+ WRITE_FILE(S["feature_has_breasts"], features["has_breasts"])
+ WRITE_FILE(S["feature_breasts_size"], features["breasts_size"])
+ WRITE_FILE(S["feature_breasts_shape"], features["breasts_shape"])
+ WRITE_FILE(S["feature_breasts_color"], features["breasts_color"])
+ WRITE_FILE(S["feature_breasts_producing"], features["breasts_producing"])
+ WRITE_FILE(S["feature_breasts_visibility"], features["breasts_visibility"])
+
+ WRITE_FILE(S["feature_has_vag"], features["has_vag"])
+ WRITE_FILE(S["feature_vag_shape"], features["vag_shape"])
+ WRITE_FILE(S["feature_vag_color"], features["vag_color"])
+ WRITE_FILE(S["feature_vag_visibility"], features["vag_visibility"])
+
+ WRITE_FILE(S["feature_has_womb"], features["has_womb"])
//Custom names
for(var/custom_name_id in GLOB.preferences_custom_names)
diff --git a/modular_citadel/code/modules/arousal/genitals.dm b/modular_citadel/code/modules/arousal/genitals.dm
index 87379274b6..74a05488fa 100644
--- a/modular_citadel/code/modules/arousal/genitals.dm
+++ b/modular_citadel/code/modules/arousal/genitals.dm
@@ -265,7 +265,6 @@
var/list/gen_index[GENITAL_LAYER_INDEX_LENGTH]
var/list/genitals_to_add
var/list/fully_exposed
- var/list/somewhat_exposed
for(var/obj/item/organ/genital/G in internal_organs)
if(G.is_exposed()) //Checks appropriate clothing slot and if it's through_clothes
LAZYADD(gen_index[G.layer_index], G)
@@ -316,13 +315,9 @@
genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size][dna.species.use_skintones ? "_s" : ""]_[aroused_state]_[layertext]"
- if(layers_num[layer] == GENITALS_FRONT_LAYER)
- if(G.genital_flags & GENITAL_THROUGH_CLOTHES)
- genital_overlay.layer = -GENITALS_EXPOSED_LAYER
- LAZYADD(fully_exposed, genital_overlay)
- else if(!(G.genital_flags & GENITAL_UNDIES_HIDDEN))
- genital_overlay.layer = -GENITALS_NO_UNDIE_LAYER
- LAZYADD(somewhat_exposed, genital_overlay)
+ if(layers_num[layer] == GENITALS_FRONT_LAYER && G.genital_flags & GENITAL_THROUGH_CLOTHES)
+ genital_overlay.layer = -GENITALS_EXPOSED_LAYER
+ LAZYADD(fully_exposed, genital_overlay)
else
genital_overlay.layer = -layers_num[layer]
standing += genital_overlay
@@ -334,10 +329,6 @@
overlays_standing[GENITALS_EXPOSED_LAYER] = fully_exposed
apply_overlay(GENITALS_EXPOSED_LAYER)
- if(LAZYLEN(somewhat_exposed))
- overlays_standing[GENITALS_NO_UNDIE_LAYER] = somewhat_exposed
- apply_overlay(GENITALS_NO_UNDIE_LAYER)
-
for(var/L in relevant_layers)
apply_overlay(layers_num[L])
diff --git a/modular_citadel/code/modules/client/preferences_savefile.dm b/modular_citadel/code/modules/client/preferences_savefile.dm
index 80e20c9f48..d9b902656f 100644
--- a/modular_citadel/code/modules/client/preferences_savefile.dm
+++ b/modular_citadel/code/modules/client/preferences_savefile.dm
@@ -44,29 +44,6 @@
WRITE_FILE(S["feature_xeno_tail"], features["xenotail"])
WRITE_FILE(S["feature_xeno_dors"], features["xenodorsal"])
WRITE_FILE(S["feature_xeno_head"], features["xenohead"])
- //cock features
- WRITE_FILE(S["feature_has_cock"], features["has_cock"])
- WRITE_FILE(S["feature_cock_shape"], features["cock_shape"])
- WRITE_FILE(S["feature_cock_color"], features["cock_color"])
- WRITE_FILE(S["feature_cock_length"], features["cock_length"])
- WRITE_FILE(S["feature_cock_girth"], features["cock_girth"])
- //balls features
- WRITE_FILE(S["feature_has_balls"], features["has_balls"])
- WRITE_FILE(S["feature_balls_color"], features["balls_color"])
- WRITE_FILE(S["feature_balls_size"], features["balls_size"])
- WRITE_FILE(S["feature_balls_shape"], features["balls_shape"])
- //breasts features
- WRITE_FILE(S["feature_has_breasts"], features["has_breasts"])
- WRITE_FILE(S["feature_breasts_size"], features["breasts_size"])
- WRITE_FILE(S["feature_breasts_shape"], features["breasts_shape"])
- WRITE_FILE(S["feature_breasts_color"], features["breasts_color"])
- WRITE_FILE(S["feature_breasts_producing"], features["breasts_producing"])
- //vagina features
- WRITE_FILE(S["feature_has_vag"], features["has_vag"])
- WRITE_FILE(S["feature_vag_shape"], features["vag_shape"])
- WRITE_FILE(S["feature_vag_color"], features["vag_color"])
- //womb features
- WRITE_FILE(S["feature_has_womb"], features["has_womb"])
//flavor text
WRITE_FILE(S["feature_flavor_text"], features["flavor_text"])
From edfc77fc2a58d723db8f89a9b46d219a6bd6412c Mon Sep 17 00:00:00 2001
From: Ghom <42542238+Ghommie@users.noreply.github.com>
Date: Wed, 25 Mar 2020 04:18:01 +0100
Subject: [PATCH 03/75] Fixes cold movespeed slowdown affecting floating mobs
(no gravity).
---
code/modules/mob/living/carbon/human/species.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index d464419b73..a4d0c36ddc 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -2050,7 +2050,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "hot")
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "cold", /datum/mood_event/cold)
//Sorry for the nasty oneline but I don't want to assign a variable on something run pretty frequently
- H.add_movespeed_modifier(MOVESPEED_ID_COLD, override = TRUE, multiplicative_slowdown = ((BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR))
+ H.add_movespeed_modifier(MOVESPEED_ID_COLD, override = TRUE, multiplicative_slowdown = ((BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR), blacklisted_movetypes = FLOATING)
switch(H.bodytemperature)
if(200 to BODYTEMP_COLD_DAMAGE_LIMIT)
H.apply_damage(COLD_DAMAGE_LEVEL_1*coldmod*H.physiology.cold_mod, BURN)
From c6b4b5f68626f7bc3db9f44fcb824fb3f9410cde Mon Sep 17 00:00:00 2001
From: Ghommie <42542238+Ghommie@users.noreply.github.com>
Date: Wed, 25 Mar 2020 05:17:09 +0100
Subject: [PATCH 04/75] lazy fix before I go to sleep.
---
.../mob/living/carbon/human/species.dm | 71 +++++++++----------
.../code/modules/arousal/genitals.dm | 2 +-
2 files changed, 35 insertions(+), 38 deletions(-)
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index d464419b73..c566e16ad9 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -550,48 +550,45 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
//Underwear, Undershirts & Socks
if(!(NO_UNDERWEAR in species_traits))
- if(H.socks && H.get_num_legs(FALSE) >= 2)
- if(H.hidden_socks)
- H.socks = "Nude"
- else
+ if(H.socks && !H.hidden_socks && H.get_num_legs(FALSE) >= 2)
+ if(H.saved_socks)
H.socks = H.saved_socks
- var/datum/sprite_accessory/underwear/socks/S = GLOB.socks_list[H.socks]
- if(S)
- var/digilegs = ((DIGITIGRADE in species_traits) && S.has_digitigrade) ? "_d" : ""
- var/mutable_appearance/MA = mutable_appearance(S.icon, "[S.icon_state][digilegs]", -BODY_LAYER)
- if(S.has_color)
- MA.color = "#[H.socks_color]"
- standing += MA
+ H.saved_socks = ""
+ var/datum/sprite_accessory/underwear/socks/S = GLOB.socks_list[H.socks]
+ if(S)
+ var/digilegs = ((DIGITIGRADE in species_traits) && S.has_digitigrade) ? "_d" : ""
+ var/mutable_appearance/MA = mutable_appearance(S.icon, "[S.icon_state][digilegs]", -BODY_LAYER)
+ if(S.has_color)
+ MA.color = "#[H.socks_color]"
+ standing += MA
- if(H.underwear)
- if(H.hidden_underwear)
- H.underwear = "Nude"
- else
+ if(H.underwear && !H.hidden_underwear)
+ if(H.saved_underwear)
H.underwear = H.saved_underwear
- var/datum/sprite_accessory/underwear/bottom/B = GLOB.underwear_list[H.underwear]
- if(B)
- var/digilegs = ((DIGITIGRADE in species_traits) && B.has_digitigrade) ? "_d" : ""
- var/mutable_appearance/MA = mutable_appearance(B.icon, "[B.icon_state][digilegs]", -BODY_LAYER)
- if(B.has_color)
- MA.color = "#[H.undie_color]"
- standing += MA
+ H.saved_underwear = ""
+ var/datum/sprite_accessory/underwear/bottom/B = GLOB.underwear_list[H.underwear]
+ if(B)
+ var/digilegs = ((DIGITIGRADE in species_traits) && B.has_digitigrade) ? "_d" : ""
+ var/mutable_appearance/MA = mutable_appearance(B.icon, "[B.icon_state][digilegs]", -BODY_LAYER)
+ if(B.has_color)
+ MA.color = "#[H.undie_color]"
+ standing += MA
- if(H.undershirt)
- if(H.hidden_undershirt)
- H.undershirt = "Nude"
- else
+ if(H.undershirt && !H.hidden_undershirt)
+ if(H.saved_undershirt)
H.undershirt = H.saved_undershirt
- var/datum/sprite_accessory/underwear/top/T = GLOB.undershirt_list[H.undershirt]
- if(T)
- var/state = "[T.icon_state][((DIGITIGRADE in species_traits) && T.has_digitigrade) ? "_d" : ""]"
- var/mutable_appearance/MA
- if(H.dna.species.sexes && H.dna.features["body_model"] == FEMALE)
- MA = wear_female_version(state, T.icon, BODY_LAYER)
- else
- MA = mutable_appearance(T.icon, state, -BODY_LAYER)
- if(T.has_color)
- MA.color = "#[H.shirt_color]"
- standing += MA
+ H.saved_undershirt = ""
+ var/datum/sprite_accessory/underwear/top/T = GLOB.undershirt_list[H.undershirt]
+ if(T)
+ var/state = "[T.icon_state][((DIGITIGRADE in species_traits) && T.has_digitigrade) ? "_d" : ""]"
+ var/mutable_appearance/MA
+ if(H.dna.species.sexes && H.dna.features["body_model"] == FEMALE)
+ MA = wear_female_version(state, T.icon, BODY_LAYER)
+ else
+ MA = mutable_appearance(T.icon, state, -BODY_LAYER)
+ if(T.has_color)
+ MA.color = "#[H.shirt_color]"
+ standing += MA
if(standing.len)
H.overlays_standing[BODY_LAYER] = standing
diff --git a/modular_citadel/code/modules/arousal/genitals.dm b/modular_citadel/code/modules/arousal/genitals.dm
index 74a05488fa..f65267aa39 100644
--- a/modular_citadel/code/modules/arousal/genitals.dm
+++ b/modular_citadel/code/modules/arousal/genitals.dm
@@ -59,7 +59,7 @@
if(!(NO_UNDERWEAR in H.dna.species.species_traits))
var/datum/sprite_accessory/underwear/top/T = GLOB.undershirt_list[H.undershirt]
var/datum/sprite_accessory/underwear/bottom/B = GLOB.underwear_list[H.underwear]
- if(zone == BODY_ZONE_CHEST ? (H.hidden_undershirt || T?.covers_chest || B?.covers_chest) : (H.hidden_underwear || T?.covers_groin || B?.covers_groin))
+ if(zone == BODY_ZONE_CHEST ? (!H.hidden_undershirt && (T?.covers_chest || B?.covers_chest)) : (!H.hidden_underwear && (T?.covers_groin || B?.covers_groin)))
return FALSE
if(genital_flags & GENITAL_THROUGH_CLOTHES)
return TRUE
From 91aad127dd3045436fdf99cd015f7ef8f6f53826 Mon Sep 17 00:00:00 2001
From: Ghom <42542238+Ghommie@users.noreply.github.com>
Date: Wed, 25 Mar 2020 13:54:41 +0100
Subject: [PATCH 05/75] Quick webedit fixing an issue with the split
personality.
---
code/datums/brain_damage/split_personality.dm | 21 ++++++++-----------
1 file changed, 9 insertions(+), 12 deletions(-)
diff --git a/code/datums/brain_damage/split_personality.dm b/code/datums/brain_damage/split_personality.dm
index 6586a065d0..1115a878f8 100644
--- a/code/datums/brain_damage/split_personality.dm
+++ b/code/datums/brain_damage/split_personality.dm
@@ -20,6 +20,7 @@
..()
make_backseats()
get_ghost()
+ RegisterSignal(M, COMSIG_MOB_DEATH, .proc/revert_to_normal)
/datum/brain_trauma/severe/split_personality/proc/make_backseats()
stranger_backseat = new(owner, src)
@@ -37,23 +38,23 @@
qdel(src)
/datum/brain_trauma/severe/split_personality/on_life()
- if(owner.stat == DEAD)
- if(current_controller != OWNER)
- switch_personalities()
- qdel(src)
- else if(prob(3))
+ if(prob(3))
switch_personalities()
..()
/datum/brain_trauma/severe/split_personality/on_lose()
if(current_controller != OWNER) //it would be funny to cure a guy only to be left with the other personality, but it seems too cruel
- switch_personalities()
+ switch_personalities(TRUE)
QDEL_NULL(stranger_backseat)
QDEL_NULL(owner_backseat)
+ UnregisterSignal(M, COMSIG_MOB_DEATH)
..()
-/datum/brain_trauma/severe/split_personality/proc/switch_personalities()
- if(QDELETED(owner) || owner.stat == DEAD || QDELETED(stranger_backseat) || QDELETED(owner_backseat))
+/datum/brain_trauma/severe/split_personality/proc/revert_to_normal()
+ qdel(src)
+
+/datum/brain_trauma/severe/split_personality/proc/switch_personalities(forced = FALSE)
+ if(QDELETED(owner) || (owner.stat == DEAD && !forced) || QDELETED(stranger_backseat) || QDELETED(owner_backseat))
return
var/mob/living/split_personality/current_backseat
@@ -126,10 +127,6 @@
if(QDELETED(body))
qdel(src) //in case trauma deletion doesn't already do it
- if((body.stat == DEAD && trauma.owner_backseat == src))
- trauma.switch_personalities()
- qdel(trauma)
-
//if one of the two ghosts, the other one stays permanently
if(!body.client && trauma.initialized)
trauma.switch_personalities()
From c05d2c1572d6ba83f4fe402dcf8790313cfd9f8a Mon Sep 17 00:00:00 2001
From: Ghommie <42542238+Ghommie@users.noreply.github.com>
Date: Wed, 25 Mar 2020 17:08:09 +0100
Subject: [PATCH 06/75] Making it actually work.
---
code/modules/client/preferences.dm | 8 +++---
.../code/modules/arousal/genitals.dm | 27 ++++++++++++-------
2 files changed, 21 insertions(+), 14 deletions(-)
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 1b280baa56..424b913ece 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -761,7 +761,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += " Change
"
dat += "Penis Shape: [features["cock_shape"]]"
dat += "Penis Length: [features["cock_length"]] inch(es)"
- dat += "Penis Visibility:[features["cock_visibility"]]"
+ dat += "Penis Visibility:[features["cock_visibility"]]"
dat += "Has Testicles:[features["has_balls"] == TRUE ? "Yes" : "No"]"
if(features["has_balls"])
if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE)
@@ -770,7 +770,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
dat += "Testicles Color:
"
dat += " Change
"
- dat += "Testicles Visibility:[features["balls_visibility"]]"
+ dat += "Testicles Visibility:[features["balls_visibility"]]"
dat += APPEARANCE_CATEGORY_COLUMN
dat += "Vagina
"
dat += "[features["has_vag"] == TRUE ? "Yes" : "No"]"
@@ -782,7 +782,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
else
dat += "Vagina Color:
"
dat += " Change
"
- dat += "Vagina Visibility:[features["vag_visibility"]]"
+ dat += "Vagina Visibility:[features["vag_visibility"]]"
dat += "Has Womb:[features["has_womb"] == TRUE ? "Yes" : "No"]"
dat += ""
dat += APPEARANCE_CATEGORY_COLUMN
@@ -797,7 +797,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += " Change
"
dat += "Cup Size:[features["breasts_size"]]"
dat += "Breasts Shape:[features["breasts_shape"]]"
- dat += "Breasts Visibility:[features["breasts_visibility"]]"
+ dat += "Breasts Visibility:[features["breasts_visibility"]]"
dat += "Lactates:[features["breasts_producing"] == TRUE ? "Yes" : "No"]"
dat += ""
dat += ""
diff --git a/modular_citadel/code/modules/arousal/genitals.dm b/modular_citadel/code/modules/arousal/genitals.dm
index f65267aa39..8d505fd06c 100644
--- a/modular_citadel/code/modules/arousal/genitals.dm
+++ b/modular_citadel/code/modules/arousal/genitals.dm
@@ -57,9 +57,9 @@
if(genital_flags & GENITAL_UNDIES_HIDDEN && ishuman(owner))
var/mob/living/carbon/human/H = owner
if(!(NO_UNDERWEAR in H.dna.species.species_traits))
- var/datum/sprite_accessory/underwear/top/T = GLOB.undershirt_list[H.undershirt]
- var/datum/sprite_accessory/underwear/bottom/B = GLOB.underwear_list[H.underwear]
- if(zone == BODY_ZONE_CHEST ? (!H.hidden_undershirt && (T?.covers_chest || B?.covers_chest)) : (!H.hidden_underwear && (T?.covers_groin || B?.covers_groin)))
+ var/datum/sprite_accessory/underwear/top/T = H.hidden_undershirt ? null : GLOB.undershirt_list[H.undershirt]
+ var/datum/sprite_accessory/underwear/bottom/B = H.hidden_underwear ? null : GLOB.underwear_list[H.underwear]
+ if(zone == BODY_ZONE_CHEST ? (T?.covers_chest || B?.covers_chest) : (!T?.covers_groin || B?.covers_groin))
return FALSE
if(genital_flags & GENITAL_THROUGH_CLOTHES)
return TRUE
@@ -72,17 +72,19 @@
/obj/item/organ/genital/proc/toggle_visibility(visibility, update = TRUE)
genital_flags &= ~(GENITAL_THROUGH_CLOTHES|GENITAL_HIDDEN|GENITAL_UNDIES_HIDDEN)
- owner.exposed_genitals -= src
+ if(owner)
+ owner.exposed_genitals -= src
switch(visibility)
if(GEN_VISIBLE_ALWAYS)
genital_flags |= GENITAL_THROUGH_CLOTHES
- owner.exposed_genitals += src
+ if(owner)
+ owner.exposed_genitals += src
if(GEN_VISIBLE_NO_UNDIES)
genital_flags |= GENITAL_UNDIES_HIDDEN
if(GEN_VISIBLE_NEVER)
genital_flags |= GENITAL_HIDDEN
- if(update && ishuman(owner)) //recast to use update genitals proc
+ if(update && owner && ishuman(owner)) //recast to use update genitals proc
var/mob/living/carbon/human/H = owner
H.update_genitals()
@@ -191,14 +193,19 @@
if(.)
update()
RegisterSignal(owner, COMSIG_MOB_DEATH, .proc/update_appearance)
+ if(genital_flags & GENITAL_THROUGH_CLOTHES)
+ owner.exposed_genitals += src
/obj/item/organ/genital/Remove(special = FALSE)
. = ..()
- var/mob/living/carbon/human/H = .
+ var/mob/living/carbon/C = .
update()
- if(!QDELETED(H))
- UnregisterSignal(H, COMSIG_MOB_DEATH)
- H.update_genitals()
+ if(!QDELETED(C))
+ if(genital_flags & UPDATE_OWNER_APPEARANCE && ishuman(C))
+ var/mob/living/carbon/human/H = .
+ H.update_genitals()
+ C.exposed_genitals -= src
+ UnregisterSignal(C, COMSIG_MOB_DEATH)
//proc to give a player their genitals and stuff when they log in
/mob/living/carbon/human/proc/give_genitals(clean = FALSE)//clean will remove all pre-existing genitals. proc will then give them any genitals that are enabled in their DNA
From ddf4d759bdc5dbda4ef6f290ca6060dd2d5887f7 Mon Sep 17 00:00:00 2001
From: Ghommie <42542238+Ghommie@users.noreply.github.com>
Date: Wed, 25 Mar 2020 17:25:23 +0100
Subject: [PATCH 07/75] Now locally tested too and it works fine.
---
modular_citadel/code/modules/arousal/genitals.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modular_citadel/code/modules/arousal/genitals.dm b/modular_citadel/code/modules/arousal/genitals.dm
index 8d505fd06c..7705dcafd1 100644
--- a/modular_citadel/code/modules/arousal/genitals.dm
+++ b/modular_citadel/code/modules/arousal/genitals.dm
@@ -59,7 +59,7 @@
if(!(NO_UNDERWEAR in H.dna.species.species_traits))
var/datum/sprite_accessory/underwear/top/T = H.hidden_undershirt ? null : GLOB.undershirt_list[H.undershirt]
var/datum/sprite_accessory/underwear/bottom/B = H.hidden_underwear ? null : GLOB.underwear_list[H.underwear]
- if(zone == BODY_ZONE_CHEST ? (T?.covers_chest || B?.covers_chest) : (!T?.covers_groin || B?.covers_groin))
+ if(zone == BODY_ZONE_CHEST ? (T?.covers_chest || B?.covers_chest) : (T?.covers_groin || B?.covers_groin))
return FALSE
if(genital_flags & GENITAL_THROUGH_CLOTHES)
return TRUE
From e4550efb39b2b9f55e94a2a34c718641469e9495 Mon Sep 17 00:00:00 2001
From: Ghom <42542238+Ghommie@users.noreply.github.com>
Date: Wed, 25 Mar 2020 17:45:11 +0100
Subject: [PATCH 08/75] Fixing creamed snout overlay a second time.
---
code/modules/mob/living/carbon/human/human.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 57667293e7..097788dd7b 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -708,7 +708,7 @@
/mob/living/carbon/human/wash_cream()
if(creamed) //clean both to prevent a rare bug
- cut_overlay(mutable_appearance('icons/effects/creampie.dmi', "creampie_lizard"))
+ cut_overlay(mutable_appearance('icons/effects/creampie.dmi', "creampie_snout"))
cut_overlay(mutable_appearance('icons/effects/creampie.dmi', "creampie_human"))
creamed = FALSE
From 36d5d5e14170439d2e9fbbe37c675ed6ce2b28da Mon Sep 17 00:00:00 2001
From: Ghommie <42542238+Ghommie@users.noreply.github.com>
Date: Wed, 25 Mar 2020 23:33:50 +0100
Subject: [PATCH 09/75] Antagonists such as wizard and nuke ops are now more
anonymous.
---
code/__DEFINES/dcs/signals.dm | 1 +
code/datums/elements/flavor_text.dm | 9 +++++++++
code/game/objects/structures/crates_lockers/closets.dm | 6 +++---
code/modules/antagonists/_common/antag_datum.dm | 1 +
4 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index 3d76390ce1..0593a3c8f8 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -175,6 +175,7 @@
#define SPEECH_LANGUAGE 5
// #define SPEECH_IGNORE_SPAM 6
// #define SPEECH_FORCED 7
+#define COMSIG_MOB_ANTAG_ON_GAIN "mob_antag_on_gain" //from base of /datum/antagonist/on_gain(): (antag_datum)
// /mob/living signals
#define COMSIG_LIVING_REGENERATE_LIMBS "living_regenerate_limbs" //from base of /mob/living/regenerate_limbs(): (noheal, excluded_limbs)
diff --git a/code/datums/elements/flavor_text.dm b/code/datums/elements/flavor_text.dm
index 373647d6f5..5e0c581ec9 100644
--- a/code/datums/elements/flavor_text.dm
+++ b/code/datums/elements/flavor_text.dm
@@ -114,6 +114,9 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code
//subtypes with additional hooks for DNA and preferences.
/datum/element/flavor_text/carbon
+ //list of antagonists etcetera that should have nothing to do with people's snowflakes.
+ var/static/list/i_dont_even_know_who_you_are = typecacheof(list(/datum/antagonist/abductor, /datum/antagonist/ert,
+ /datum/antagonist/nukeop, /datum/antagonist/official, /datum/antagonist/wizard))
/datum/element/flavor_text/carbon/Attach(datum/target, text = "", _name = "Flavor Text", _addendum, _max_len = MAX_FLAVOR_LEN, _always_show = FALSE, _edit = TRUE)
if(!iscarbon(target))
@@ -144,3 +147,9 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code
/datum/element/flavor_text/carbon/proc/unset_flavor(mob/living/carbon/user)
texts_by_atom[user] = ""
+
+/datum/element/flavor_text/carbon/proc/on_antag_gain(mob/living/carbon/user, datum/antagonist/antag)
+ if(is_type_in_typecache(antag, i_dont_even_know_who_you_are))
+ texts_by_atom[user] = ""
+ if(user.dna)
+ user.dna.features["flavor_text"] = ""
\ No newline at end of file
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index e19feea582..11db7f37c8 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -121,7 +121,7 @@
return FALSE
var/turf/T = get_turf(src)
for(var/mob/living/L in T)
- if(L.anchored || horizontal && L.mob_size > MOB_SIZE_TINY && L.density)
+ if(L.move_resist >= MOVE_FORCE_VERY_STRONG || (horizontal && L.mob_size > MOB_SIZE_TINY && L.density))
if(user)
to_chat(user, "There's something large on top of [src], preventing it from opening." )
return FALSE
@@ -133,7 +133,7 @@
if(closet != src && !closet.wall_mounted)
return FALSE
for(var/mob/living/L in T)
- if(L.anchored || horizontal && L.mob_size > MOB_SIZE_TINY && L.density)
+ if(L.move_resist >= MOVE_FORCE_VERY_STRONG || horizontal && L.mob_size > MOB_SIZE_TINY && L.density)
if(user)
to_chat(user, "There's something too large in [src], preventing it from closing.")
return FALSE
@@ -216,7 +216,7 @@
if(!isliving(AM)) //let's not put ghosts or camera mobs inside closets...
return FALSE
var/mob/living/L = AM
- if(L.anchored || L.buckled || L.incorporeal_move || L.has_buckled_mobs())
+ if(L.move_resist >= MOVE_FORCE_VERY_STRONG || L.buckled || L.incorporeal_move || L.has_buckled_mobs())
return FALSE
if(L.mob_size > MOB_SIZE_TINY) // Tiny mobs are treated as items.
if(horizontal && L.density)
diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm
index 2e3626dd4c..19845be315 100644
--- a/code/modules/antagonists/_common/antag_datum.dm
+++ b/code/modules/antagonists/_common/antag_datum.dm
@@ -75,6 +75,7 @@ GLOBAL_LIST_EMPTY(antagonists)
remove_blacklisted_quirks()
if(is_banned(owner.current) && replace_banned)
replace_banned_player()
+ SEND_SIGNAL(owner.current, COMSIG_MOB_ANTAG_ON_GAIN, src)
/datum/antagonist/proc/is_banned(mob/M)
if(!M)
From 4a01e59623a987f86b2814303a8aa05eacc9dcf7 Mon Sep 17 00:00:00 2001
From: Ghommie <42542238+Ghommie@users.noreply.github.com>
Date: Wed, 25 Mar 2020 23:36:31 +0100
Subject: [PATCH 10/75] Signals things.
---
code/datums/elements/flavor_text.dm | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/code/datums/elements/flavor_text.dm b/code/datums/elements/flavor_text.dm
index 5e0c581ec9..d34d6946ae 100644
--- a/code/datums/elements/flavor_text.dm
+++ b/code/datums/elements/flavor_text.dm
@@ -125,6 +125,7 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code
if(. == ELEMENT_INCOMPATIBLE)
return
RegisterSignal(target, COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, .proc/update_dna_flavor_text)
+ RegisterSignal(target, COMSIG_MOB_ANTAG_ON_GAIN, .proc/on_antag_gain)
if(ishuman(target))
RegisterSignal(target, COMSIG_HUMAN_PREFS_COPIED_TO, .proc/update_prefs_flavor_text)
RegisterSignal(target, COMSIG_HUMAN_HARDSET_DNA, .proc/update_dna_flavor_text)
@@ -132,7 +133,7 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code
/datum/element/flavor_text/carbon/Detach(mob/living/carbon/C)
. = ..()
- UnregisterSignal(C, list(COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, COMSIG_HUMAN_PREFS_COPIED_TO, COMSIG_HUMAN_HARDSET_DNA, COMSIG_HUMAN_ON_RANDOMIZE))
+ UnregisterSignal(C, list(COMSIG_CARBON_IDENTITY_TRANSFERRED_TO, COMSIG_MOB_ANTAG_ON_GAIN, COMSIG_HUMAN_PREFS_COPIED_TO, COMSIG_HUMAN_HARDSET_DNA, COMSIG_HUMAN_ON_RANDOMIZE))
/datum/element/flavor_text/carbon/proc/update_dna_flavor_text(mob/living/carbon/C)
texts_by_atom[C] = C.dna.features["flavor_text"]
From 1642903ab3c62777fc3236c81d80ed22aa042bf0 Mon Sep 17 00:00:00 2001
From: Ghommie <42542238+Ghommie@users.noreply.github.com>
Date: Wed, 25 Mar 2020 23:46:27 +0100
Subject: [PATCH 11/75] Spares the official because they don't have their name
replaced.
---
code/datums/elements/flavor_text.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/datums/elements/flavor_text.dm b/code/datums/elements/flavor_text.dm
index d34d6946ae..ea8e361694 100644
--- a/code/datums/elements/flavor_text.dm
+++ b/code/datums/elements/flavor_text.dm
@@ -116,7 +116,7 @@ GLOBAL_LIST_EMPTY(mobs_with_editable_flavor_text) //et tu, hacky code
/datum/element/flavor_text/carbon
//list of antagonists etcetera that should have nothing to do with people's snowflakes.
var/static/list/i_dont_even_know_who_you_are = typecacheof(list(/datum/antagonist/abductor, /datum/antagonist/ert,
- /datum/antagonist/nukeop, /datum/antagonist/official, /datum/antagonist/wizard))
+ /datum/antagonist/nukeop, /datum/antagonist/wizard))
/datum/element/flavor_text/carbon/Attach(datum/target, text = "", _name = "Flavor Text", _addendum, _max_len = MAX_FLAVOR_LEN, _always_show = FALSE, _edit = TRUE)
if(!iscarbon(target))
From 17f4b0f34fa5b26846e0d246a3daa5fea47750a2 Mon Sep 17 00:00:00 2001
From: Seris02
Date: Thu, 26 Mar 2020 17:46:41 +0800
Subject: [PATCH 12/75] I assume this works
---
code/game/machinery/computer/robot.dm | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/code/game/machinery/computer/robot.dm b/code/game/machinery/computer/robot.dm
index 9356a8e933..2621616759 100644
--- a/code/game/machinery/computer/robot.dm
+++ b/code/game/machinery/computer/robot.dm
@@ -11,16 +11,19 @@
/obj/machinery/computer/robotics/proc/can_control(mob/user, mob/living/silicon/robot/R)
if(!istype(R))
- return 0
+ return FALSE
if(isAI(user))
if (R.connected_ai != user)
- return 0
+ return FALSE
if(iscyborg(user))
if (R != user)
- return 0
+ return FALSE
if(R.scrambledcodes)
- return 0
- return 1
+ return FALSE
+ if (hasSiliconAccessInArea(user) && !issilicon(user))
+ if (!Adjacent(user))
+ return FALSE
+ return TRUE
/obj/machinery/computer/robotics/ui_interact(mob/user)
. = ..()
From 4199792576905b34feae5537c8a75904b8933d3d Mon Sep 17 00:00:00 2001
From: bunny232
Date: Thu, 26 Mar 2020 10:45:30 -0400
Subject: [PATCH 13/75] Boxstation secmos is no longer connected to the
scrubber loop (#11630)
* Update BoxStation.dmm
* Update BoxStation.dmm
---
_maps/map_files/BoxStation/BoxStation.dmm | 178 +++++++++++-----------
1 file changed, 93 insertions(+), 85 deletions(-)
diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm
index 68e9ee8ec0..82bfb49e38 100644
--- a/_maps/map_files/BoxStation/BoxStation.dmm
+++ b/_maps/map_files/BoxStation/BoxStation.dmm
@@ -53,6 +53,16 @@
/obj/structure/lattice/catwalk,
/turf/open/space,
/area/space/nearstation)
+"aah" = (
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
+/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden,
+/turf/open/floor/plasteel,
+/area/security/main)
"aai" = (
/turf/closed/wall/r_wall,
/area/security/prison)
@@ -1541,6 +1551,18 @@
/obj/structure/lattice/catwalk,
/turf/open/space,
/area/solar/port/fore)
+"adB" = (
+/obj/structure/cable{
+ icon_state = "4-8"
+ },
+/obj/structure/disposalpipe/segment{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{
+ dir = 1
+ },
+/turf/open/floor/plasteel,
+/area/security/main)
"adC" = (
/obj/structure/table,
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
@@ -2665,6 +2687,20 @@
/obj/effect/spawner/structure/window/reinforced,
/turf/open/floor/plating,
/area/security/brig)
+"afo" = (
+/obj/structure/noticeboard{
+ dir = 1;
+ pixel_y = -27
+ },
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/red,
+/obj/effect/turf_decal/tile/red{
+ dir = 8
+ },
+/turf/open/floor/plasteel,
+/area/security/main)
"afp" = (
/obj/docking_port/stationary{
dir = 4;
@@ -3143,6 +3179,20 @@
},
/turf/open/floor/plasteel,
/area/security/prison)
+"agl" = (
+/obj/machinery/atmospherics/pipe/simple/supply/hidden{
+ dir = 4
+ },
+/obj/effect/turf_decal/tile/red,
+/obj/effect/turf_decal/tile/red{
+ dir = 8
+ },
+/obj/structure/chair/sofa/right{
+ dir = 1
+ },
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
+/turf/open/floor/plasteel,
+/area/security/main)
"agm" = (
/obj/machinery/light{
dir = 8
@@ -3321,6 +3371,15 @@
/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
/turf/open/floor/plasteel,
/area/security/main)
+"agD" = (
+/obj/effect/turf_decal/tile/red{
+ dir = 4
+ },
+/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
+ dir = 1
+ },
+/turf/open/floor/plasteel,
+/area/security/brig)
"agE" = (
/obj/structure/table,
/obj/item/storage/fancy/donut_box{
@@ -3332,6 +3391,13 @@
},
/turf/open/floor/plasteel,
/area/security/main)
+"agF" = (
+/obj/machinery/atmospherics/pipe/simple/supply/hidden,
+/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
+ dir = 4
+ },
+/turf/open/floor/plasteel,
+/area/security/brig)
"agG" = (
/obj/machinery/airalarm{
dir = 8;
@@ -3436,6 +3502,10 @@
},
/turf/open/floor/plasteel,
/area/security/brig)
+"agN" = (
+/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden,
+/turf/open/floor/plasteel,
+/area/security/courtroom)
"agO" = (
/obj/machinery/door/airlock/security/glass{
name = "Brig Infirmary";
@@ -3467,6 +3537,19 @@
},
/turf/open/floor/plasteel,
/area/security/brig)
+"agQ" = (
+/obj/machinery/light_switch{
+ pixel_y = 28
+ },
+/obj/structure/closet/secure_closet/courtroom,
+/obj/effect/decal/cleanable/cobweb,
+/obj/structure/sign/warning/securearea{
+ pixel_x = -32
+ },
+/obj/item/gavelhammer,
+/obj/machinery/atmospherics/pipe/simple/scrubbers,
+/turf/open/floor/plasteel,
+/area/security/courtroom)
"agR" = (
/obj/effect/turf_decal/loading_area{
dir = 4;
@@ -3888,16 +3971,6 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/plasteel/dark,
/area/ai_monitored/security/armory)
-"ahC" = (
-/obj/structure/disposalpipe/segment{
- dir = 4
- },
-/obj/structure/cable{
- icon_state = "4-8"
- },
-/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/hidden,
-/turf/open/floor/plasteel,
-/area/security/main)
"ahD" = (
/obj/structure/chair,
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
@@ -4202,21 +4275,6 @@
/obj/machinery/atmospherics/components/unary/vent_scrubber/on,
/turf/open/floor/plasteel/showroomfloor,
/area/security/brig)
-"aia" = (
-/obj/structure/noticeboard{
- dir = 1;
- pixel_y = -27
- },
-/obj/machinery/atmospherics/pipe/simple/supply/hidden{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
-/obj/effect/turf_decal/tile/red,
-/obj/effect/turf_decal/tile/red{
- dir = 8
- },
-/turf/open/floor/plasteel,
-/area/security/main)
"aib" = (
/obj/structure/cable{
icon_state = "2-8"
@@ -4556,19 +4614,6 @@
},
/turf/open/floor/plating,
/area/maintenance/fore/secondary)
-"aiB" = (
-/obj/machinery/atmospherics/pipe/simple/supply/hidden{
- dir = 4
- },
-/obj/effect/turf_decal/tile/red,
-/obj/effect/turf_decal/tile/red{
- dir = 8
- },
-/obj/structure/chair/sofa/right{
- dir = 1
- },
-/turf/open/floor/plasteel,
-/area/security/main)
"aiC" = (
/obj/structure/cable{
icon_state = "1-4"
@@ -4729,10 +4774,6 @@
/obj/effect/turf_decal/box,
/turf/open/floor/plasteel/dark,
/area/security/brig)
-"aiP" = (
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
-/turf/closed/wall/r_wall,
-/area/security/main)
"aiQ" = (
/obj/effect/spawner/structure/window/reinforced,
/obj/structure/cable{
@@ -4847,18 +4888,6 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/plasteel/dark,
/area/security/brig)
-"ajh" = (
-/obj/machinery/light_switch{
- pixel_y = 28
- },
-/obj/structure/closet/secure_closet/courtroom,
-/obj/effect/decal/cleanable/cobweb,
-/obj/structure/sign/warning/securearea{
- pixel_x = -32
- },
-/obj/item/gavelhammer,
-/turf/open/floor/plasteel,
-/area/security/courtroom)
"aji" = (
/obj/structure/chair{
name = "Judge"
@@ -5126,12 +5155,6 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/plasteel/dark,
/area/security/brig)
-"ajM" = (
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{
- dir = 4
- },
-/turf/open/floor/plasteel,
-/area/security/courtroom)
"ajN" = (
/obj/structure/cable{
icon_state = "4-8"
@@ -5286,16 +5309,6 @@
},
/turf/open/floor/plating,
/area/construction/mining/aux_base)
-"aka" = (
-/obj/effect/turf_decal/tile/red{
- dir = 4
- },
-/obj/machinery/atmospherics/pipe/manifold/supply/hidden{
- dir = 1
- },
-/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden,
-/turf/open/floor/plasteel,
-/area/security/brig)
"akb" = (
/obj/machinery/light{
dir = 8
@@ -5609,11 +5622,6 @@
/obj/effect/turf_decal/tile/red,
/turf/open/floor/plasteel,
/area/security/brig)
-"akE" = (
-/obj/machinery/atmospherics/pipe/simple/supply/hidden,
-/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden,
-/turf/open/floor/plasteel,
-/area/security/brig)
"akF" = (
/obj/machinery/atmospherics/pipe/simple/supply/hidden,
/obj/effect/turf_decal/tile/red,
@@ -91862,11 +91870,11 @@ adl
aet
agy
aha
-ahC
-aia
-aiP
-aka
-akE
+aah
+afo
+adR
+agD
+agF
gyr
alq
amd
@@ -92633,11 +92641,11 @@ aff
aeU
ajA
akd
-ahF
-aiB
-abp
-ajh
-ajM
+adB
+agl
+uHp
+agQ
+agN
akw
alb
alG
From 02f7aff68061fd943d9bebade2fa9ea3e72a3ac6 Mon Sep 17 00:00:00 2001
From: CitadelStationBot
Date: Thu, 26 Mar 2020 09:45:33 -0500
Subject: [PATCH 14/75] Automatic changelog generation for PR #11630 [ci skip]
---
html/changelogs/AutoChangeLog-pr-11630.yml | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 html/changelogs/AutoChangeLog-pr-11630.yml
diff --git a/html/changelogs/AutoChangeLog-pr-11630.yml b/html/changelogs/AutoChangeLog-pr-11630.yml
new file mode 100644
index 0000000000..c65ecfe3bd
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11630.yml
@@ -0,0 +1,4 @@
+author: "bunny232"
+delete-after: True
+changes:
+ - bugfix: "Box secmos now is now longer connected to the scrubber loop"
From 75a9bc0b80b7c7716a0daf30e131484c442eb328 Mon Sep 17 00:00:00 2001
From: Ghom <42542238+Ghommie@users.noreply.github.com>
Date: Thu, 26 Mar 2020 15:54:02 +0100
Subject: [PATCH 15/75] Update bloodsucker.dm
---
code/game/gamemodes/bloodsucker/bloodsucker.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/game/gamemodes/bloodsucker/bloodsucker.dm b/code/game/gamemodes/bloodsucker/bloodsucker.dm
index a45e989318..9515d6063c 100644
--- a/code/game/gamemodes/bloodsucker/bloodsucker.dm
+++ b/code/game/gamemodes/bloodsucker/bloodsucker.dm
@@ -19,7 +19,7 @@
antag_flag = ROLE_BLOODSUCKER
false_report_weight = 1
restricted_jobs = list("AI","Cyborg")
- protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
+ protected_jobs = list("Chaplain", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
required_players = 20
required_enemies = 2
recommended_enemies = 4
From 8e54cbe364b45ea5b76b87264d41a00b179b1496 Mon Sep 17 00:00:00 2001
From: Ghom <42542238+Ghommie@users.noreply.github.com>
Date: Thu, 26 Mar 2020 15:54:38 +0100
Subject: [PATCH 16/75] Update dynamic_rulesets_roundstart.dm
---
code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
index 8b44abbe03..a7fc9b86ce 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
@@ -805,7 +805,7 @@
antag_flag = ROLE_BLOODSUCKER
antag_datum = ANTAG_DATUM_BLOODSUCKER
minimum_required_age = 0
- protected_roles = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
+ protected_roles = list("Chaplain", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
restricted_roles = list("Cyborg", "AI")
required_candidates = 1
weight = 2
From 8bd238c87c38af065e0dfb13cd7ded852540652f Mon Sep 17 00:00:00 2001
From: Trilbyspaceclone <30435998+Trilbyspaceclone@users.noreply.github.com>
Date: Thu, 26 Mar 2020 11:49:49 -0400
Subject: [PATCH 17/75] Reblances flares, flashlights and eye-lights (#11404)
* Update flashlight.dm
* makes the torch be enlightend
* Update flashlight.dm
* Update code/game/objects/items/devices/flashlight.dm
Co-Authored-By: Ghom <42542238+Ghommie@users.noreply.github.com>
* >makes atmo pipes small items >makes heavy duty flashlight lightweight > muh realism
Co-authored-by: Ghom <42542238+Ghommie@users.noreply.github.com>
---
code/game/objects/items/devices/flashlight.dm | 23 ++++++++-----------
1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm
index bf023c2c07..29a31122bf 100644
--- a/code/game/objects/items/devices/flashlight.dm
+++ b/code/game/objects/items/devices/flashlight.dm
@@ -170,7 +170,7 @@
flags_1 = CONDUCT_1
brightness_on = 2
light_color = "#FFDDCC"
- flashlight_power = 0.3
+ flashlight_power = 0.5
var/holo_cooldown = 0
/obj/item/flashlight/pen/afterattack(atom/target, mob/user, proximity_flag)
@@ -227,15 +227,12 @@
custom_materials = null
on = TRUE
-
// green-shaded desk lamp
/obj/item/flashlight/lamp/green
desc = "A classic green-shaded desk lamp."
icon_state = "lampgreen"
item_state = "lampgreen"
-
-
/obj/item/flashlight/lamp/verb/toggle_light()
set name = "Toggle light"
set category = "Object"
@@ -258,12 +255,13 @@
desc = "A red Nanotrasen issued flare. There are instructions on the side, it reads 'pull cord, make light'."
w_class = WEIGHT_CLASS_SMALL
brightness_on = 7 // Pretty bright.
+ total_mass = 0.8
light_color = "#FA421A"
icon_state = "flare"
item_state = "flare"
actions_types = list()
var/fuel = 0
- var/on_damage = 7
+ var/on_damage = 9
var/produce_heat = 1500
heat = 1000
light_color = LIGHT_COLOR_FLARE
@@ -331,14 +329,15 @@
name = "torch"
desc = "A torch fashioned from some leaves and a log."
w_class = WEIGHT_CLASS_BULKY
- brightness_on = 4
+ brightness_on = 6 //When on were like a lantern
light_color = "#FAA44B"
icon_state = "torch"
item_state = "torch"
lefthand_file = 'icons/mob/inhands/items_lefthand.dmi'
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
light_color = LIGHT_COLOR_ORANGE
- on_damage = 10
+ total_mass = TOTAL_MASS_NORMAL_ITEM
+ on_damage = 12 //Its a log thats on fire
slot_flags = null
/obj/item/flashlight/lantern
@@ -348,10 +347,9 @@
lefthand_file = 'icons/mob/inhands/equipment/mining_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/mining_righthand.dmi'
desc = "A mining lantern."
- brightness_on = 6 // luminosity when on
+ brightness_on = 6 // luminosity when on
light_color = "#FFAA44"
- flashlight_power = 0.75
-
+ flashlight_power = 0.8
/obj/item/flashlight/slime
gender = PLURAL
@@ -372,7 +370,6 @@
var/emp_cur_charges = 4
var/charge_tick = 0
-
/obj/item/flashlight/emp/New()
..()
START_PROCESSING(SSobj, src)
@@ -435,7 +432,7 @@
var/fuel = 0
/obj/item/flashlight/glowstick/Initialize()
- fuel = rand(1600, 2000)
+ fuel = rand(1000, 1500)
light_color = color
. = ..()
@@ -540,7 +537,7 @@
/obj/item/flashlight/eyelight
name = "eyelight"
desc = "This shouldn't exist outside of someone's head, how are you seeing this?"
- brightness_on = 15
+ brightness_on = 10
flags_1 = CONDUCT_1
item_flags = DROPDEL
actions_types = list()
From 9ab89ddcea7605ae8326e3d44e1321888f384f67 Mon Sep 17 00:00:00 2001
From: CitadelStationBot
Date: Thu, 26 Mar 2020 10:49:52 -0500
Subject: [PATCH 18/75] Automatic changelog generation for PR #11404 [ci skip]
---
html/changelogs/AutoChangeLog-pr-11404.yml | 8 ++++++++
1 file changed, 8 insertions(+)
create mode 100644 html/changelogs/AutoChangeLog-pr-11404.yml
diff --git a/html/changelogs/AutoChangeLog-pr-11404.yml b/html/changelogs/AutoChangeLog-pr-11404.yml
new file mode 100644
index 0000000000..18e0145b34
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-11404.yml
@@ -0,0 +1,8 @@
+author: "Trilbyspaceclone"
+delete-after: True
+changes:
+ - balance: "torches take less staminda to use."
+ - balance: "Glowsticks dont last as long"
+ - balance: "Penlights are better at being lights"
+ - balance: "Torches are brighter then before - Indian Johns want to be on lava land rejoy!"
+ - balance: "Eye lights have 30% less light coming out of them."
From 0bf2cf04848aeae7a2288d7ff408eeefe251e6a5 Mon Sep 17 00:00:00 2001
From: deathride58
Date: Thu, 26 Mar 2020 11:51:48 -0400
Subject: [PATCH 19/75] Adds a lfwb-inspired orbiting pixel + flashing outline
animation to the sprint and combat buttons (toggleable via prefs) (#11623)
* Adds a flashing effect to the sprint and combat mode toggles (toggleable via prefs)
* Adds the ability to change the color of the hud toggle flash as well
---
code/modules/client/preferences.dm | 14 ++++++++++++++
code/modules/client/preferences_savefile.dm | 7 ++++++-
code/modules/mob/living/living_combat.dm | 2 +-
code/modules/mob/living/living_sprint.dm | 2 +-
icons/mob/screen_gen.dmi | Bin 116168 -> 118425 bytes
.../code/_onclick/hud/screen_objects.dm | 14 ++++++++++++++
modular_citadel/code/_onclick/hud/sprint.dm | 14 ++++++++++++++
7 files changed, 50 insertions(+), 3 deletions(-)
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index ecff37c1f3..e1ecb81ab6 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -187,6 +187,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/sprint_spacebar = FALSE
var/sprint_toggle = FALSE
+ var/hud_toggle_flash = TRUE
+ var/hud_toggle_color = "#ffffff"
+
var/list/exp = list()
var/list/menuoptions
@@ -902,6 +905,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "Fit Viewport: [auto_fit_viewport ? "Auto" : "Manual"]
"
dat += "Sprint Key: [sprint_spacebar ? "Space" : "Shift"]
"
dat += "Toggle Sprint: [sprint_toggle ? "Enabled" : "Disabled"]
"
+ dat += "HUD Button Flashes: [hud_toggle_flash ? "Enabled" : "Disabled"]
"
+ dat += "HUD Button Flash Color: Change
"
if (CONFIG_GET(flag/maprotation) && CONFIG_GET(flag/tgstyle_maprotation))
var/p_map = preferred_map
@@ -2075,6 +2080,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(pickedPDASkin)
pda_skin = pickedPDASkin
+ if("hud_toggle_color")
+ var/new_toggle_color = input(user, "Choose your HUD toggle flash color:", "Game Preference",hud_toggle_color) as color|null
+ if(new_toggle_color)
+ hud_toggle_color = new_toggle_color
+
else
switch(href_list["preference"])
//CITADEL PREFERENCES EDIT - I can't figure out how to modularize these, so they have to go here. :c -Pooj
@@ -2278,6 +2288,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if("sprint_toggle")
sprint_toggle = !sprint_toggle
+
+ if("hud_toggle_flash")
+ hud_toggle_flash = !hud_toggle_flash
+
if("save")
save_preferences()
save_character()
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index 69b8b5685f..731b6b7725 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -200,6 +200,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["auto_fit_viewport"] >> auto_fit_viewport
S["sprint_spacebar"] >> sprint_spacebar
S["sprint_toggle"] >> sprint_toggle
+ S["hud_toggle_flash"] >> hud_toggle_flash
+ S["hud_toggle_color"] >> hud_toggle_color
S["menuoptions"] >> menuoptions
S["enable_tips"] >> enable_tips
S["tip_delay"] >> tip_delay
@@ -239,6 +241,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
auto_fit_viewport = sanitize_integer(auto_fit_viewport, 0, 1, initial(auto_fit_viewport))
sprint_spacebar = sanitize_integer(sprint_spacebar, 0, 1, initial(sprint_spacebar))
sprint_toggle = sanitize_integer(sprint_toggle, 0, 1, initial(sprint_toggle))
+ hud_toggle_flash = sanitize_integer(hud_toggle_flash, 0, 1, initial(hud_toggle_flash))
+ hud_toggle_color = sanitize_hexcolor(hud_toggle_color, 6, 1, initial(hud_toggle_color))
ghost_form = sanitize_inlist(ghost_form, GLOB.ghost_forms, initial(ghost_form))
ghost_orbit = sanitize_inlist(ghost_orbit, GLOB.ghost_orbits, initial(ghost_orbit))
ghost_accs = sanitize_inlist(ghost_accs, GLOB.ghost_accs_options, GHOST_ACCS_DEFAULT_OPTION)
@@ -248,7 +252,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
pda_style = sanitize_inlist(pda_style, GLOB.pda_styles, initial(pda_style))
pda_color = sanitize_hexcolor(pda_color, 6, 1, initial(pda_color))
pda_skin = sanitize_inlist(pda_skin, GLOB.pda_reskins, PDA_SKIN_ALT)
-
screenshake = sanitize_integer(screenshake, 0, 800, initial(screenshake))
damagescreenshake = sanitize_integer(damagescreenshake, 0, 2, initial(damagescreenshake))
widescreenpref = sanitize_integer(widescreenpref, 0, 1, initial(widescreenpref))
@@ -301,6 +304,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["auto_fit_viewport"], auto_fit_viewport)
WRITE_FILE(S["sprint_spacebar"], sprint_spacebar)
WRITE_FILE(S["sprint_toggle"], sprint_toggle)
+ WRITE_FILE(S["hud_toggle_flash"], hud_toggle_flash)
+ WRITE_FILE(S["hud_toggle_color"], hud_toggle_color)
WRITE_FILE(S["menuoptions"], menuoptions)
WRITE_FILE(S["enable_tips"], enable_tips)
WRITE_FILE(S["tip_delay"], tip_delay)
diff --git a/code/modules/mob/living/living_combat.dm b/code/modules/mob/living/living_combat.dm
index 4cd2def5a8..493f2ffdff 100644
--- a/code/modules/mob/living/living_combat.dm
+++ b/code/modules/mob/living/living_combat.dm
@@ -43,7 +43,7 @@
/// Updates the combat mode HUD icon.
/mob/living/proc/update_combat_mode_icon()
var/obj/screen/combattoggle/T = locate() in hud_used?.static_inventory
- T?.update_icon_state()
+ T?.update_icon()
/// Enables intentionally being in combat mode. Please try not to use this proc for feedback whenever possible.
/mob/living/proc/enable_intentional_combat_mode(silent = TRUE, visible = FALSE)
diff --git a/code/modules/mob/living/living_sprint.dm b/code/modules/mob/living/living_sprint.dm
index 66aa3ebc6f..55d5f3320c 100644
--- a/code/modules/mob/living/living_sprint.dm
+++ b/code/modules/mob/living/living_sprint.dm
@@ -4,7 +4,7 @@
/mob/living/proc/update_sprint_icon()
var/obj/screen/sprintbutton/S = locate() in hud_used?.static_inventory
- S?.update_icon_state()
+ S?.update_icon()
/mob/living/proc/update_hud_sprint_bar()
hud_used?.sprint_buffer?.update_to_mob(src)
diff --git a/icons/mob/screen_gen.dmi b/icons/mob/screen_gen.dmi
index f1fafb8946acb62a2f2a071315c35b0058f589ee..ea946f60d9c31139c6e5d3e8aed79794e0294ff0 100644
GIT binary patch
literal 118425
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