diff --git a/code/__DEFINES/citadel_defines.dm b/code/__DEFINES/citadel_defines.dm index 98153f06a4..7d391b2147 100644 --- a/code/__DEFINES/citadel_defines.dm +++ b/code/__DEFINES/citadel_defines.dm @@ -8,7 +8,7 @@ //organ defines #define COCK_SIZE_MIN 1 -#define COCK_SIZE_MAX 24 +#define COCK_SIZE_MAX 20 #define COCK_GIRTH_RATIO_MAX 1.25 #define COCK_GIRTH_RATIO_DEF 0.75 @@ -18,18 +18,16 @@ #define KNOT_GIRTH_RATIO_DEF 2.1 #define KNOT_GIRTH_RATIO_MIN 1.25 -#define BALLS_VOLUME_BASE 50 +#define BALLS_VOLUME_BASE 25 #define BALLS_VOLUME_MULT 1 #define BALLS_SIZE_MIN 1 -#define BALLS_SIZE_SMALL 2 -#define BALLS_SIZE_NORMAL 3 -#define BALLS_SIZE_BIG 4 -#define BALLS_SIZE_BIGGER 5 -#define BALLS_SIZE_BIGGEST 6 +#define BALLS_SIZE_DEF 3 #define BALLS_SIZE_MAX 7 +#define BALLS_SACK_SIZE_MIN 1 #define BALLS_SACK_SIZE_DEF 8 +#define BALLS_SACK_SIZE_MAX 40 #define CUM_RATE 5 #define CUM_RATE_MULT 1 @@ -60,6 +58,7 @@ #define BREASTS_SIZE_HH 8.5//Largest size, ever. For now. #define BREASTS_SIZE_MIN BREASTS_SIZE_A +#define BREASTS_SIZE_DEF BREASTS_SIZE_C #define BREASTS_SIZE_MAX BREASTS_SIZE_HH #define MILK_RATE 5 diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 535e7a1010..dab4471330 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -31,19 +31,25 @@ #define FRIDAY_13TH "Friday the 13th" //Human Overlays Indexes///////// -#define MUTATIONS_LAYER 26 //mutations. Tk headglows, cold resistance glow, etc -#define BODY_BEHIND_LAYER 25 //certain mutantrace features (tail when looking south) that must appear behind the body parts -#define BODYPARTS_LAYER 24 //Initially "AUGMENTS", this was repurposed to be a catch-all bodyparts flag -#define BODY_ADJ_LAYER 23 //certain mutantrace features (snout, body markings) that must appear above the body parts -#define BODY_LAYER 22 //underwear, undershirts, socks, eyes, lips(makeup) -#define FRONT_MUTATIONS_LAYER 21 //mutations that should appear above body, body_adj and bodyparts layer (e.g. laser eyes) -#define DAMAGE_LAYER 20 //damage indicators (cuts and burns) -#define UNIFORM_LAYER 19 -#define ID_LAYER 18 -#define SHOES_LAYER 17 -#define GLOVES_LAYER 16 -#define EARS_LAYER 15 -#define SUIT_LAYER 14 +//citadel code +#define MUTATIONS_LAYER 31 //mutations. Tk headglows, cold resistance glow, etc +#define BODY_BEHIND_LAYER 30 //certain mutantrace features (tail when looking south) that must appear behind the body parts +#define GENITALS_BEHIND_LAYER 29 +#define BODYPARTS_LAYER 28 //Initially "AUGMENTS", this was repurposed to be a catch-all bodyparts flag +#define BODY_ADJ_LAYER 27 //certain mutantrace features (snout, body markings) that must appear above the body parts +#define GENITALS_ADJ_LAYER 26 +#define BODY_LAYER 25 //underwear, undershirts, socks, eyes, lips(makeup) +#define GENITALS_FRONT_LAYER 24 +#define FRONT_MUTATIONS_LAYER 23 //mutations that should appear above body, body_adj and bodyparts layer (e.g. laser eyes) +#define DAMAGE_LAYER 22 //damage indicators (cuts and burns) +#define UNIFORM_LAYER 21 +#define ID_LAYER 20 +#define SHOES_LAYER 19 +#define GLOVES_LAYER 18 +#define EARS_LAYER 17 +#define SUIT_LAYER 16 +#define BODY_TAUR_LAYER 15 +#define GENITALS_FRONT_LAYER 14 #define GLASSES_LAYER 13 #define BELT_LAYER 12 //Possible make this an overlay of somethign required to wear a belt? #define SUIT_STORE_LAYER 11 @@ -57,7 +63,7 @@ #define HANDS_LAYER 3 #define BODY_FRONT_LAYER 2 #define FIRE_LAYER 1 //If you're on fire -#define TOTAL_LAYERS 26 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_; +#define TOTAL_LAYERS 31 //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/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index 63c051061d..f26b750492 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -28,8 +28,9 @@ #define CHAT_GHOSTWHISPER 128 #define CHAT_GHOSTPDA 256 #define CHAT_GHOSTRADIO 512 +#define CHAT_LOOC 1024 -#define TOGGLES_DEFAULT_CHAT (CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_PULLR|CHAT_GHOSTWHISPER|CHAT_GHOSTPDA|CHAT_GHOSTRADIO) +#define TOGGLES_DEFAULT_CHAT (CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_PULLR|CHAT_GHOSTWHISPER|CHAT_GHOSTPDA|CHAT_GHOSTRADIO|CHAT_LOOC) #define PARALLAX_INSANE -1 //for show offs #define PARALLAX_HIGH 0 //default. diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index f0c42311b6..79429cff2c 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -37,6 +37,7 @@ init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, wings_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/wings_open, wings_open_list) + //citadel code //mammal bodyparts (fucking furries) init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_body_markings, mam_body_markings_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails, mam_tails_list) @@ -52,6 +53,9 @@ init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_head, xeno_head_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_tail, xeno_tail_list) init_sprite_accessory_subtypes(/datum/sprite_accessory/xeno_dorsal, xeno_dorsal_list) + //genitals + init_sprite_accessory_subtypes(/datum/sprite_accessory/penis, cock_shapes_list) + init_sprite_accessory_subtypes(/datum/sprite_accessory/breasts, breasts_size_list) //Species for(var/spath in subtypesof(/datum/species)) diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index b57d5b2548..02dc12ddd9 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -47,7 +47,7 @@ init_sprite_accessory_subtypes(/datum/sprite_accessory/socks, socks_list) return pick(socks_list) -/proc/random_features() +/proc/random_features(penis=0,balls=0,vagina=0,womb=0,breasts=0) if(!tails_list_human.len) init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, tails_list_human) if(!tails_list_lizard.len) @@ -68,9 +68,87 @@ init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, body_markings_list) if(!wings_list.len) init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, wings_list) + if(!cock_shapes_list.len) + init_sprite_accessory_subtypes(/datum/sprite_accessory/penis, cock_shapes_list) + if(ishuman(src)) + var/mob/living/carbon/human/H = src + if(H.gender == MALE) + penis = 1 + balls = 1 + vagina = 0 + womb = 0 + breasts = 0 + if(H.gender == FEMALE) + penis = 0 + balls = 0 + vagina = 1 + womb = 1 + breasts = 1 - //For now we will always return none for tail_human and ears. - return(list("mcolor" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), "tail_lizard" = pick(tails_list_lizard), "tail_human" = "None", "wings" = "None", "snout" = pick(snouts_list), "horns" = pick(horns_list), "ears" = "None", "frills" = pick(frills_list), "spines" = pick(spines_list), "body_markings" = pick(body_markings_list), "legs" = "Normal Legs")) + return(list( + "mcolor" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), + "mcolor2" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), + "mcolor3" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), + "tail_lizard" = pick(tails_list_lizard), + "tail_human" = "None", + "wings" = "None", + "snout" = pick(snouts_list), + "horns" = pick(horns_list), + "ears" = "None", + "frills" = pick(frills_list), + "spines" = pick(spines_list), + "body_markings" = pick(body_markings_list), + "legs" = "Normal Legs", + "taur" = "None", + "mam_body_markings" = "None", + "mam_ears" = "None", + "mam_tail" = "None", + "mam_tail_animated" = "None", + "xenodorsal" = "None", + "xenohead" = "None", + "xenotail" = "None", + "exhibitionist" = FALSE, + "has_cock" = FALSE, + "cock_shape" = "human", + "cock_length" = 6, + "cock_girth_ratio" = COCK_GIRTH_RATIO_DEF, + "cock_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), + "has_sheath" = FALSE, + "sheath_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_amount" = 2, + "balls_sack_size" = BALLS_SACK_SIZE_DEF, + "balls_size" = BALLS_SIZE_DEF, + "balls_cum_rate" = CUM_RATE, + "balls_cum_mult" = CUM_RATE_MULT, + "balls_efficiency" = CUM_EFFICIENCY, + "balls_fluid" = "semen", + "has_ovi" = FALSE, + "ovi_shape" = "knotted", + "ovi_length" = 6, + "ovi_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), + "has_eggsack" = FALSE, + "eggsack_internal" = TRUE, + "eggsack_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), + "eggsack_size" = BALLS_SACK_SIZE_DEF, + "eggsack_egg_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), + "eggsack_egg_size" = EGG_GIRTH_DEF, + "has_breasts" = FALSE, + "breasts_color" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), + "breasts_size" = pick(breasts_size_list), + "breasts_fluid" = "milk", + "has_vag" = FALSE, + "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, + "womb_fluid" = "femcum")) /proc/random_hair_style(gender) switch(gender) diff --git a/code/_globalvars/configuration.dm b/code/_globalvars/configuration.dm index cb3e38a92f..075289e320 100644 --- a/code/_globalvars/configuration.dm +++ b/code/_globalvars/configuration.dm @@ -9,6 +9,9 @@ var/changelog_hash = "" var/ooc_allowed = 1 // used with admin verbs to disable ooc - not a config option apparently var/dooc_allowed = 1 +//citadel code +var/looc_allowed = 1 +var/dlooc_allowed = 1 var/abandon_allowed = 1 var/enter_allowed = 1 var/guests_allowed = 1 diff --git a/code/citadel/_cit_helpers.dm b/code/citadel/_cit_helpers.dm new file mode 100644 index 0000000000..a48158d42c --- /dev/null +++ b/code/citadel/_cit_helpers.dm @@ -0,0 +1,163 @@ +//THIS FILE CONTAINS CONSTANTS, PROCS, DEFINES, AND OTHER THINGS// +//////////////////////////////////////////////////////////////////// +/mob/proc/setClickCooldown(var/timeout) + next_move = max(world.time + timeout, next_move) + +/proc/get_matrix_largest() + var/matrix/mtrx=new() + return mtrx.Scale(2) +/proc/get_matrix_large() + var/matrix/mtrx=new() + return mtrx.Scale(1.5) +/proc/get_matrix_norm() + var/matrix/mtrx=new() + return mtrx +/proc/get_matrix_small() + var/matrix/mtrx=new() + return mtrx.Scale(0.8) +/proc/get_matrix_smallest() + var/matrix/mtrx=new() + return mtrx.Scale(0.65) + +proc/get_racelist(var/mob/user)//This proc returns a list of species that 'user' has available to them. It searches the list of ckeys attached to the 'whitelist' var for a species and also checks if they're an admin. + for(var/spath in subtypesof(/datum/species)) + var/datum/species/S = new spath() + var/list/wlist = S.whitelist + if(S.whitelisted && (wlist.Find(user.ckey) || wlist.Find(user.key) || user.client.holder)) //If your ckey is on the species whitelist or you're an admin: + whitelisted_species_list[S.id] = S.type //Add the species to their available species list. + else if(!S.whitelisted && S.roundstart) //Normal roundstart species will be handled here. + whitelisted_species_list[S.id] = S.type + + return whitelisted_species_list + + //Mammal Species +var/global/list/mam_body_markings_list = list() +var/global/list/mam_ears_list = list() +var/global/list/mam_tails_list = list() +var/global/list/mam_tails_animated_list = list() +var/global/list/taur_list = list() + + //Exotic Species +var/global/list/exotic_tails_list = list() +var/global/list/exotic_tails_animated_list = list() +var/global/list/exotic_ears_list = list() +var/global/list/exotic_head_list = list() +var/global/list/exotic_back_list = list() + + //Xenomorph Species +var/global/list/xeno_head_list = list() //I forgot the ' = list()' part for the longest time and couldn't figure out what was wrong. *facepalm +var/global/list/xeno_tail_list = list() +var/global/list/xeno_dorsal_list = list() + + + //Genitals and Arousal Lists +var/global/list/cock_shapes_list = list()//global_lists.dm for the list initializations +var/global/list/breasts_size_list = list() +var/global/list/cum_into_containers_list = list(/obj/item/weapon/reagent_containers/food/snacks/pie) +var/global/list/dick_nouns = list("dick","cock","member","shaft") +var/global/list/cum_id_list = list("semen") +var/global/list/milk_id_list = list("milk") +//mentor stuff +var/list/mentors = list() + +/client/proc/reload_mentors() + set name = "Reload Mentors" + set category = "Admin" + if(!src.holder) return + message_admins("[key_name_admin(usr)] manually reloaded mentors") + +//Flavor Text +/mob/living/carbon/human/verb/set_flavor() + set name = "Set Flavor Text" + set desc = "Sets an extended description of your character's features." + set category = "IC" + + flavor_text = copytext(sanitize(input(usr, "Please enter your new flavor text.", "Flavor text", null) as text), 1) + +//LOOC toggles +/client/verb/listen_looc() + set name = "Show/Hide LOOC" + set category = "Preferences" + set desc = "Toggles seeing LocalOutOfCharacter chat" + prefs.chat_toggles ^= CHAT_LOOC + prefs.save_preferences() + src << "You will [(prefs.chat_toggles & CHAT_LOOC) ? "now" : "no longer"] see messages on the LOOC channel." + feedback_add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/datum/admins/proc/togglelooc() + set category = "Server" + set desc="Fukken metagamers" + set name="Toggle LOOC" + toggle_looc() + log_admin("[key_name(usr)] toggled LOOC.") + message_admins("[key_name_admin(usr)] toggled LOOC.") + feedback_add_details("admin_verb","TLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + +/proc/toggle_looc(toggle = null) + if(toggle != null) //if we're specifically en/disabling ooc + if(toggle != looc_allowed) + looc_allowed = toggle + else + return + else //otherwise just toggle it + looc_allowed = !looc_allowed + world << "The LOOC channel has been globally [looc_allowed ? "enabled" : "disabled"]." + +/datum/admins/proc/toggleloocdead() + set category = "Server" + set desc="Toggle dis bitch" + set name="Toggle Dead LOOC" + dlooc_allowed = !( dlooc_allowed ) + + log_admin("[key_name(usr)] toggled OOC.") + message_admins("[key_name_admin(usr)] toggled Dead OOC.") + feedback_add_details("admin_verb","TDLOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! + + +/mob/living/carbon/proc/has_penis() + if(getorganslot("penis"))//slot shared with ovipositor + if(istype(getorganslot("penis"), /obj/item/organ/genital/penis)) + return 1 + return 0 + +/mob/living/carbon/proc/has_balls() + if(getorganslot("balls")) + if(istype(getorganslot("balls"), /obj/item/organ/genital/testicles)) + return 1 + return 0 + +/mob/living/carbon/proc/has_vagina() + if(getorganslot("vagina")) + return 1 + return 0 + +/mob/living/carbon/proc/has_breasts() + if(getorganslot("breasts")) + return 1 + return 0 + +/mob/living/carbon/proc/has_ovipositor() + if(getorganslot("penis"))//shared slot + if(istype(getorganslot("penis"), /obj/item/organ/genital/ovipositor)) + return 1 + return 0 + +/mob/living/carbon/human/proc/has_eggsack() + if(getorganslot("balls")) + if(istype(getorganslot("balls"), /obj/item/organ/genital/eggsack)) + return 1 + return 0 + +/mob/living/carbon/human/proc/is_bodypart_exposed(bodypart) + +/mob/living/carbon/proc/is_groin_exposed() + for(var/obj/item/I in get_equipped_items()) + if(I.body_parts_covered & GROIN) + return 0 + return 1 + +/mob/living/carbon/proc/is_chest_exposed() + for(var/obj/item/I in get_equipped_items()) + if(I.body_parts_covered & CHEST) + return 0 + return 1 \ No newline at end of file diff --git a/code/citadel/_helpers.dm b/code/citadel/_helpers.dm deleted file mode 100644 index c0b0c0769b..0000000000 --- a/code/citadel/_helpers.dm +++ /dev/null @@ -1,68 +0,0 @@ -//THIS FILE CONTAINS CONSTANTS, PROCS, DEFINES, AND OTHER THINGS// -//////////////////////////////////////////////////////////////////// -/mob/proc/setClickCooldown(var/timeout) - next_move = max(world.time + timeout, next_move) - -/proc/get_matrix_largest() - var/matrix/mtrx=new() - return mtrx.Scale(2) -/proc/get_matrix_large() - var/matrix/mtrx=new() - return mtrx.Scale(1.5) -/proc/get_matrix_norm() - var/matrix/mtrx=new() - return mtrx -/proc/get_matrix_small() - var/matrix/mtrx=new() - return mtrx.Scale(0.8) -/proc/get_matrix_smallest() - var/matrix/mtrx=new() - return mtrx.Scale(0.65) - -proc/get_racelist(var/mob/user)//This proc returns a list of species that 'user' has available to them. It searches the list of ckeys attached to the 'whitelist' var for a species and also checks if they're an admin. - for(var/spath in subtypesof(/datum/species)) - var/datum/species/S = new spath() - var/list/wlist = S.whitelist - if(S.whitelisted && (wlist.Find(user.ckey) || wlist.Find(user.key) || user.client.holder)) //If your ckey is on the species whitelist or you're an admin: - whitelisted_species_list[S.id] = S.type //Add the species to their available species list. - else if(!S.whitelisted && S.roundstart) //Normal roundstart species will be handled here. - whitelisted_species_list[S.id] = S.type - - return whitelisted_species_list - - //Mammal Species -var/global/list/mam_body_markings_list = list() -var/global/list/mam_ears_list = list() -var/global/list/mam_tails_list = list() -var/global/list/mam_tails_animated_list = list() -var/global/list/taur_list = list() - - //Exotic Species -var/global/list/exotic_tails_list = list() -var/global/list/exotic_tails_animated_list = list() -var/global/list/exotic_ears_list = list() -var/global/list/exotic_head_list = list() -var/global/list/exotic_back_list = list() - - //Xenomorph Species -var/global/list/xeno_head_list = list() //I forgot the ' = list()' part for the longest time and couldn't figure out what was wrong. *facepalm -var/global/list/xeno_tail_list = list() -var/global/list/xeno_dorsal_list = list() - - -//mentor stuff - -var/list/mentors = list() - -/client/proc/reload_mentors() - set name = "Reload Mentors" - set category = "Admin" - if(!src.holder) return - message_admins("[key_name_admin(usr)] manually reloaded mentors") - -/mob/living/carbon/human/verb/set_flavor() - set name = "Set Flavor Text" - set desc = "Sets an extended description of your character's features." - set category = "IC" - - flavor_text = copytext(sanitize(input(usr, "Please enter your new flavor text.", "Flavor text", null) as text), 1) diff --git a/code/citadel/cit_arousal.dm b/code/citadel/cit_arousal.dm index ff77bb06e0..d4aa1716b3 100644 --- a/code/citadel/cit_arousal.dm +++ b/code/citadel/cit_arousal.dm @@ -6,33 +6,56 @@ var/arousal_rate = 1 //The base rate that arousal will increase in this mob. var/arousal_loss_rate = 1 //How easily arousal can be relieved for this mob. var/canbearoused = FALSE //Mob-level disabler for arousal. Starts off and can be enabled as features are added for different mob types. - var/mb_cd_length = 100 //10 second cooldown for masturbating because fuck spam + var/mb_cd_length = 50 //5 second cooldown for masturbating because fuck spam var/mb_cd_timer = 0 //The timer itself /mob/living/carbon/human canbearoused = TRUE + var/saved_underwear = ""//saves their underwear so it can be toggled later + var/saved_undershirt = "" + +/mob/living/carbon/human/New() + ..() + saved_underwear = underwear + saved_undershirt = undershirt + //Species vars /datum/species var/arousal_gain_rate = 1 //Rate at which this species becomes aroused var/arousal_lose_rate = 1 //Multiplier for how easily arousal can be relieved + var/list/cum_fluids = list("semen") + var/list/milk_fludis = list("milk") + var/list/femcum_fluids = list("femcum") //Mob procs /mob/living/Life() - if(stat != DEAD) - handle_arousal() - ..() - /mob/living/proc/handle_arousal() return /mob/living/carbon/handle_arousal() - ..() - var/datum/species/S - if(has_dna()) + if(canbearoused && dna) + var/datum/species/S S = dna.species - if(S && SSmob.times_fired%36==2 && getArousalLoss() < 100)//Totally stolen from breathing code. Do this every 36 ticks. - adjustArousalLoss(arousal_rate * S.arousal_gain_rate) + if(S && SSmob.times_fired%36==2 && getArousalLoss() < max_arousal)//Totally stolen from breathing code. Do this every 36 ticks. + adjustArousalLoss(arousal_rate * S.arousal_gain_rate) + if(dna.features["exhibitionist"]) + var/amt_nude = 0 + if(is_chest_exposed() && (gender == FEMALE || getorganslot("breasts"))) + amt_nude++ + if(is_groin_exposed()) + if(getorganslot("penis")) + amt_nude++ + if(getorganslot("vagina")) + amt_nude++ + var/mob/living/M + var/watchers = 0 + for(M in view(world.view, src)) + if(M.client && !M.stat && !M.eye_blind && (locate(src) in viewers(world.view,M))) + watchers++ + if(watchers && amt_nude) + adjustArousalLoss((amt_nude * watchers) + S.arousal_gain_rate) + /mob/living/proc/getArousalLoss() return arousalloss @@ -55,35 +78,11 @@ return ((100 / max_arousal) * arousalloss) /mob/living/proc/isPercentAroused(percentage)//returns true if the mob's arousal (measured in a percent of 100) is greater than the arg percentage. - if(!isnum(percentage)) - return FALSE + if(!isnum(percentage) || percentage > 100 || percentage < 0) + CRASH("Provided percentage is invalid") if(getPercentAroused() >= percentage) return TRUE -/mob/living/proc/mob_masturbate()//This is just so I can test this shit without being forced to add actual content to get rid of arousal. Will be a very basic proc for a while. - set name = "Masturbate" - set category = "IC" - if(canbearoused && !restrained() && !stat) - if(mb_cd_timer <= world.time) - //start the cooldown even if it fails - mb_cd_timer = world.time + mb_cd_length - if(getArousalLoss() >= ((max_arousal / 100) * 33))//33% arousal or greater required - src.visible_message("[src] starts masturbating!", \ - "You start masturbating.") - if(do_after(src, 100, target = src)) - src.visible_message("[src] relieves themself!", \ - "You have relieved yourself.") - setArousalLoss(min_arousal) - /* - switch(gender) - if(MALE) - PoolOrNew(/obj/effect/decal/cleanable/semen, loc) - if(FEMALE) - PoolOrNew(/obj/effect/decal/cleanable/femcum, loc) - */ - else - src << "You aren't aroused enough for that." - //H U D// /mob/living/proc/updatearousal() update_arousal_hud() @@ -143,6 +142,7 @@ /obj/screen/arousal name = "arousal" icon_state = "arousal0" + icon = 'code/citadel/icons/hud.dmi' screen_loc = ui_arousal /obj/screen/arousal/Click() @@ -154,3 +154,135 @@ return 1 else M << "Arousal is disabled. Feature is unavailable." + + + +/mob/living/proc/mob_masturbate()//This is just so I can test this shit without being forced to add actual content to get rid of arousal. Will be a very basic proc for a while. + set name = "Masturbate" + set category = "IC" + if(canbearoused && !restrained() && !stat) + if(mb_cd_timer <= world.time) + //start the cooldown even if it fails + mb_cd_timer = world.time + mb_cd_length + if(getArousalLoss() >= ((max_arousal / 100) * 33))//33% arousal or greater required + src.visible_message("[src] starts masturbating!", \ + "You start masturbating.") + if(do_after(src, 30, target = src)) + src.visible_message("[src] relieves themself!", \ + "You have relieved yourself.") + setArousalLoss(min_arousal) + /* + switch(gender) + if(MALE) + PoolOrNew(/obj/effect/decal/cleanable/semen, loc) + if(FEMALE) + PoolOrNew(/obj/effect/decal/cleanable/femcum, loc) + */ + else + src << "You aren't aroused enough for that." + +/mob/living/carbon/human/mob_masturbate() + if(mb_cd_timer > world.time) + src << "You need to wait [round((mb_cd_timer - world.time)/(20))] seconds before you can do that again!" + return + var/list/genitals_list = list() + var/obj/item/organ/genital/SG = null//originally selected_genital + var/list/containers_list = list() + var/obj/item/weapon/reagent_containers/SC = null + var/datum/reagents/fluid_source = null + var/into_container = 0 + var/arms = get_num_arms() + var/free_hands = arms + var/total_cum = 0 + var/finished = 0 + var/mb_time = 30 + mb_cd_timer = (world.time + mb_cd_length) + if(canbearoused && has_dna()) + if(restrained()) + src << "You can't do that while restrained!" + return + if(stat) + src << "You must be conscious to do that!" + return + if(getArousalLoss() < 33)//flat number instead of percentage + src << "You aren't aroused enough for that!" + return + if(!is_groin_exposed()) + src << "You need to undress, first!" + return + if(!arms) + src << "You need at least one arm." + return + for(var/helditem in held_items)//how many hands are free + if(isobj(helditem)) + free_hands-- + if(free_hands <= 0) + src << "You need at least one free hand." + return + for(var/obj/item/organ/genital/G in internal_organs) + if(G.can_masturbate_with)//filter out what you can't masturbate with + genitals_list += G + if(genitals_list.len) + SG = input(src, "with what?", "Masturbate") as null|obj in genitals_list + if(SG) + for(var/obj/item/weapon/reagent_containers/container in held_items) + if(container.is_open_container() || istype(container, /obj/item/weapon/reagent_containers/food/snacks/pie)) + containers_list += container + if(containers_list.len) + SC = input(src, "Into or onto what?(Cancel for nowhere)", "Masturbate") as null|obj in containers_list + if(SC) + if(in_range(src, SC)) + into_container = 1 + SG.update() + switch(SG.type) + + //Penis + if(/obj/item/organ/genital/penis) + var/obj/item/organ/genital/penis/P = SG + if(!P.linked_balls) + src << "Grow a pair!" + return + fluid_source = P.linked_balls.reagents + total_cum = fluid_source.total_volume + if(into_container)//into a glass or beaker or whatever + src.visible_message("[src] starts [pick("jerking off","stroking")] their [SG] over [SC].", \ + "You start jerking off over [SC.name].", \ + "You start masturbating.") + if(do_after(src, mb_time, target = src) && in_range(src, SC)) + fluid_source.trans_to(SC, total_cum) + src.visible_message("[src] orgasms, [pick("cumming into", "emptying themself into")] [SC]!", \ + "You cum into [SC].", \ + "You have relieved yourself.") + finished = 1 + + else//not into a container + src.visible_message("[src] starts [pick("jerking off","stroking")] their [pick(dick_nouns)].", \ + "You start jerking off your [pick(dick_nouns)].", \ + "You start masturbating.") + if(do_after(src, mb_time, target = src)) + if(total_cum > 5) + fluid_source.reaction(src.loc, TOUCH, 1, 0) + fluid_source.clear_reagents() + src.visible_message("[src] orgasms, [pick("shooting cum", "draining their balls")][istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""]!", \ + "You cum[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""].", \ + "You have relieved yourself.") + finished = 1 + + else//backup message, just in case + src.visible_message("[src] starts masturbating!", \ + "You start masturbating.") + if(do_after(src, mb_time, target = src)) + src.visible_message("[src] [pick("relieves themself!", "shudders and moans in orgasm!")]", \ + "You have relieved yourself.") + finished = 1 + if(finished) + setArousalLoss(min_arousal) + + else + src << "You have no genitals!" + return + +/mob/living/carbon/proc/force_orgasm(intensity) + if(canbearoused && has_dna() && (has_penis() || has_vagina())) + return 1 + return 0 \ No newline at end of file diff --git a/code/citadel/cit_genemods.dm b/code/citadel/cit_genemods.dm new file mode 100644 index 0000000000..2279ab972b --- /dev/null +++ b/code/citadel/cit_genemods.dm @@ -0,0 +1,22 @@ +//Will include consumable gene mods in the future. + +/obj/item/weapon/genemod + name = "genetic modifier" + desc = "Microbodies which can grow, morph, or otherwise change an organism into something else." + icon = 'icons/obj/items.dmi' + icon_state = "dnainjector" + throw_speed = 3 + throw_range = 5 + w_class = WEIGHT_CLASS_TINY + origin_tech = "biotech=3" + var/applied_region = "chest" + var/list/add_mutations = list() + var/list/remove_mutations = list() + + var/list/add_mutations_static = list() + var/list/remove_mutations_static = list() + + var/used = 0 + +/obj/item/weapon/genemod/proc/use(mob/living/carbon/human/target) + return \ No newline at end of file diff --git a/code/citadel/kegs.dm b/code/citadel/cit_kegs.dm similarity index 100% rename from code/citadel/kegs.dm rename to code/citadel/cit_kegs.dm diff --git a/code/citadel/cit_reagents.dm b/code/citadel/cit_reagents.dm index 5b982656cc..794a3ad553 100644 --- a/code/citadel/cit_reagents.dm +++ b/code/citadel/cit_reagents.dm @@ -30,17 +30,15 @@ icon = 'code/citadel/icons/effects.dmi' icon_state = "semen1" random_icon_states = list("semen1", "semen2", "semen3", "semen4") -// blood_state = BLOOD_STATE_SEMEN -// bloodiness = MAX_SHOE_BLOODINESS /obj/effect/decal/cleanable/semen/New() + ..() dir = pick(1,2,4,8) - ..() -/obj/effect/decal/cleanable/semen/replace_decal(obj/effect/decal/cleanable/semen/S) -// if(S.reagent_DNA["semen"]) -// reagent_DNA["semen"] |= S.reagent_DNA["semen"] - ..() +/datum/reagent/consumable/semen/reaction_turf(turf/T, reac_volume) + if(!isspaceturf(T)) + var/obj/effect/decal/cleanable/reagentdecal = new/obj/effect/decal/cleanable/semen(T) + reagentdecal.reagents.add_reagent("semen", reac_volume) /datum/reagent/consumable/femcum name = "Female Ejaculate" @@ -65,14 +63,27 @@ bloodiness = null /obj/effect/decal/cleanable/femcum/New() - dir = pick(1,2,4,8) ..() + dir = pick(1,2,4,8) /obj/effect/decal/cleanable/femcum/replace_decal(obj/effect/decal/cleanable/femcum/F) if (F.blood_DNA) blood_DNA |= F.blood_DNA.Copy() ..() +/datum/reagent/consumable/femcum/reaction_turf(turf/T, reac_volume) + if(!istype(T)) + return + if(reac_volume < 3) + return + + var/obj/effect/decal/cleanable/femcum/S = locate() in T + if(!S) + S = new(T) + S.reagents.add_reagent("semen", reac_volume) + if(data["blood_DNA"]) + S.blood_DNA[data["blood_DNA"]] = data["blood_type"] + //aphrodisiac & anaphrodisiac /datum/reagent/aphrodisiac diff --git a/code/citadel/icons/breasts.dmi b/code/citadel/icons/breasts.dmi new file mode 100644 index 0000000000..7735fad868 Binary files /dev/null and b/code/citadel/icons/breasts.dmi differ diff --git a/code/citadel/icons/breasts_onmob.dmi b/code/citadel/icons/breasts_onmob.dmi new file mode 100644 index 0000000000..12f23ad56d Binary files /dev/null and b/code/citadel/icons/breasts_onmob.dmi differ diff --git a/code/citadel/icons/dildo.dmi b/code/citadel/icons/dildo.dmi new file mode 100644 index 0000000000..22eb48c9cf Binary files /dev/null and b/code/citadel/icons/dildo.dmi differ diff --git a/code/citadel/icons/effects.dmi b/code/citadel/icons/effects.dmi index 9a99bc085a..cc8be21dd4 100644 Binary files a/code/citadel/icons/effects.dmi and b/code/citadel/icons/effects.dmi differ diff --git a/code/citadel/icons/hud.dmi b/code/citadel/icons/hud.dmi new file mode 100644 index 0000000000..bf2adcb1fc Binary files /dev/null and b/code/citadel/icons/hud.dmi differ diff --git a/code/citadel/icons/onahole.dmi b/code/citadel/icons/onahole.dmi new file mode 100644 index 0000000000..030ebcc69d Binary files /dev/null and b/code/citadel/icons/onahole.dmi differ diff --git a/code/citadel/icons/ovipositor.dmi b/code/citadel/icons/ovipositor.dmi new file mode 100644 index 0000000000..81d857417f Binary files /dev/null and b/code/citadel/icons/ovipositor.dmi differ diff --git a/code/citadel/icons/penis.dmi b/code/citadel/icons/penis.dmi new file mode 100644 index 0000000000..56f7f12803 Binary files /dev/null and b/code/citadel/icons/penis.dmi differ diff --git a/code/citadel/icons/penis_onmob.dmi b/code/citadel/icons/penis_onmob.dmi new file mode 100644 index 0000000000..628ed11068 Binary files /dev/null and b/code/citadel/icons/penis_onmob.dmi differ diff --git a/code/citadel/icons/vagina_onmob.dmi b/code/citadel/icons/vagina_onmob.dmi new file mode 100644 index 0000000000..867ede99d5 Binary files /dev/null and b/code/citadel/icons/vagina_onmob.dmi differ diff --git a/code/citadel/organs.dm b/code/citadel/organs.dm deleted file mode 100644 index 7ba1fd0ac2..0000000000 --- a/code/citadel/organs.dm +++ /dev/null @@ -1,45 +0,0 @@ -/obj/item/organ/stomach - name = "stomach" - icon_state = "stomach" - zone = "chest" - slot = "stomach" - w_class = 3 - -/obj/item/organ/stomach/prepare_eat() - var/obj/S = ..() - S.reagents.add_reagent("sacid", 2) - return S - -/obj/item/organ/penis - name = "penis" - icon_state = "penis" - zone = "groin" - slot = "penis" - w_class = 3 - var/shape = "human" - var/size = "normal" - var/testicles - -/obj/item/organ/testicles - name = "testicles" - icon_state = "testicles" - zone = "groin" - slot = "testicles" - w_class = 3 - var/size = "normal" - -/obj/item/organ/vagina - name = "vagina" - icon_state = "vagina" - zone = "groin" - slot = "vagina" - w_class = 3 - var/shape = "human" - var/ovaries - -/obj/item/organ/womb - name = "womb" - icon_state = "womb" - zone = "groin" - slot = "womb" - w_class = 3 diff --git a/code/citadel/organs/breasts.dm b/code/citadel/organs/breasts.dm new file mode 100644 index 0000000000..41ebb2d0f8 --- /dev/null +++ b/code/citadel/organs/breasts.dm @@ -0,0 +1,32 @@ +/obj/item/organ/genital/breasts + name = "breasts" + desc = "Female milk producing organs." + icon_state = "breasts" + icon = 'code/citadel/icons/breasts.dmi' + zone = "chest" + slot = "breasts" + w_class = 3 + size = "e" + fluid_id = "milk" + var/cup_size = BREASTS_SIZE_DEF + var/amount = 2 + producing = TRUE + +/obj/item/organ/genital/breasts/New() + ..() + create_reagents(fluid_max_volume) + reagents.add_reagent(fluid_id, fluid_max_volume) + update() + +/obj/item/organ/genital/breasts/on_life() + reagents.maximum_volume = fluid_max_volume + if(fluid_id && producing) + generate_milk() + +/obj/item/organ/genital/breasts/proc/generate_milk() + if(!owner) + return FALSE + if(owner.stat == DEAD) + return FALSE + reagents.isolate_reagent(fluid_id) + reagents.add_reagent(fluid_id, (fluid_mult * fluid_rate)) \ No newline at end of file diff --git a/code/citadel/organs/eggsack.dm b/code/citadel/organs/eggsack.dm new file mode 100644 index 0000000000..e760ef6035 --- /dev/null +++ b/code/citadel/organs/eggsack.dm @@ -0,0 +1,14 @@ +/obj/item/organ/genital/eggsack + name = "egg sack" + desc = "An egg producing reproductive organ." + icon_state = "egg_sack" + icon = 'code/citadel/icons/ovipositor.dmi' + zone = "groin" + slot = "testicles" + w_class = 3 + var/internal = TRUE + var/egg_girth = EGG_GIRTH_DEF + var/cum_mult = CUM_RATE_MULT + var/cum_rate = CUM_RATE + var/cum_efficiency = CUM_EFFICIENCY + var/obj/item/organ/ovipositor/linked_ovi diff --git a/code/citadel/organs/genitals.dm b/code/citadel/organs/genitals.dm new file mode 100644 index 0000000000..1cd904fd83 --- /dev/null +++ b/code/citadel/organs/genitals.dm @@ -0,0 +1,233 @@ +/obj/item/organ/genital + color = "#fcccb3" + var/shape = "human" + var/sensitivity = 1 + var/list/genital_flags = list() + var/can_masturbate_with = 0 + var/size = 2 //can vary between num or text, just used in icon_state strings + var/fluid_id = null + var/fluid_max_volume = 50 + var/fluid_efficiency = 1 + var/fluid_rate = 1 + var/fluid_mult = 1 + var/producing = FALSE + +/obj/item/organ/genital/New() + ..() + reagents = create_reagents(fluid_max_volume) + +/obj/item/organ/genital/proc/update() + return + +/obj/item/organ/genital/proc/update_size() + return + +/obj/item/organ/genital/proc/update_appearance() + return + +/obj/item/organ/genital/proc/update_link() + + +/obj/item/organ/genital/Insert(mob/living/carbon/M, special = 0) + ..() + update() +/obj/item/organ/genital/Remove(mob/living/carbon/M, special = 0) + ..() + update() + +//proc to give a player their genitals and stuff when they log in +/mob/living/carbon/human/proc/give_genitals(clean=0)//clean will remove all pre-existing genitals. proc will then give them any genitals that are enabled in their DNA + if(clean) + var/obj/item/organ/genital/GtoClean + for(GtoClean in internal_organs) + GtoClean.Remove(src) + qdel(GtoClean) + if(dna.features["has_cock"]) + give_penis() + if(dna.features["has_balls"]) + give_balls() + else if(dna.features["has_ovi"]) + give_ovipositor() + if(dna.features["has_eggsack"]) + give_eggsack() + if(dna.features["has_breasts"]) + give_breasts() + if(dna.features["has_vag"]) + give_vagina() + if(dna.features["has_womb"]) + give_womb() + +/mob/living/carbon/human/proc/give_penis() + if(!dna) + return FALSE + if(NOGENITALS in dna.species.species_traits) + return FALSE + if(!getorganslot("penis")) + var/obj/item/organ/genital/penis/P = new + P.Insert(src) + if(P) + if(dna.species.use_skintones && dna.features["genitals_use_skintone"]) + P.color = skintone2hex(skin_tone) + else + P.color = dna.features["cock_color"] + P.length = dna.features["cock_length"] + P.girth_ratio = dna.features["cock_girth_ratio"] + P.shape = dna.features["cock_shape"] + P.update() + +/mob/living/carbon/human/proc/give_balls() + if(!dna) + return FALSE + if(NOGENITALS in dna.species.species_traits) + return FALSE + if(!getorganslot("testicles")) + var/obj/item/organ/genital/testicles/T = new + T.Insert(src) + if(dna.species.use_skintones && dna.features["genitals_use_skintone"]) + T.color = skintone2hex(skin_tone) + else + T.color = dna.features["balls_color"] + T.size = dna.features["bals_size"] + T.sack_size = dna.features["balls_sack_size"] + T.fluid_id = dna.features["balls_fluid"] + T.fluid_rate = dna.features["balls_cum_rate"] + T.fluid_mult = dna.features["balls_cum_mult"] + T.fluid_efficiency = dna.features["balls_efficiency"] + T.update() + +/mob/living/carbon/human/proc/give_breasts() + if(!has_dna()) + return FALSE + if(NOGENITALS in dna.species.species_traits) + return FALSE + if(!getorganslot("breasts")) + var/obj/item/organ/genital/breasts/B = new + B.Insert(src) + B.cup_size = dna.features["breasts_size"] + B.fluid_id = dna.features["breasts_fluid"] + B.update() + + +/mob/living/carbon/human/proc/give_ovipositor() +/mob/living/carbon/human/proc/give_eggsack() +/mob/living/carbon/human/proc/give_vagina() + if(!has_dna()) + return FALSE + if(NOGENITALS in dna.species.species_traits) + return FALSE + if(!getorganslot("vagina")) + var/obj/item/organ/genital/vagina/V = new + V.Insert(src) + if(dna.species.use_skintones && dna.features["genitals_use_skintone"]) + V.color = skintone2hex(skin_tone) + else + V.color = dna.features["vag_color"] + V.update() +/mob/living/carbon/human/proc/give_womb() + if(!has_dna()) + return FALSE + if(NOGENITALS in dna.species.species_traits) + return FALSE + if(!getorganslot("womb")) + var/obj/item/organ/genital/womb/W = new + W.Insert(src) + W.update() + + +/datum/species/proc/genitals_layertext(layer) + switch(layer) + if(GENITALS_BEHIND_LAYER) + return "BEHIND" + if(GENITALS_ADJ_LAYER) + return "ADJ" + if(GENITALS_FRONT_LAYER) + return "FRONT" + +//procs to handle sprite overlays being applied to humans + +/obj/item/equipped(mob/user, slot) + if(ishuman(user)) + var/mob/living/carbon/human/H = user + H.update_genitals() + ..() + +/mob/living/carbon/human/doUnEquip(obj/item/I, force) + . = ..() + if(!.) + return + update_genitals() + +/mob/living/carbon/human/proc/update_genitals() + dna.species.handle_genitals(src) + +/datum/species/proc/handle_genitals(mob/living/carbon/human/H) + if(!H) + CRASH("H = null") + if(!H.internal_organs.len) + return + if(NOGENITALS in species_traits) + return + + var/list/genitals_to_add = list() + var/list/relevent_layers = list(GENITALS_BEHIND_LAYER, GENITALS_ADJ_LAYER, GENITALS_FRONT_LAYER) + var/list/standing = list() + var/size + + H.remove_overlay(GENITALS_BEHIND_LAYER) + H.remove_overlay(GENITALS_ADJ_LAYER) + H.remove_overlay(GENITALS_FRONT_LAYER) + + if(H.disabilities & HUSK) + return + //start scanning for genitals + if(H.has_penis() && H.is_groin_exposed()) + genitals_to_add += H.getorganslot("penis") + if(H.has_breasts() && H.is_chest_exposed()) + genitals_to_add += H.getorganslot("breasts") + if(H.has_vagina() && H.is_groin_exposed()) + genitals_to_add += H.getorganslot("vagina") + var/image/I + //start applying overlays + for(var/layer in relevent_layers) + var/layertext = genitals_layertext(layer) + for(var/obj/item/organ/genital/G in genitals_to_add) + var/datum/sprite_accessory/S + switch(G.type) + if(/obj/item/organ/genital/penis) + S = cock_shapes_list[G.shape] + size = G.size + + if(!S || S.icon_state == "none") + continue + var/icon_string + icon_string = "[G.slot]_[S.icon_state]_[size]_[layertext]" + I = image("icon" = S.icon, "icon_state" = icon_string, "layer" =- layer) + if(S.center) + I = center_image(I,S.dimension_x,S.dimension_y) + switch(S.color_src) + if("cock_color") + I.color = "#[H.dna.features["cock_color"]]" + if("breasts_color") + I.color = "#[H.dna.features["breasts_color"]]" + if(MUTCOLORS) + if(fixed_mut_color) + I.color = "#[fixed_mut_color]" + else + I.color = "#[H.dna.features["mcolor"]]" + if(MUTCOLORS2) + if(fixed_mut_color2) + I.color = "#[fixed_mut_color2]" + else + I.color = "#[H.dna.features["mcolor2"]]" + if(MUTCOLORS3) + if(fixed_mut_color3) + I.color = "#[fixed_mut_color3]" + else + I.color = "#[H.dna.features["mcolor3"]]" + standing += I + H.overlays_standing[layer] = standing.Copy() + standing = list() + + H.apply_overlay(GENITALS_BEHIND_LAYER) + H.apply_overlay(GENITALS_ADJ_LAYER) + H.apply_overlay(GENITALS_FRONT_LAYER) \ No newline at end of file diff --git a/code/citadel/organs/genitals_sprite_accessories.dm b/code/citadel/organs/genitals_sprite_accessories.dm new file mode 100644 index 0000000000..376017f73b --- /dev/null +++ b/code/citadel/organs/genitals_sprite_accessories.dm @@ -0,0 +1,116 @@ +//DICKS,COCKS,PENISES,WHATEVER YOU WANT TO CALL THEM +/datum/sprite_accessory/penis + icon = 'code/citadel/icons/penis_onmob.dmi' + icon_state = null + name = "penis" //the preview name of the accessory + gender_specific = 0 //Might be needed somewhere down the list. + color_src = "cock_color" + locked = 0 + +/datum/sprite_accessory/penis/none + icon_state = "none" + name = "None" + +/datum/sprite_accessory/penis/human + icon_state = "human" + name = "Human" + +/datum/sprite_accessory/penis/knotted + icon_state = "knotted" + name = "Knotted" + +/datum/sprite_accessory/penis/flared + icon_state = "flared" + name = "Flared" + +/datum/sprite_accessory/penis/barbknot + icon_state = "barbknot" + name = "Barbed, Knotted" + +/datum/sprite_accessory/penis/tapered + icon_state = "tapered" + name = "Tapered" + +//BREASTS BE HERE +/datum/sprite_accessory/breasts + icon = 'code/citadel/icons/breasts_onmob.dmi' + icon_state = null + name = "breasts" + gender_specific = 0 + color_src = MUTCOLORS2 //I'll have skin_tone override this if the species uses them + locked = 0 +/*!!ULTRACOMPRESSEDEDITION!!*/ +/datum/sprite_accessory/breasts/none + icon_state = "none" + name = "None" +/datum/sprite_accessory/breasts/a + icon_state = "a" + name = "A" +/datum/sprite_accessory/breasts/aa + icon_state = "a" + name = "AA" +/datum/sprite_accessory/breasts/b + icon_state = "b" + name = "B" +/datum/sprite_accessory/breasts/bb + icon_state = "b" + name = "BB" +/datum/sprite_accessory/breasts/c + icon_state = "c" + name = "C" +/datum/sprite_accessory/breasts/cc + icon_state = "c" + name = "CC" +/datum/sprite_accessory/breasts/d + icon_state = "d" + name = "D" +/datum/sprite_accessory/breasts/dd + icon_state = "d" + name = "DD" +/datum/sprite_accessory/breasts/e + icon_state = "e" + name = "E" +/datum/sprite_accessory/breasts/ee + icon_state = "e" + name = "EE" +/datum/sprite_accessory/breasts/f + icon_state = "f" + name = "F" + locked = 1 +/datum/sprite_accessory/breasts/ff + icon_state = "f" + name = "FF" + locked = 1 +/datum/sprite_accessory/breasts/g + icon_state = "g" + name = "G" + locked = 1 +/datum/sprite_accessory/breasts/gg + icon_state = "g" + name = "GG" + locked = 1 +/datum/sprite_accessory/breasts/h + icon_state = "h" + name = "H" + locked = 1 +/datum/sprite_accessory/breasts/hh + icon_state = "h" + name = "HH" + locked = 1 + +//OVIPOSITORS BE HERE +/datum/sprite_accessory/ovipositor + icon = 'code/citadel/icons/penis_onmob.dmi' + icon_state = null + name = "Ovipositor" //the preview name of the accessory + gender_specific = 0 //Might be needed somewhere down the list. + color_src = "cock_color" + locked = 0 + +/datum/sprite_accessory/ovipositor/knotted + icon_state = "none" + name = "None" + +/datum/sprite_accessory/ovipositor/knotted + icon_state = "knotted" + name = "Knotted" diff --git a/code/citadel/organs/ovipositor.dm b/code/citadel/organs/ovipositor.dm new file mode 100644 index 0000000000..b54b93bc93 --- /dev/null +++ b/code/citadel/organs/ovipositor.dm @@ -0,0 +1,17 @@ +/obj/item/organ/genital/ovipositor + name = "ovipositor" + desc = "An egg laying reproductive organ." + icon_state = "ovi_knotted_2" + icon = 'code/citadel/icons/ovipositor.dmi' + zone = "groin" + slot = "penis" + w_class = 3 + shape = "knotted" + size = 3 + var/length = 6 //inches + var/girth = 0 + var/girth_ratio = COCK_GIRTH_RATIO_DEF //citadel_defines.dm for these defines + var/knot_girth_ratio = KNOT_GIRTH_RATIO_DEF + var/list/oviflags = list() + + var/obj/item/organ/eggsack/linked_eggsack diff --git a/code/citadel/organs/penis.dm b/code/citadel/organs/penis.dm new file mode 100644 index 0000000000..7427503a99 --- /dev/null +++ b/code/citadel/organs/penis.dm @@ -0,0 +1,60 @@ +/obj/item/organ/genital/penis + name = "penis" + desc = "A male reproductive organ." + icon_state = "penis" + icon = 'code/citadel/icons/penis.dmi' + zone = "groin" + slot = "penis" + w_class = 3 + color = null + can_masturbate_with = 1 + size = 2 //arbitrary value derived from length and girth for sprites. + var/length = 6 //inches + var/girth = 0 + var/girth_ratio = COCK_GIRTH_RATIO_DEF //0.73; check citadel_defines.dm + var/knot_girth_ratio = KNOT_GIRTH_RATIO_DEF + var/list/dickflags = list() + var/list/knotted_types = list("", "barbknot") + var/obj/item/organ/genital/testicles/linked_balls + +/obj/item/organ/genital/penis/New() + ..() + update() + +/obj/item/organ/genital/penis/update() + update_size() + update_appearance() + update_link() + +/obj/item/organ/genital/penis/update_size() + switch(length) + if(-INFINITY to 5) + size = 1 + if(5 to 9) + size = 2 + if(9 to 12) + size = 3//no new sprites for anything larger + if(9 to 15) + size = 3 + if(15 to INFINITY) + size = 3 + girth = (length * girth_ratio) + +/obj/item/organ/genital/penis/update_appearance() + var/string = "penis_[shape]_[size]" + icon_state = sanitize_text(string) +// name = "[shape] penis" + desc = "That's a [lowertext(shape)] penis. You estimate it's about [round(length, 0.25)] inch[length > 1 ? "es" : ""] long and [round(girth, 0.25)] inch[length > 1 ? "es" : ""] around." + if(!owner) + return + color = sanitize_hexcolor(owner.dna.features["cock_color"], 6, 0) + +/obj/item/organ/genital/penis/update_link() + if(owner) + linked_balls = (owner.getorganslot("testicles")) + if(linked_balls) + linked_balls.linked_penis = src + else + if(linked_balls) + linked_balls.linked_penis = null + linked_balls = null diff --git a/code/citadel/organs/testicles.dm b/code/citadel/organs/testicles.dm new file mode 100644 index 0000000000..9f2b0bacf2 --- /dev/null +++ b/code/citadel/organs/testicles.dm @@ -0,0 +1,60 @@ +/obj/item/organ/genital/testicles + name = "testicles" + desc = "A male reproductive organ." + icon_state = "testicles" + icon = 'code/citadel/icons/penis.dmi' + zone = "groin" + slot = "testicles" + w_class = 3 + var/internal = FALSE + size = BALLS_SIZE_DEF + var/sack_size = BALLS_SACK_SIZE_DEF + fluid_id = "semen" + producing = TRUE + var/sent_full_message = 1 //defaults to 1 since they're full to start + var/obj/item/organ/genital/penis/linked_penis + +/obj/item/organ/genital/testicles/New() + ..() + create_reagents(fluid_max_volume) + reagents.add_reagent(fluid_id, fluid_max_volume) + +/obj/item/organ/genital/testicles/on_life() + if(fluid_id && producing) + generate_cum() + +/obj/item/organ/genital/testicles/proc/generate_cum() + reagents.maximum_volume = fluid_max_volume + if(reagents.total_volume >= reagents.maximum_volume) + if(sent_full_message < 0) + send_full_message() + sent_full_message = 1 + return FALSE + sent_full_message = 0 + if(!owner && linked_penis) + if(linked_penis.linked_balls == src) + linked_penis.linked_balls = null + linked_penis = null + return FALSE + if(!reagents) + create_reagents(fluid_max_volume) + update_link() + if(!linked_penis) + return FALSE + reagents.isolate_reagent(fluid_id)//remove old reagents if it changed and just clean up generally + reagents.add_reagent(fluid_id, (fluid_mult * fluid_rate))//generate the cum + +/obj/item/organ/genital/testicles/update_link() + if(owner) + linked_penis = (owner.getorganslot("penis")) + if(linked_penis) + linked_penis.linked_balls = src + else if(linked_penis != null) + linked_penis.linked_balls = null + linked_penis = null + +/obj/item/organ/genital/testicles/proc/send_full_message(msg = "Your balls finally feel full, again.") + if(owner && istext(msg)) + owner << msg + return TRUE + diff --git a/code/citadel/organs/vagina.dm b/code/citadel/organs/vagina.dm new file mode 100644 index 0000000000..1229c45be9 --- /dev/null +++ b/code/citadel/organs/vagina.dm @@ -0,0 +1,15 @@ +/obj/item/organ/genital/vagina + name = "vagina" + desc = "A female reproductive organ." + icon_state = "vagina" + zone = "groin" + slot = "vagina" + can_masturbate_with = 1 + w_class = 3 + var/wetness = 1 + var/capacity_length = 8//D E P T H + var/capacity_girth = 8 + var/clits = 1 + var/clit_diam = 0.25 + var/clit_len = 0.25 + var/obj/item/organ/womb/linked_womb diff --git a/code/citadel/organs/womb.dm b/code/citadel/organs/womb.dm new file mode 100644 index 0000000000..563b434c80 --- /dev/null +++ b/code/citadel/organs/womb.dm @@ -0,0 +1,9 @@ +/obj/item/organ/genital/womb + name = "womb" + desc = "A female reproductive organ." + icon_state = "womb" + zone = "groin" + slot = "womb" + w_class = 3 + fluid_id = "femcum" + var/obj/item/organ/genital/vagina/linked_vag diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index 2db9928edc..eba591ac50 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -91,7 +91,7 @@ CLONE:[M.getCloneLoss()] BRAIN:[M.getBrainLoss()] STAMINA:[M.getStaminaLoss()] - AROUSAL:[M.getArousalLoss()] + AROUSAL:[M.getArousalLoss()] "} else @@ -1148,6 +1148,8 @@ L.adjustCloneLoss(amount) if("stamina") L.adjustStaminaLoss(amount) + if("arousal") + L.adjustArousalLoss(amount) else usr << "You caused an error. DEBUG: Text:[Text] Mob:[L]" return diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 3efc7d82b2..b18620c896 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -375,6 +375,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s if(item_action_slot_check(slot, user)) //some items only give their actions buttons when in a specific slot. A.Grant(user) + //sometimes we only want to grant the item's action if it's equipped in a specific slot. /obj/item/proc/item_action_slot_check(slot, mob/user) if(slot == slot_in_backpack || slot == slot_legcuffed) //these aren't true slots, so avoid granting actions there diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 78c5ceba85..89182acc0f 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -493,7 +493,7 @@ var/global/BSACooldown = 0 set name="Toggle Dead OOC" dooc_allowed = !( dooc_allowed ) - log_admin("[key_name(usr)] toggled OOC.") + log_admin("[key_name(usr)] toggled Dead OOC.") message_admins("[key_name_admin(usr)] toggled Dead OOC.") feedback_add_details("admin_verb","TDOOC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! /* diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 3915ee8df5..5a4123d75d 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -62,14 +62,79 @@ var/list/preferences_datums = list() var/skin_tone = "caucasian1" //Skin color var/eye_color = "000" //Eye color var/datum/species/pref_species = new /datum/species/human() //Mutant race - var/list/features = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF", "tail_lizard" = "Smooth", "tail_human" = "None", "snout" = "Round", "horns" = "None", "ears" = "None", "wings" = "None", "frills" = "None", "spines" = "None", "body_markings" = "None", "mam_body_markings" = "None", "mam_ears" = "None", "mam_tail" = "None", "mam_tail_animated" = "None", - "xenodorsal" = "None", "xenohead" = "None", "xenotail" = "None", "legs" = "Normal Legs", "taur" = "None") + var/list/features = list("mcolor" = "FFF", + "mcolor2" = "FFF", + "mcolor3" = "FFF", + "tail_lizard" = "Smooth", + "tail_human" = "None", + "snout" = "Round", + "horns" = "None", + "ears" = "None", + "wings" = "None", + "frills" = "None", + "spines" = "None", + "body_markings" = "None", + "mam_body_markings" = "None", + "mam_ears" = "None", + "mam_tail" = "None", + "mam_tail_animated" = "None", + "xenodorsal" = "None", + "xenohead" = "None", + "xenotail" = "None", + "legs" = "Normal Legs", + "taur" = "None", + "exhibitionist" = FALSE, + "genitals_use_skintone" = FALSE, + "has_cock" = FALSE, + "cock_shape" = "human", + "cock_length" = 6, + "cock_girth_ratio" = COCK_GIRTH_RATIO_DEF, + "cock_color" = "fff", + "has_sheath" = FALSE, + "sheath_color" = "fff", + "has_balls" = FALSE, + "balls_internal" = FALSE, + "balls_color" = "fff", + "balls_amount" = 2, + "balls_sack_size" = BALLS_SACK_SIZE_DEF, + "balls_size" = BALLS_SIZE_DEF, + "balls_cum_rate" = CUM_RATE, + "balls_cum_mult" = CUM_RATE_MULT, + "balls_efficiency" = CUM_EFFICIENCY, + "balls_fluid" = "semen", + "has_ovi" = FALSE, + "ovi_shape" = "knotted", + "ovi_length" = 6, + "ovi_color" = "fff", + "has_eggsack" = FALSE, + "eggsack_internal" = TRUE, + "eggsack_color" = "fff", + "eggsack_size" = BALLS_SACK_SIZE_DEF, + "eggsack_egg_color" = "fff", + "eggsack_egg_size" = EGG_GIRTH_DEF, + "has_breasts" = FALSE, + "breasts_color" = "fff", + "breasts_size" = "C", + "breasts_fluid" = "milk", + "has_vag" = FALSE, + "vag_color" = "fff", + "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, + "womb_fluid" = "femcum" + )//MAKE SURE TO UPDATE THE LIST IN MOBS.DM IF YOU'RE GOING TO ADD TO THIS LIST, OTHERWISE THINGS MIGHT GET FUCKEY + var/list/custom_names = list("clown", "mime", "ai", "cyborg", "religion", "deity") var/prefered_security_department = SEC_DEPT_RANDOM //Mob preview var/icon/preview_icon = null + var/icon/nude_preview_icon = null //Jobs, uses bitflags var/job_civilian_high = 0 @@ -90,7 +155,7 @@ var/list/preferences_datums = list() // Want randomjob if preferences already filled - Donkie var/joblessrole = BERANDOMJOB //defaults to 1 for fewer assistants - // 0 = character settings, 1 = game preferences + // 0 = character settings, 1 = game preferences, 2 = character appearance var/current_tab = 0 var/flavor_text = "" @@ -135,13 +200,18 @@ var/list/preferences_datums = list() /datum/preferences/proc/ShowChoices(mob/user) if(!user || !user.client) return - update_preview_icon() + if(current_tab == 2) + update_preview_icon(nude=TRUE) + else + update_preview_icon(nude=FALSE) user << browse_rsc(preview_icon, "previewicon.png") var/dat = "
" - dat += "Character Settings " + dat += "Character Settings" + dat += "Character Appearance" dat += "Game Preferences" + if(!path) dat += "
Please create an account to save your preferences
" @@ -179,7 +249,8 @@ var/list/preferences_datums = list() dat += "Gender: [gender == MALE ? "Male" : "Female"]
" dat += "Age: [age]
" - + dat += "Arousal:[arousable == TRUE ? "Enabled" : "Disabled"]
" + dat += "Exhibitionist:[features["exhibitionist"] == TRUE ? "Yes" : "No"]
" dat += "Special Names:
" dat += "Clown: [custom_names["clown"]] " dat += "Mime:[custom_names["mime"]]
" @@ -196,270 +267,9 @@ var/list/preferences_datums = list() dat += "
" dat += "" - - dat += "

