Skip to content

Commit

Permalink
Merge pull request #2607 from Superlagg/makes-dummies-less-dumm
Browse files Browse the repository at this point in the history
fixes dummies
  • Loading branch information
Superlagg committed Jul 7, 2023
2 parents 5e4e6f1 + bfa63cf commit 55a7922
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 77 deletions.
30 changes: 30 additions & 0 deletions code/__HELPERS/_lists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -870,3 +870,33 @@
return (call(cmp)(L[i],A) > 0) ? i : i+1
else
return i

/// Takes a list, and applies a weight multiplier to each element, starting at 1 and multiplying by weight_mult each time
/// Makes a weighted list that heavily favors the first elements
/// If reverse is true, it starts at the end of the list and works backwards
/// Only feed it an unassociated list, or an associated list with only numeric values
/proc/WeightedCascadingPicker(list/input, weight_mult = 2, reverse, numberify)
if(!LAZYLEN(input))
return list()
var/list/ret = list() // Retival mankind's batman
var/weight = 1
if(reverse)
weight = (abs(weight_mult) ** (length(input) - 1))
weight_mult = (1 / abs(weight_mult))
for(var/i in 1 to length(input))
ret["[i]"] = weight
weight = abs(round(weight *= weight_mult))
var/index = text2num(pickweight(ret))
var/out = LAZYACCESS(input, index)
if(numberify)
out = text2num(out)
return out //outeval mankind's batman

/// Like the above, but it takes a range instead of a list
/proc/WeightedCascadingPickerRange(low, high, weight_mult = 2, reverse)
var/list/input = list()
for(var/i in low to high)
input += "[i]"
return WeightedCascadingPicker(input, weight_mult, reverse, TRUE)


22 changes: 20 additions & 2 deletions code/__HELPERS/unsorted.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1672,5 +1672,23 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
return LAZYACCESS(first_last, 1)
return rname



/// Makes a gaussian distribution, returning a positive integer
/proc/GaussianReacharound(mean, stddev, min, max)
var/cool_input = gaussian(mean, stddev)
cool_input = abs(cool_input)
cool_input = round(cool_input)
cool_input = clamp(cool_input, min, max)
return cool_input

/proc/GaussianListPicker(list/input, mean, stddev)
if(!LAZYLEN(input))
return
var/index = GaussianReacharound(mean, stddev, 0, LAZYLEN(input))
var/output = LAZYACCESS(input, index)
if(!output)
output = pick(input) // shruggaroni
return output

/proc/GaussianRangePicker(min, max, mean, stddev)
var/index = GaussianReacharound(mean, stddev, min, max)
return index
46 changes: 28 additions & 18 deletions code/controllers/subsystem/dummies.dm
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ SUBSYSTEM_DEF(dummy) // who ya callin dummy, dummy?
var/list/naked_player_cache = list()
/// Pictures of everyone at various moments, clothed~
/// list("ckey" = list(image, image, image))
var/list/very_naked_player_cache = list()
/// Pictures of everyone at various moments, clothed~
/// list("ckey" = list(image, image, image))
var/list/clothed_player_cache = list()
/// Pictures of everyone at various moments, clothed~
/// list("ckey" = list(image, image, image))
Expand Down Expand Up @@ -73,7 +76,8 @@ SUBSYSTEM_DEF(dummy) // who ya callin dummy, dummy?
random_clothes,
copy_equipment,
genitals,
cache = TRUE
cache = TRUE,
underwear = TRUE,
)
var/image_key = generate_key(slotkey, spec, clothes, template, client_or_prefs, loadout, random_body, random_species, random_clothes, copy_equipment, genitals, cache)
if(LAZYACCESS(image_cache, image_key))
Expand All @@ -88,35 +92,39 @@ SUBSYSTEM_DEF(dummy) // who ya callin dummy, dummy?
else if (istype(client_or_prefs, /datum/preferences))
var/datum/preferences/P = client_or_prefs
clint = P.parent
else if(istype(template) && template.client)
clint = template.client
if(!template && ishuman(clint.mob))
template = clint.mob