Body

" - dat += "Random Body " - dat += "Always Random Body: [be_random_body ? "Yes" : "No"]
" - - dat += "" - - // dat += "Size:[character_size]
" - dat += "Set Flavor Text
" - if(lentext(flavor_text) <= 40) - if(!lentext(flavor_text)) - dat += "\[...\]" - else - dat += "[flavor_text]" - else - dat += "[TextPreview(flavor_text)]...
" dat += "
" - dat += "
" - if(pref_species.use_skintones) - - dat += "" - - if(HAIR in pref_species.species_traits) - - dat += "" - - if(EYECOLOR in pref_species.species_traits) - - dat += "" - - if(config.mutant_races) //We don't allow mutant bodyparts for humans either unless this is true. - - if((MUTCOLORS in pref_species.species_traits) || (MUTCOLORS_PARTSONLY in pref_species.species_traits)) - - dat += "" - - if("tail_lizard" in pref_species.mutant_bodyparts) - dat += "" - - if("snout" in pref_species.mutant_bodyparts) - dat += "" - - if("horns" in pref_species.mutant_bodyparts) - dat += "" - - if("frills" in pref_species.mutant_bodyparts) - dat += "" - - if("spines" in pref_species.mutant_bodyparts) - dat += "" - - if("body_markings" in pref_species.mutant_bodyparts) - dat += "" - - //Mammal bodyparts - if("mam_body_markings" in pref_species.mutant_bodyparts) - dat += "" - - if("mam_tail" in pref_species.mutant_bodyparts) - dat += "" - - if("mam_ears" in pref_species.mutant_bodyparts) - dat += "" - - if("taur" in pref_species.mutant_bodyparts) - dat += "" - -//Xeno Bodyparts - if("xenohead" in pref_species.mutant_bodyparts) - dat += "" - - if("xenotail" in pref_species.mutant_bodyparts) - dat += "" - - if("xenodorsal" in pref_species.mutant_bodyparts) - dat += "" - - if(config.mutant_humans) - - if("tail_human" in pref_species.mutant_bodyparts) - dat += "" - - if("ears" in pref_species.mutant_bodyparts) - dat += "" - - if("wings" in pref_species.mutant_bodyparts && r_wings_list.len >1) - dat += "" - - dat += "
" - - if(config.mutant_races) - dat += "Species:
[pref_species.id]
" - else - dat += "Species: Human
" - - dat += "Underwear:
[underwear]
" - dat += "Undershirt:
[undershirt]
" - dat += "Socks:
[socks]
" - dat += "Backpack:
[backbag]
" - dat += "Uplink Spawn Location:
[uplink_spawn_loc]
" - - dat += "