if(istype(clint))
var/datum/preferences/P = clint.prefs
P?.copy_to(mannequin)
if(istype(template))
copy_human_mob(template, mannequin)
if(copy_equipment)
copy_equipped(template, mannequin)
else if(istype(clint))
var/datum/preferences/P = clint.prefs
P.copy_to(mannequin)
if(copy_equipment && ishuman(clint.mob))
copy_equipped(clint.mob, mannequin)
else
if(random_species && !ispath(spec))
spec = pick(list(/datum/species/human, /datum/species/lizard, /datum/species/mammal))
if(ispath(spec))
mannequin.set_species(spec)
if(random_body)
randomize_human(mannequin, spec)
if(copy_equipment && (istype(template) || istype(clint)))
copy_equipped(template, mannequin)
else
if(random_clothes && !ispath(clothes))
randomize_human(mannequin, spec, underwear, genitals)
if(random_clothes)
if(!ispath(clothes))
clothes = pick(subtypesof(/datum/outfit/job))
if(ispath(clothes))
else
random_clothes = FALSE
clothes = new clothes()
var/datum/preferences/P = clint?.prefs
clothes.equip(mannequin, TRUE, P)
clothes.equip(mannequin, TRUE, clint)
if(!genitals)
for(var/obj/item/organ/genital/nad in mannequin.internal_organs)
qdel(nad) // say bye to ur naddies
if(!underwear)
mannequin.underwear = "Nude"
mannequin.socks = "Nude"
mannequin.undershirt = "Nude"

mannequin.update_body(TRUE)
mannequin.update_hair()
Expand Down Expand Up @@ -263,10 +271,7 @@ SUBSYSTEM_DEF(dummy) // who ya callin dummy, dummy?
return LAZYACCESS(image_cache, slutkey)
return get_dummy_image("PLAYER", template = H, client_or_prefs = clont, copy_equipment = equipped)

/datum/controller/subsystem/dummy/proc/capture_snapshot_of_players(obey_cooldown)
if(obey_cooldown && !COOLDOWN_FINISHED(src, snapshot_cooldown))
return
COOLDOWN_START(src, snapshot_cooldown, 5 MINUTES)
/datum/controller/subsystem/dummy/proc/capture_snapshot_of_players()
for(var/client/C in GLOB.clients)
snapshot_player(C)

Expand All @@ -283,17 +288,22 @@ SUBSYSTEM_DEF(dummy) // who ya callin dummy, dummy?
H = C.mob
if(!ishuman(H))
return
if(!LAZYACCESS(very_naked_player_cache, "[C.ckey]%%[H.real_name]"))
very_naked_player_cache["[C.ckey]%%[H.real_name]"] = list()
if(!LAZYACCESS(naked_player_cache, "[C.ckey]%%[H.real_name]"))
naked_player_cache["[C.ckey]%%[H.real_name]"] = list()
if(!LAZYACCESS(clothed_player_cache, "[C.ckey]%%[H.real_name]"))
clothed_player_cache["[C.ckey]%%[H.real_name]"] = list()
if(!LAZYACCESS(randomclothed_player_cache, "[C.ckey]%%[H.real_name]"))
randomclothed_player_cache["[C.ckey]%%[H.real_name]"] = list()
var/image/naked = get_dummy_image("PLAYER", template = H, client_or_prefs = C, random_body = FALSE, random_species = FALSE, random_clothes = FALSE)
var/image/supernaked = get_dummy_image("PLAYER", template = H, client_or_prefs = C, random_body = FALSE, random_species = FALSE, random_clothes = FALSE, underwear = FALSE, genitals = TRUE)
var/image/clothed = get_dummy_image("PLAYER", template = H, client_or_prefs = C, random_body = FALSE, random_species = FALSE, random_clothes = FALSE, copy_equipment = TRUE)
var/image/clothed2 = get_dummy_image("PLAYER", template = H, client_or_prefs = C, random_body = FALSE, random_species = FALSE, random_clothes = TRUE)
if(naked)
naked_player_cache["[C.ckey]%%[H.real_name]"] |= naked
if(supernaked)
very_naked_player_cache["[C.ckey]%%[H.real_name]"] |= supernaked
if(clothed)
clothed_player_cache["[C.ckey]%%[H.real_name]"] |= clothed
if(clothed2)
Expand Down
14 changes: 10 additions & 4 deletions code/game/objects/items/mannequin.dm
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@
var/my_ckey
var/my_name
var/nude = TRUE
var/very_nude = FALSE
var/random_clothes = FALSE