Skin Tone

" - - dat += "[skin_tone]
" - - dat += "
" - - dat += "

Hair Style

" - - dat += "[hair_style]
" - dat += "< >
" - dat += "    Change
" - - - dat += "
" - - dat += "

Facial Hair Style

" - - dat += "[facial_hair_style]
" - dat += "< >
" - dat += "    Change
" - - dat += "
" - - dat += "

Eye Color

" - - dat += "    Change
" - - dat += "
" - - dat += "

Alien/Mutant Colors

" - - dat += "    Change
" - - dat += "    Change
" - - dat += "    Change
" - - dat += "
" - - dat += "

Tail

" - - dat += "[features["tail_lizard"]]
" - - dat += "
" - - dat += "

Snout

" - - dat += "[features["snout"]]
" - - dat += "
" - - dat += "

Horns

" - - dat += "[features["horns"]]
" - - dat += "
" - - dat += "

Frills

" - - dat += "[features["frills"]]
" - - dat += "
" - - dat += "

Spines

" - - dat += "[features["spines"]]
" - - dat += "
" - - dat += "

Body Markings

" - - dat += "[features["body_markings"]]
" - - dat += "
" - - dat += "

Mammal Body Markings

" - - dat += "[features["mam_body_markings"]]
" - - dat += "
" - - dat += "