/obj/item/ckey_mannequin/clothed
Expand All @@ -171,6 +172,9 @@
/obj/item/ckey_mannequin/clothed/random
random_clothes = TRUE

/obj/item/ckey_mannequin/very_nude
very_nude = TRUE

/obj/item/ckey_mannequin/attack_hand(mob/user, act_intent, attackchain_flags)
if(!attune_to(user))
return ..()
Expand All @@ -187,13 +191,13 @@
visible_message("[user] touches [src], and it transforms!")
my_ckey = user.ckey
my_name = user.real_name
SSdummy.snapshot_player(my_ckey)
START_PROCESSING(SSobj, src)
update_icon()
return TRUE

/obj/item/ckey_mannequin/process()
update_icon()
if(prob(1))
if(prob(5))
switch(rand(1,5))
if(1)
step_rand(src)
Expand All @@ -205,6 +209,7 @@
TOGGLE_VAR(nude)
if(5)
TOGGLE_VAR(random_clothes)
update_icon()

/obj/item/ckey_mannequin/update_overlays()
. = ..()
Expand All @@ -215,10 +220,11 @@
name = initial(name)
desc = initial(desc)
return
SSdummy.snapshot_player(my_ckey)
var/list/imglist
var/list/cool_list
if(nude)
if(very_nude)
cool_list = SSdummy.very_naked_player_cache
else if(nude)
cool_list = SSdummy.naked_player_cache
else if(random_clothes)
cool_list = SSdummy.randomclothed_player_cache
Expand Down
65 changes: 62 additions & 3 deletions code/modules/admin/create_mob.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,26 @@

user << browse(create_panel_helper(create_mob_html), "window=create_mob;size=425x475")

/proc/randomize_human(mob/living/carbon/human/H, species)
/mob/living/carbon/human/proc/randomize(species, undies, genitals)
return randomize_human(src, species, undies, genitals)

/proc/randomize_human(mob/living/carbon/human/H, species, undies = TRUE, genitals)
if(!ishuman(H))
return
H.gender = pick(MALE, FEMALE)
H.real_name = random_unique_name(H.gender)
H.name = H.real_name
H.underwear = random_underwear(H.gender)
if(undies)
H.underwear = random_underwear(H.gender)
H.undershirt = random_undershirt(H.gender)
H.socks = random_socks(H.gender)
else
H.underwear = "Nude"
H.undershirt = "Nude"
H.socks = "Nude"
H.undie_color = random_short_color()
H.undershirt = random_undershirt(H.gender)
H.shirt_color = random_short_color()
H.socks_color = random_short_color()
H.dna.skin_tone_override = null
H.skin_tone = random_skin_tone()
H.hair_style = random_hair_style(H.gender)
Expand Down Expand Up @@ -95,8 +107,55 @@
// H.dna.features["deco_wings"] = pick(GLOB.deco_wings_list)
// H.dna.features["insect_fluff"] = pick(GLOB.insect_fluffs_list)
// H.dna.features["legs"] = "Digitigrade"
if(genitals)
var/static/list/boob_cup_sizes
if(!boob_cup_sizes)
var/list/L = CONFIG_GET(keyed_list/breasts_cups_prefs)
boob_cup_sizes = L.Copy()
var/static/penis_inches_min
if(!penis_inches_min)
penis_inches_min = CONFIG_GET(number/penis_min_inches_prefs)
var/static/penis_inches_max
if(!penis_inches_max)
penis_inches_max = CONFIG_GET(number/penis_max_inches_prefs)
var/static/butt_size_min
if(!butt_size_min)
butt_size_min = CONFIG_GET(number/butt_min_size_prefs)
var/static/butt_size_max
if(!butt_size_max)
butt_size_max = CONFIG_GET(number/butt_max_size_prefs)
var/static/belly_size_min
if(!belly_size_min)
belly_size_min = CONFIG_GET(number/belly_min_size_prefs)
var/static/belly_size_max
if(!belly_size_max)
belly_size_max = CONFIG_GET(number/belly_max_size_prefs)
if(prob(50))
H.dna.features["has_butt"] = TRUE
H.dna.features["butt_color"] = H.dna.features["mcolor"]
H.dna.features["butt_size"] = GaussianRangePicker(butt_size_min, butt_size_max, 4, 3)
if(prob(80))
H.dna.features["has_belly"] = TRUE
H.dna.features["belly_color"] = H.dna.features["mcolor"]
H.dna.features["belly_size"] = GaussianRangePicker(belly_size_min, belly_size_max, 4, 3)
H.dna.features["belly_shape"] = pick(GLOB.belly_shapes_list)
if(H.gender == FEMALE || H.gender == NEUTER || H.gender == PLURAL || prob(10))
H.dna.features["has_vag"] = TRUE // they only get the normal vag cus the rest are scary D:
H.dna.features["vag_color"] = H.dna.features["mcolor"]