Tail

" - - dat += "[features["mam_tail"]]
" - - if("legs" in pref_species.mutant_bodyparts) - dat += "
" - - dat += "

Legs

" - - dat += "[features["legs"]]
" - - dat += "
" - - dat += "

Ears

" - - dat += "[features["mam_ears"]]
" - - dat += "
" - - dat += "

Taur Body

" - - dat += "[features["taur"]]
" - - dat += "
" - - dat += "

Head/Caste

" - - dat += "[features["xenohead"]]
" - - dat += "
" - - dat += "

Tail

" - - dat += "[features["xenotail"]]
" - - dat += "
" - - dat += "

Dorsal Tubes

" - - dat += "[features["xenodorsal"]]
" - - dat += "
" - - dat += "

Tail

" - - dat += "[features["tail_human"]]
" - - dat += "
" - - dat += "

Ears

" - - dat += "[features["ears"]]
" - - dat += "
" - - dat += "

Wings

" - - dat += "[features["wings"]]
" - - dat += "
" - //citadel code - if(NOGENITALS in pref_species.species_traits) - dat += "

Your species ([pref_species.name]) does not support genitals!

" - else - dat += "

Genitals

" - - dat += "" - - - dat += "
" - - dat += "" - - dat += "

Options

" - dat += "Arousal:[arousable == TRUE ? "Enabled" : "Disabled"]
" - dat += "