H.dna.features["has_womb"] = TRUE

H.dna.features["has_breasts"] = TRUE
H.dna.features["breasts_color"] = H.dna.features["mcolor"]
H.dna.features["breasts_size"] = GaussianListPicker(boob_cup_sizes, 5, 2) // The wasteland has a buxomness epidemic
if(H.gender == MALE || H.gender == NEUTER || H.gender == PLURAL || prob(10))
H.dna.features["has_balls"] = TRUE
H.dna.features["balls_color"] = H.dna.features["mcolor"]

H.dna.features["has_cock"] = TRUE
H.dna.features["cock_size"] = GaussianRangePicker(penis_inches_min, penis_inches_max, 7, 3) // fuck it, everyone's got a HUUUUUGE COCK =3
H.dna.features["cock_shape"] = pick(GLOB.cock_shapes_list)
H.give_genitals(TRUE)
SEND_SIGNAL(H, COMSIG_HUMAN_ON_RANDOMIZE)

H.update_body(TRUE)
Expand Down
6 changes: 4 additions & 2 deletions code/modules/awaymissions/corpse.dm
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
var/important_info = ""
var/faction = null
var/permanent = FALSE //If true, the spawner will not disappear upon running out of uses.
var/random = FALSE //Don't set a name or gender, just go random
var/random = TRUE //Don't set a name or gender, just go random
var/antagonist_type
var/objectives = null
var/uses = 1 //how many times can we spawn from it. set to -1 for infinite.
Expand Down Expand Up @@ -96,6 +96,8 @@
if(!mob_gender)
mob_gender = pick(MALE, FEMALE)
M.gender = mob_gender
else
randomize_human(M, null, prob(50), TRUE)
if(faction)
M.faction = list(faction)
if(disease)
Expand Down Expand Up @@ -336,7 +338,7 @@
name = "Cook"
outfit = /datum/outfit/job/wasteland/f13wastelander
random
/obj/effect/mob_spawn/human/doctor
name = "Doctor"
outfit = /datum/outfit/job/doctor
Expand Down
7 changes: 6 additions & 1 deletion code/modules/mob/living/carbon/carbon.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1208,7 +1208,7 @@
stomach_contents.Add(C)
log_combat(src, C, "devoured")

/mob/living/carbon/proc/create_bodyparts()
/mob/living/carbon/proc/create_bodyparts(actually_dont)
var/l_arm_index_next = -1
var/r_arm_index_next = 0
for(var/X in bodyparts)
Expand All @@ -1224,6 +1224,11 @@
r_arm_index_next += 2
O.held_index = r_arm_index_next //2, 4, 6, 8...
hand_bodyparts += O
if(actually_dont)
for(var/obj/item/bodypart/O in bodyparts)
if(O.body_zone == BODY_ZONE_CHEST)
continue
qdel(O)

/mob/living/carbon/do_after_coefficent()
. = ..()
Expand Down
Loading

0 comments on commit 55a7922

Please sign in to comment.