More Coming Soon(tm)

" - - dat += "
" - - if (1) // Game Preferences dat += "
" dat += "

General Settings

" @@ -546,6 +356,7 @@ var/list/preferences_datums = list() else dat += "High" dat += "
" +// dat += "Genital Colors:[features["genitals_use_skintone"] == TRUE ? "Skin Tone" : "Custom"]
" dat += "
" @@ -573,6 +384,127 @@ var/list/preferences_datums = list() dat += "
" + //Character Appearance + if(2) + dat += "" + */ + + + dat += "
" + dat += "

" + dat += "Set Flavor Text
" + if(lentext(flavor_text) <= 40) + if(!lentext(flavor_text)) + dat += "\[...\]" + else + dat += "[flavor_text]" + else + dat += "[TextPreview(flavor_text)]...
" + if(config.mutant_races)//really don't need this check, but fuck un-tabbing all those lines + dat += "

Body

" + dat += "Gender: [gender == MALE ? "Male" : "Female"]
" + dat += "Species:[pref_species.id]
" + dat += "Random Body
" + dat += "Always Random Body: [be_random_body ? "Yes" : "No"]
" + if((MUTCOLORS in pref_species.species_traits) || (MUTCOLORS_PARTSONLY in pref_species.species_traits)) + dat += "Primary Color:     Change
" + dat += "Secondary Color:     Change
" + dat += "Tertiary Color:     Change
" + if(pref_species.use_skintones) + dat += "Skin Tone: [skin_tone]
" + if(HAIR in pref_species.species_traits) + dat += "Hair Style: [hair_style]
" + dat += "Hair Color:     Change
" + dat += "Facial Hair Style: [facial_hair_style]
" + dat += "Facial Hair Color:     Change
" + if(EYECOLOR in pref_species.species_traits) + dat += "Eye Color:     Change
" + if("tail_lizard" in pref_species.mutant_bodyparts) + dat += "Tail: [features["tail_lizard"]]
" + else if("mam_tail" in pref_species.mutant_bodyparts) + dat += "Tail: [features["mam_tail"]]
" + else if("tail_human" in pref_species.mutant_bodyparts) + dat += "Tail: [features["tail_human"]]
" + if("snout" in pref_species.mutant_bodyparts) + dat += "Snout: [features["snout"]]
" + if("horns" in pref_species.mutant_bodyparts) + dat += "Snout: [features["horns"]]
" + if("frills" in pref_species.mutant_bodyparts) + dat += "Frills: [features["frills"]]
" + if("spines" in pref_species.mutant_bodyparts) + dat += "Spines: [features["spines"]]
" + if("body_markings" in pref_species.mutant_bodyparts) + dat += "Body Markings: [features["body_markings"]]
" + else if("mam_body_markings" in pref_species.mutant_bodyparts) + dat += "Body Markings: [features["mam_body_markings"]]
" + if("mam_ears" in pref_species.mutant_bodyparts) + dat += "Ears: [features["mam_ears"]]
" + else if("ears" in pref_species.mutant_bodyparts) + dat += "Ears: [features["ears"]]
" + if("legs" in pref_species.mutant_bodyparts) + dat += "Legs: [features["legs"]]
" + if("taur" in pref_species.mutant_bodyparts) + dat += "Taur: [features["taur"]]
" + if("wings" in pref_species.mutant_bodyparts && r_wings_list.len >1) + dat += "Wings: [features["wings"]]
" + if("xenohead" in pref_species.mutant_bodyparts) + dat += "Caste: [features["xenohead"]]
" + if("xenotail" in pref_species.mutant_bodyparts) + dat += "Tail: [features["xenotail"]]
" + if("xenodorsal" in pref_species.mutant_bodyparts) + dat += "Dorsal Tubes: [features["xenodorsal"]]
" + + dat += "
" + + + dat += "

Clothing & Equipment

" +//underwear will be refactored later so it fits in with other wearable equipment and isn't just an overlay +// dat += "Underwear:[underwear]
" +// dat += "Undershirt:[undershirt]
" +// dat += "Socks:[socks]
" + dat += "Backpack:[backbag]
" + dat += "Uplink Location:[uplink_spawn_loc]
" + + dat += "

Genitals

" + if(NOGENITALS in pref_species.species_traits) + dat += "Your species ([pref_species.name]) does not support genitals!
" + else + dat += "Has Penis:[features["has_cock"] == TRUE ? "Yes" : "No"]
" + if(features["has_cock"] == TRUE) + if(pref_species.use_skintones && features["genitals_use_skintone"] == TRUE) + dat += "Penis Color:   (Skin tone overriding)
" + else + dat += "Penis Color:    Change
" +// dat += "
" + dat += "Penis Shape: [features["cock_shape"]]
" + dat += "Penis Length: [features["cock_length"]] inch(es)
" + dat += "Has Testicles:[features["has_balls"] == TRUE ? "Yes" : "No"]
" + if(features["has_balls"] == TRUE) + dat += "Testicles Color:    Change
" + dat += "Has Vagina:[features["has_vag"] == TRUE ? "Yes" : "No"]
" + if(features["has_vag"]) + dat += "Vagina Color:    Change
" + dat += "Has Womb:[features["has_womb"] == TRUE ? "Yes" : "No"]
" + dat += "Has Breasts:[features["has_breasts"] == TRUE ? "Yes" : "No"]
" + if(features["has_breasts"]) +// if(pref_species.use_skintones) +// dat += "Color:   (Skin tone overriding)" +// else +// dat += "Color:    Change" + dat += "Cup Size:[features["breasts_size"]]
" + /* + dat += "

Ovipositor

" + dat += "Has Ovipositor:[features["has_ovi"] == TRUE ? "Yes" : "No"]" + if(features["has_ovi"]) + dat += "Ovi Color:    Change" + dat += "

Eggsack

" + dat += "Has Eggsack:[features["has_eggsack"] == TRUE ? "Yes" : "No"]
" + if(features["has_eggsack"] == TRUE) + dat += "Color:    Change" + dat += "Egg Color:    Change" + dat += "Egg Size:[features["eggsack_egg_size"]]\" Diameter" + + dat += "
" dat += "
" if(!IsGuestKey(user.key)) @@ -1122,24 +1054,33 @@ var/list/preferences_datums = list() new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in tails_list_lizard if(new_tail) features["tail_lizard"] = new_tail + if(new_tail != "None") + features["taur"] = "None" if("tail_human") var/new_tail new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in tails_list_human if(new_tail) features["tail_human"] = new_tail + if(new_tail != "None") + features["taur"] = "None" if("mam_tail") var/new_tail new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in mam_tails_list if(new_tail) features["mam_tail"] = new_tail + if(new_tail != "None") + features["taur"] = "None" if("taur") var/new_taur new_taur = input(user, "Choose your character's tauric body:", "Character Preference") as null|anything in taur_list if(new_taur) features["taur"] = new_taur + if(new_taur != "None") + features["mam_tail"] = "None" + features["xenotail"] = "None" /* Doesn't exist yet. will include facial overlays to mimic 5th port species heads. if("mam_snout") @@ -1326,6 +1267,82 @@ var/list/preferences_datums = list() if(pickedui) UI_style = pickedui + //citadel code + if("cock_color") + var/new_cockcolor = input(user, "Penis color:", "Character Preference") as color|null + if(new_cockcolor) + var/temp_hsv = RGBtoHSV(new_cockcolor) + if(new_cockcolor == "#000000") + features["cock_color"] = pref_species.default_color + else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) + features["cock_color"] = sanitize_hexcolor(new_cockcolor) + else + user << "Invalid color. Your color is not bright enough." + + if("cock_length") + var/new_length = input(user, "Penis length in inches:\n([COCK_SIZE_MIN]-[COCK_SIZE_MAX])", "Character Preference") as num|null + if(new_length) + features["cock_length"] = max(min( round(text2num(new_length)), COCK_SIZE_MAX),COCK_SIZE_MIN) + + if("cock_shape") + var/new_shape + new_shape = input(user, "Penis shape:", "Character Preference") as null|anything in cock_shapes_list + if(new_shape) + features["cock_shape"] = new_shape + + if("balls_color") + var/new_ballscolor = input(user, "Testicle Color:", "Character Preference") as color|null + if(new_ballscolor) + var/temp_hsv = RGBtoHSV(new_ballscolor) + if(new_ballscolor == "#000000") + features["balls_color"] = pref_species.default_color + else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) + features["balls_color"] = sanitize_hexcolor(new_ballscolor) + else + user << "Invalid color. Your color is not bright enough." + + if("egg_size") + var/new_size + var/list/egg_sizes = list(1,2,3) + new_size = input(user, "Egg Diameter(inches):", "Egg Size") as null|anything in egg_sizes + if(new_size) + features["eggsack_egg_size"] = new_size + + if("egg_color") + var/new_egg_color = input(user, "Egg Color:", "Character Preference") as color|null + if(new_egg_color) + var/temp_hsv = RGBtoHSV(new_egg_color) + if(ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) + features["eggsack_egg_color"] = sanitize_hexcolor(new_egg_color) + else + user << "Invalid color. Your color is not bright enough." + if("breasts_size") + var/new_size + new_size = input(user, "Breast Size", "Character Preference") as null|anything in breasts_size_list + if(new_size) + features["breasts_size"] = new_size + + if("breasts_color") + var/new_breasts_color = input(user, "Breast Color:", "Character Preference") as color|null + if(new_breasts_color) + var/temp_hsv = RGBtoHSV(new_breasts_color) + if(new_breasts_color == "#000000") + features["breasts_color"] = pref_species.default_color + else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) + features["breasts_color"] = sanitize_hexcolor(new_breasts_color) + else + user << "Invalid color. Your color is not bright enough." + if("vag_color") + var/new_vagcolor = input(user, "Vagina color:", "Character Preference") as color|null + if(new_vagcolor) + var/temp_hsv = RGBtoHSV(new_vagcolor) + if(new_vagcolor == "#000000") + features["vag_color"] = pref_species.default_color + else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) + features["vag_color"] = sanitize_hexcolor(new_vagcolor) + else + user << "Invalid color. Your color is not bright enough." + else switch(href_list["preference"]) @@ -1339,6 +1356,105 @@ var/list/preferences_datums = list() arousable = TRUE else//failsafe arousable = FALSE + if("has_cock") + switch(features["has_cock"]) + if(TRUE) + features["has_cock"] = FALSE + if(FALSE) + features["has_cock"] = TRUE + features["has_ovi"] = FALSE + features["has_eggsack"] = FALSE + else + features["has_cock"] = FALSE + features["has_ovi"] = FALSE + if("has_balls") + switch(features["has_balls"]) + if(TRUE) + features["has_balls"] = FALSE + if(FALSE) + features["has_balls"] = TRUE + features["has_eggsack"] = FALSE + else + features["has_balls"] = FALSE + features["has_eggsack"] = FALSE + + if("has_ovi") + switch(features["has_ovi"]) + if(TRUE) + features["has_ovi"] = FALSE + if(FALSE) + features["has_ovi"] = TRUE + features["has_cock"] = FALSE + features["has_balls"] = FALSE + else + features["has_ovi"] = FALSE + features["has_cock"] = FALSE + + if("has_eggsack") + switch(features["has_eggsack"]) + if(TRUE) + features["has_eggsack"] = FALSE + if(FALSE) + features["has_eggsack"] = TRUE + features["has_balls"] = FALSE + else + features["has_eggsack"] = FALSE + features["has_balls"] = FALSE + + if("balls_internal") + switch(features["balls_internal"]) + if(TRUE) + features["balls_internal"] = FALSE + if(FALSE) + features["balls_internal"] = TRUE + features["eggsack_internal"] = FALSE + else + features["balls_internal"] = FALSE + features["eggsack_internal"] = FALSE + + if("eggsack_internal") + switch(features["eggsack_internal"]) + if(TRUE) + features["eggsack_internal"] = FALSE + if(FALSE) + features["eggsack_internal"] = TRUE + features["balls_internal"] = FALSE + else + features["eggsack_internal"] = FALSE + features["balls_internal"] = FALSE + + if("has_breasts") + switch(features["has_breasts"]) + if(TRUE) + features["has_breasts"] = FALSE + if(FALSE) + features["has_breasts"] = TRUE + else + features["has_breasts"] = FALSE + if("has_vag") + switch(features["has_vag"]) + if(TRUE) + features["has_vag"] = FALSE + if(FALSE) + features["has_vag"] = TRUE + else + features["has_vag"] = FALSE + if("has_womb") + switch(features["has_womb"]) + if(TRUE) + features["has_womb"] = FALSE + if(FALSE) + features["has_womb"] = TRUE + else + features["has_womb"] = FALSE + if("exhibitionist") + switch(features["exhibitionist"]) + if(TRUE) + features["exhibitionist"] = FALSE + if(FALSE) + features["exhibitionist"] = TRUE + else + features["exhibitionist"] = FALSE if("publicity") if(unlock_content) @@ -1348,11 +1464,11 @@ var/list/preferences_datums = list() gender = FEMALE else gender = MALE - underwear = random_underwear(gender) - undershirt = random_undershirt(gender) - socks = random_socks() - facial_hair_style = random_facial_hair_style(gender) - hair_style = random_hair_style(gender) + underwear = "Nude" + undershirt = "Nude" + socks = "Nude" + facial_hair_style = "Shaved" + hair_style = "Bald" if("hotkeys") hotkeys = !hotkeys @@ -1490,6 +1606,8 @@ var/list/preferences_datums = list() else chosen_species = /datum/species/human character.set_species(chosen_species, icon_update=0) + //citadel code + character.give_genitals() if(icon_updates) character.update_body() diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 83735853c9..551d18e246 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -8,14 +8,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car This proc checks if the current directory of the savefile S needs updating It is to be used by the load_character and load_preferences procs. (S.cd=="/" is preferences, S.cd=="/character[integer]" is a character slot, etc) - if the current directory's version is below SAVEFILE_VERSION_MIN it will simply wipe everything in that directory (if we're at root "/" then it'll just wipe the entire savefile, for instance.) - if its version is below SAVEFILE_VERSION_MAX but above the minimum, it will load data but later call the respective update_preferences() or update_character() proc. Those procs allow coders to specify format changes so users do not lose their setups and have to redo them again. - Failing all that, the standard sanity checks are performed. They simply check the data is suitable, reverting to initial() values if necessary. */ @@ -312,6 +309,27 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["feature_xeno_dors"] >> features["xenodorsal"] S["feature_xeno_head"] >> features["xenohead"] S["feature_lizard_legs"] >> features["legs"] + //cock features + S["feature_has_cock"] >> features["has_cock"] + S["feature_cock_shape"] >> features["cock_shape"] + S["feature_cock_color"] >> features["cock_color"] + S["feature_cock_length"] >> features["cock_length"] + S["feature_cock_girth"] >> features["cock_girth"] + S["feature_has_sheath"] >> features["sheath_color"] + //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_sack_size"] >> features["balls_sack_size"] + S["feature_balls_fluid"] >> features["balls_fluid"] + //breasts features + S["feature_has_breasts"] >> features["has_breasts"] + S["feature_breasts_size"] >> features["breasts_size"] + S["feature_breasts_color"] >> features["breasts_color"] + S["feature_breasts_fluid"] >> features["breasts_fluid"] + //vagina features + S["feature_has_vag"] >> features["has_vag"] + S["feature_vag_color"] >> features["vag_color"] if(!config.mutant_humans) features["tail_human"] = "none" features["ears"] = "none" @@ -361,14 +379,17 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car if(gender == MALE) hair_style = sanitize_inlist(hair_style, hair_styles_male_list) facial_hair_style = sanitize_inlist(facial_hair_style, facial_hair_styles_male_list) - underwear = sanitize_inlist(underwear, underwear_m) - undershirt = sanitize_inlist(undershirt, undershirt_m) +// underwear = sanitize_inlist(underwear, underwear_m) +// undershirt = sanitize_inlist(undershirt, undershirt_m) else hair_style = sanitize_inlist(hair_style, hair_styles_female_list) facial_hair_style = sanitize_inlist(facial_hair_style, facial_hair_styles_female_list) - underwear = sanitize_inlist(underwear, underwear_f) - undershirt = sanitize_inlist(undershirt, undershirt_f) - socks = sanitize_inlist(socks, socks_list) +// underwear = sanitize_inlist(underwear, underwear_f) +// undershirt = sanitize_inlist(undershirt, undershirt_f) +// socks = sanitize_inlist(socks, socks_list) + underwear = "Nude" + undershirt = "Nude" + socks = "Nude" age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age)) hair_color = sanitize_hexcolor(hair_color, 3, 0) facial_hair_color = sanitize_hexcolor(facial_hair_color, 3, 0) @@ -396,6 +417,25 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car features["xenohead"] = sanitize_inlist(features["xenohead"], xeno_head_list) features["xenodorsal"] = sanitize_inlist(features["xenodorsal"], xeno_dorsal_list) features["feature_lizard_legs"] = sanitize_inlist(features["legs"], legs_list, "Normal Legs") + //cock features + features["has_cock"] = sanitize_integer(features["has_cock"], 0, 1, 0) + features["cock_shape"] = sanitize_inlist(features["cock_shape"], cock_shapes_list, "Human") + features["cock_color"] = sanitize_hexcolor(features["cock_color"], 3, 0) + features["cock_length"] = sanitize_integer(features["cock_length"], COCK_SIZE_MIN, COCK_SIZE_MAX, 6) + //balls features + features["has_balls"] = sanitize_integer(features["has_balls"], 0, 1, 0) + features["balls_color"] = sanitize_hexcolor(features["balls_color"], 3, 0) + features["balls_size"] = sanitize_integer(features["balls_size"], BALLS_SIZE_MIN, BALLS_SIZE_MAX, BALLS_SIZE_DEF) + features["balls_sack_size"] = sanitize_integer(features["balls_sack_size"], BALLS_SACK_SIZE_MIN, BALLS_SACK_SIZE_MAX, BALLS_SACK_SIZE_DEF) + features["balls_fluid"] = sanitize_inlist(features["balls_fluid"], cum_id_list, "semen") + //breasts features + features["has_breasts"] = sanitize_integer(features["has_breasts"], 0, 1, 0) + features["breasts_size"] = sanitize_inlist(features["breasts_size"], breasts_size_list, "C") + features["breasts_color"] = sanitize_hexcolor(features["breasts_color"], 3, 0) + features["breasts_fluid"] = sanitize_inlist(features["breasts_fluid"], cum_id_list, "semen") + //vagina features + features["has_vag"] = sanitize_integer(features["has_vag"], 0, 1, 0) + features["vag_color"] = sanitize_hexcolor(features["breasts_color"], 3, 0) joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole)) job_civilian_high = sanitize_integer(job_civilian_high, 0, 65535, initial(job_civilian_high)) @@ -468,6 +508,27 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car S["religion_name"] << custom_names["religion"] S["deity_name"] << custom_names["deity"] S["prefered_security_department"] << prefered_security_department + //cock features + S["feature_has_cock"] << features["has_cock"] + S["feature_cock_shape"] << features["cock_shape"] + S["feature_cock_color"] << features["cock_color"] + S["feature_cock_length"] << features["cock_length"] + S["feature_cock_girth"] << features["cock_girth"] + S["feature_has_sheath"] << features["sheath_color"] + //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_sack_size"] << features["balls_sack_size"] + S["feature_balls_fluid"] << features["balls_fluid"] + //breasts features + S["feature_has_breasts"] << features["has_breasts"] + S["feature_breasts_size"] << features["breasts_size"] + S["feature_breasts_color"] << features["breasts_color"] + S["feature_breasts_fluid"] << features["breasts_fluid"] + //vagina features + S["feature_has_vag"] << features["has_vag"] + S["feature_vag_color"] << features["vag_color"] //Jobs S["joblessrole"] << joblessrole @@ -496,4 +557,4 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car /client/verb/savefile_import(path as text) var/savefile/S = new /savefile(path) S.ImportText("/",file("[path].txt")) -*/ +*/ \ No newline at end of file diff --git a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm index a3c076a81d..b6ccee3f7c 100644 --- a/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm +++ b/code/modules/food_and_drinks/drinks/drinks/drinkingglass.dm @@ -517,6 +517,22 @@ icon_state = "glass_yellow" name = "Eggnog" desc = "For enjoying the most wonderful time of the year." + if("aphro") + icon_state = "glass_aphro" + name = "glass of aphrodisiac" + desc = "For your love interest." + if("aphro+") + icon_state = "glass_aphro+" + name = "glass of strong aphrodisiac" + desc = "For your less interested love interest." + if("semen") + icon_state = "glass_semen" + name = "glass of semen" + desc = "Salty." + if("femcum") + icon_state = "glass_femcum" + name = "glass of female ejaculate" + desc = "A glass of female ejaculate." else icon_state ="glass_brown" var/image/I = image(icon, "glassoverlay") @@ -627,6 +643,18 @@ icon_state = "shotglassgreen" name = "shot of absinthe" desc = "I am stuck in the cycles of my guilt..." + if ("semen") + icon_state = "shotglasswhite" + name = "cum shot" + desc = "All those college years boil down to this." + if("aphro") + icon_state = "shotglassaphro" + name = "shot of love" + desc = "Guaranteed to put you in the mood." + if("aphro+") + icon_state = "shotglassaphro" + name = "strong shot of love" + desc = "Guaranteed to put you in the mood. Not recommended to take more than one unless you're dedicated." else icon_state = "shotglassbrown" name = "shot of... what?" @@ -648,7 +676,7 @@ /obj/item/weapon/reagent_containers/food/drinks/drinkingglass/filled/cola name = "Space Cola" list_reagents = list("cola" = 50) - + /obj/item/weapon/reagent_containers/food/drinks/drinkingglass/filled/nuka_cola name = "Nuka Cola" list_reagents = list("nuka_cola" = 50) diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm index c4584d01dd..06c6982b35 100644 --- a/code/modules/mob/living/carbon/damage_procs.dm +++ b/code/modules/mob/living/carbon/damage_procs.dm @@ -36,6 +36,8 @@ adjustCloneLoss(damage * hit_percent) if(STAMINA) adjustStaminaLoss(damage * hit_percent) + if(AROUSAL) + adjustArousalLoss(damage * hit_percent) return 1 diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 06c7144c44..264bf56cbe 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -28,6 +28,9 @@ if (notransform) return + //citadel code + if(stat != DEAD) + handle_arousal() if(..()) //not dead for(var/datum/mutation/human/HM in dna.mutations) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 443fb6e3fb..828419cb5e 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -269,6 +269,7 @@ standing += img_eyes //Underwear, Undershirts & Socks + /*This will be refactored at a later date if(H.underwear) var/datum/sprite_accessory/underwear/underwear = underwear_list[H.underwear] if(underwear) @@ -286,11 +287,13 @@ var/datum/sprite_accessory/socks/socks = socks_list[H.socks] if(socks) standing += image("icon"=socks.icon, "icon_state"="[socks.icon_state]", "layer"=-BODY_LAYER) - + */ if(standing.len) H.overlays_standing[BODY_LAYER] = standing H.apply_overlay(BODY_LAYER) + //citadel code + handle_genitals(H) handle_mutant_bodyparts(H) /datum/species/proc/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour) @@ -392,9 +395,9 @@ bodyparts_to_add -= "mam_ears" if("taur" in mutant_bodyparts) - if(!H.dna.features["taur"] || H.dna.features["taur"] == "None" || !H.dna.features["mam_tail"] == "None" || !H.dna.features["mam_waggingtail"] == "None") + if(!H.dna.features["taur"] || H.dna.features["taur"] == "None") bodyparts_to_add -= "taur" - + else //Digitigrade legs are stuck in the phantom zone between true limbs and mutant bodyparts. Mainly it just needs more agressive updating than most limbs. var/update_needed = FALSE diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index a666573d16..421a67c5b4 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -265,8 +265,11 @@ There are several things that need to be remembered: if(hud_used.inventory_shown) //if the inventory is open client.screen += shoes //add it to client's screen update_observer_view(shoes,1) - var/image/standing = shoes.build_worn_icon(state = shoes.icon_state, default_layer = SHOES_LAYER, default_icon_file = 'icons/mob/feet.dmi') - overlays_standing[SHOES_LAYER] = standing + if("taur" in dna.species.mutant_bodyparts) + switch(dna.features["taur"]) + if(!"Naga" || "None") + var/image/standing = shoes.build_worn_icon(state = shoes.icon_state, default_layer = SHOES_LAYER, default_icon_file = 'icons/mob/feet.dmi') + overlays_standing[SHOES_LAYER] = standing apply_overlay(SHOES_LAYER) diff --git a/code/modules/mob/living/carbon/update_icons.dm b/code/modules/mob/living/carbon/update_icons.dm index ec5689d782..a78674c42b 100644 --- a/code/modules/mob/living/carbon/update_icons.dm +++ b/code/modules/mob/living/carbon/update_icons.dm @@ -224,6 +224,9 @@ /mob/living/carbon/proc/update_body_parts() //CHECK FOR UPDATE var/oldkey = icon_render_key + var/istaur = 0 + if("taur" in dna.species.mutant_bodyparts && dna.features["taur"] != "None") + istaur = 1 icon_render_key = generate_icon_render_key() if(oldkey == icon_render_key) return @@ -232,6 +235,8 @@ for(var/X in bodyparts) var/obj/item/bodypart/BP = X + if(istaur && (istype(BP, /obj/item/bodypart/r_leg) || istype(BP, /obj/item/bodypart/l_leg)) ) + continue BP.update_limb() //LOAD ICONS diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm index 499bcb328f..8f05c8853f 100644 --- a/code/modules/mob/new_player/preferences_setup.dm +++ b/code/modules/mob/new_player/preferences_setup.dm @@ -5,9 +5,6 @@ gender = gender_override else gender = pick(MALE,FEMALE) - underwear = random_underwear(gender) - undershirt = random_undershirt(gender) - socks = random_socks() skin_tone = random_skin_tone() hair_style = random_hair_style(gender) facial_hair_style = random_facial_hair_style(gender) @@ -17,12 +14,16 @@ if(!pref_species) var/rando_race = pick(config.roundstart_races) pref_species = new rando_race() - backbag = 1 features = random_features() age = rand(AGE_MIN,AGE_MAX) -/datum/preferences/proc/update_preview_icon() +/datum/preferences/proc/update_preview_icon(nude=FALSE) // Silicons only need a very basic preview since there is no customization for them. + var/wide_icon = 0 + var/stamp_x = 0 + var/stamp_y = 1 + if(features["taur"] != "None") + wide_icon = 1 if(job_engsec_high) switch(job_engsec_high) if(AI) @@ -41,45 +42,56 @@ // Determine what job is marked as 'High' priority, and dress them up as such. var/datum/job/previewJob var/highRankFlag = job_civilian_high | job_medsci_high | job_engsec_high + if(!nude) + if(job_civilian_low & ASSISTANT) + previewJob = SSjob.GetJob("Assistant") + else if(highRankFlag) + var/highDeptFlag + if(job_civilian_high) + highDeptFlag = CIVILIAN + else if(job_medsci_high) + highDeptFlag = MEDSCI + else if(job_engsec_high) + highDeptFlag = ENGSEC - if(job_civilian_low & ASSISTANT) - previewJob = SSjob.GetJob("Assistant") - else if(highRankFlag) - var/highDeptFlag - if(job_civilian_high) - highDeptFlag = CIVILIAN - else if(job_medsci_high) - highDeptFlag = MEDSCI - else if(job_engsec_high) - highDeptFlag = ENGSEC - - for(var/datum/job/job in SSjob.occupations) - if(job.flag == highRankFlag && job.department_flag == highDeptFlag) - previewJob = job - break + for(var/datum/job/job in SSjob.occupations) + if(job.flag == highRankFlag && job.department_flag == highDeptFlag) + previewJob = job + break if(previewJob) mannequin.job = previewJob.title previewJob.equip(mannequin, TRUE) CHECK_TICK preview_icon = icon('icons/effects/effects.dmi', "nothing") - preview_icon.Scale(48+32, 16+32) + preview_icon.Scale((112), (32)) CHECK_TICK mannequin.setDir(NORTH) - var/icon/stamp = getFlatIcon(mannequin) + if(wide_icon) + stamp_x = 16 + else + stamp_x = 32 CHECK_TICK - preview_icon.Blend(stamp, ICON_OVERLAY, 25, 17) + preview_icon.Blend(stamp, ICON_OVERLAY, stamp_x, stamp_y) CHECK_TICK mannequin.setDir(WEST) stamp = getFlatIcon(mannequin) + if(wide_icon) + stamp_x = 48 + else + stamp_x = 64 CHECK_TICK - preview_icon.Blend(stamp, ICON_OVERLAY, 1, 9) + preview_icon.Blend(stamp, ICON_OVERLAY, stamp_x, stamp_y) CHECK_TICK mannequin.setDir(SOUTH) stamp = getFlatIcon(mannequin) + if(wide_icon) + stamp_x = -15 + else + stamp_x = 1 CHECK_TICK - preview_icon.Blend(stamp, ICON_OVERLAY, 49, 1) + preview_icon.Blend(stamp, ICON_OVERLAY, stamp_x, stamp_y) CHECK_TICK preview_icon.Scale(preview_icon.Width() * 2, preview_icon.Height() * 2) // Scaling here to prevent blurring in the browser. CHECK_TICK diff --git a/code/modules/reagents/kegs.dm b/code/modules/reagents/kegs.dm deleted file mode 100644 index 6767c52218..0000000000 --- a/code/modules/reagents/kegs.dm +++ /dev/null @@ -1,42 +0,0 @@ -/obj/structure/reagent_dispensers/keg - name = "keg" - desc = "A keg." - icon_state = "keg" - var/reagent_type = "water" - -/obj/structure/reagent_dispensers/keg/New() - ..() - reagents.add_reagent(reagent_type,1000) - -/obj/structure/reagent_dispensers/keg/blob_act() - qdel(src) - -/obj/structure/reagent_dispensers/keg/mead - name = "keg of mead" - desc = "A keg of mead." - icon_state = "orangekeg" - reagent_type = "mead" - -/obj/structure/reagent_dispensers/keg/aphro - name = "keg of aphrodisiac" - desc = "A keg of aphrodisiac." - icon_state = "pinkkeg" - reagent_type = "hornychem" - -/obj/structure/reagent_dispensers/keg/milk - name = "keg of milk" - desc = "It's not quite what you were hoping for." - icon_state = "whitekeg" - reagent_type = "milk" - -/obj/structure/reagent_dispensers/keg/semen - name = "keg of semen" - desc = "Dear lord, where did this even come from?" - icon_state = "whitekeg" - reagent_type = "semen" - -/obj/structure/reagent_dispensers/keg/gargle - name = "keg of pan galactic gargleblaster" - desc = "A keg of... wow that's a long name." - icon_state = "bluekeg" - reagent_type = "gargleblaster" \ No newline at end of file diff --git a/icons/mob/pai.dmi b/icons/mob/pai.dmi index ddb1d8f725..6e74c17587 100644 Binary files a/icons/mob/pai.dmi and b/icons/mob/pai.dmi differ diff --git a/icons/mob/special/mam_taur.dmi b/icons/mob/special/mam_taur.dmi index fae756e188..4626f63404 100644 Binary files a/icons/mob/special/mam_taur.dmi and b/icons/mob/special/mam_taur.dmi differ diff --git a/icons/obj/drinks.dmi b/icons/obj/drinks.dmi index c03eef3497..3971257a95 100644 Binary files a/icons/obj/drinks.dmi and b/icons/obj/drinks.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 275c8d1dba..324fd77536 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -143,13 +143,23 @@ #include "code\_onclick\hud\robot.dm" #include "code\_onclick\hud\screen_objects.dm" #include "code\_onclick\hud\swarmer.dm" -#include "code\citadel\_helpers.dm" +#include "code\citadel\_cit_helpers.dm" #include "code\citadel\cit_areas.dm" #include "code\citadel\cit_arousal.dm" +#include "code\citadel\cit_genemods.dm" +#include "code\citadel\cit_kegs.dm" #include "code\citadel\cit_reagents.dm" #include "code\citadel\cit_uniforms.dm" #include "code\citadel\discordbot.dm" -#include "code\citadel\kegs.dm" +#include "code\citadel\organs\breasts.dm" +#include "code\citadel\organs\eggsack.dm" +#include "code\citadel\organs\genitals.dm" +#include "code\citadel\organs\genitals_sprite_accessories.dm" +#include "code\citadel\organs\ovipositor.dm" +#include "code\citadel\organs\penis.dm" +#include "code\citadel\organs\testicles.dm" +#include "code\citadel\organs\vagina.dm" +#include "code\citadel\organs\womb.dm" #include "code\controllers\admin.dm" #include "code\controllers\configuration.dm" #include "code\controllers\controller.dm"