From 08083581c37ab1db06de2341641712394c164c76 Mon Sep 17 00:00:00 2001 From: CitadelStationBot Date: Sun, 17 Sep 2017 11:59:40 -0500 Subject: [PATCH] [MIRROR] (Hopefully) Lessens preferences and manifest injection lag (#2796) * (Hopefully) Lessens preferences and manifest injection lag * Update datacore.dm * Update preferences_setup.dm --- code/__DEFINES/misc.dm | 4 + code/__HELPERS/icons.dm | 8 +- code/controllers/subsystem/ticker.dm | 4 +- code/datums/datacore.dm | 574 +++++++++--------- .../mob/dead/new_player/preferences_setup.dm | 184 +++--- code/modules/mob/living/carbon/human/dummy.dm | 43 ++ code/modules/mob/living/carbon/human/human.dm | 9 - tgstation.dme | 1 + 8 files changed, 424 insertions(+), 403 deletions(-) create mode 100644 code/modules/mob/living/carbon/human/dummy.dm diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 11b0396cbd..c5d917ece4 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -456,3 +456,7 @@ GLOBAL_LIST_INIT(ghost_others_options, list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE #define SECURITY_SAFE 1 #define SECURITY_ULTRASAFE 2 #define SECURITY_TRUSTED 3 + +//Dummy mob reserve slots +#define DUMMY_HUMAN_SLOT_PREFERENCES "dummy_preference_preview" +#define DUMMY_HUMAN_SLOT_MANIFEST "dummy_manifest_generation" diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 9b16644b4c..91bf127ab8 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -926,10 +926,10 @@ GLOBAL_LIST_EMPTY(friendly_animal_types) return 0 //For creating consistent icons for human looking simple animals -/proc/get_flat_human_icon(icon_id, datum/job/J, datum/preferences/prefs) +/proc/get_flat_human_icon(icon_id, datum/job/J, datum/preferences/prefs, dummy_key) var/static/list/humanoid_icon_cache = list() if(!icon_id || !humanoid_icon_cache[icon_id]) - var/mob/living/carbon/human/dummy/body = new() + var/mob/living/carbon/human/dummy/body = generate_or_wait_for_human_dummy(dummy_key) if(prefs) prefs.copy_to(body) @@ -956,14 +956,12 @@ GLOBAL_LIST_EMPTY(friendly_animal_types) partial = getFlatIcon(body) out_icon.Insert(partial,dir=EAST) - qdel(body) - humanoid_icon_cache[icon_id] = out_icon + dummy_key? unset_busy_human_dummy(dummy_key) : qdel(body) return out_icon else return humanoid_icon_cache[icon_id] - //Hook, override to run code on- wait this is images //Images have dir without being an atom, so they get their own definition. //Lame. diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 9f2a03437e..2c41985678 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -243,10 +243,10 @@ SUBSYSTEM_DEF(ticker) PostSetup() - return 1 + return TRUE /datum/controller/subsystem/ticker/proc/PostSetup() - set waitfor = 0 + set waitfor = FALSE mode.post_setup() GLOB.start_state = new /datum/station_state() GLOB.start_state.count(1) diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 005c02c355..b20381ca85 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -1,287 +1,287 @@ - -/datum/datacore - var/medical[] = list() - var/medicalPrintCount = 0 - var/general[] = list() - var/security[] = list() - var/securityPrintCount = 0 - var/securityCrimeCounter = 0 - //This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character(). - var/locked[] = list() - -/datum/data - var/name = "data" - -/datum/data/record - name = "record" - var/list/fields = list() - -/datum/data/record/Destroy() - if(src in GLOB.data_core.medical) - GLOB.data_core.medical -= src - if(src in GLOB.data_core.security) - GLOB.data_core.security -= src - if(src in GLOB.data_core.general) - GLOB.data_core.general -= src - if(src in GLOB.data_core.locked) - GLOB.data_core.locked -= src - . = ..() - -/datum/data/crime - name = "crime" - var/crimeName = "" - var/crimeDetails = "" - var/author = "" - var/time = "" - var/dataId = 0 - -/datum/datacore/proc/createCrimeEntry(cname = "", cdetails = "", author = "", time = "") - var/datum/data/crime/c = new /datum/data/crime - c.crimeName = cname - c.crimeDetails = cdetails - c.author = author - c.time = time - c.dataId = ++securityCrimeCounter - return c - -/datum/datacore/proc/addMinorCrime(id = "", datum/data/crime/crime) - for(var/datum/data/record/R in security) - if(R.fields["id"] == id) - var/list/crimes = R.fields["mi_crim"] - crimes |= crime - return - -/datum/datacore/proc/removeMinorCrime(id, cDataId) - for(var/datum/data/record/R in security) - if(R.fields["id"] == id) - var/list/crimes = R.fields["mi_crim"] - for(var/datum/data/crime/crime in crimes) - if(crime.dataId == text2num(cDataId)) - crimes -= crime - return - -/datum/datacore/proc/removeMajorCrime(id, cDataId) - for(var/datum/data/record/R in security) - if(R.fields["id"] == id) - var/list/crimes = R.fields["ma_crim"] - for(var/datum/data/crime/crime in crimes) - if(crime.dataId == text2num(cDataId)) - crimes -= crime - return - -/datum/datacore/proc/addMajorCrime(id = "", datum/data/crime/crime) - for(var/datum/data/record/R in security) - if(R.fields["id"] == id) - var/list/crimes = R.fields["ma_crim"] - crimes |= crime - return - -/datum/datacore/proc/manifest() - for(var/mob/dead/new_player/N in GLOB.player_list) - if(ishuman(N.new_character)) - manifest_inject(N.new_character, N.client) - CHECK_TICK - -/datum/datacore/proc/manifest_modify(name, assignment) - var/datum/data/record/foundrecord = find_record("name", name, GLOB.data_core.general) - if(foundrecord) - foundrecord.fields["rank"] = assignment - -/datum/datacore/proc/get_manifest(monochrome, OOC) - var/list/heads = list() - var/list/sec = list() - var/list/eng = list() - var/list/med = list() - var/list/sci = list() - var/list/sup = list() - var/list/civ = list() - var/list/bot = list() - var/list/misc = list() - var/dat = {" - - - - "} - var/even = 0 - // sort mobs - for(var/datum/data/record/t in GLOB.data_core.general) - var/name = t.fields["name"] - var/rank = t.fields["rank"] - var/department = 0 - if(rank in GLOB.command_positions) - heads[name] = rank - department = 1 - if(rank in GLOB.security_positions) - sec[name] = rank - department = 1 - if(rank in GLOB.engineering_positions) - eng[name] = rank - department = 1 - if(rank in GLOB.medical_positions) - med[name] = rank - department = 1 - if(rank in GLOB.science_positions) - sci[name] = rank - department = 1 - if(rank in GLOB.supply_positions) - sup[name] = rank - department = 1 - if(rank in GLOB.civilian_positions) - civ[name] = rank - department = 1 - if(rank in GLOB.nonhuman_positions) - bot[name] = rank - department = 1 - if(!department && !(name in heads)) - misc[name] = rank - if(heads.len > 0) - dat += "" - for(var/name in heads) - dat += "" - even = !even - if(sec.len > 0) - dat += "" - for(var/name in sec) - dat += "" - even = !even - if(eng.len > 0) - dat += "" - for(var/name in eng) - dat += "" - even = !even - if(med.len > 0) - dat += "" - for(var/name in med) - dat += "" - even = !even - if(sci.len > 0) - dat += "" - for(var/name in sci) - dat += "" - even = !even - if(sup.len > 0) - dat += "" - for(var/name in sup) - dat += "" - even = !even - if(civ.len > 0) - dat += "" - for(var/name in civ) - dat += "" - even = !even - // in case somebody is insane and added them to the manifest, why not - if(bot.len > 0) - dat += "" - for(var/name in bot) - dat += "" - even = !even - // misc guys - if(misc.len > 0) - dat += "" - for(var/name in misc) - dat += "" - even = !even - - dat += "
NameRank
Heads
[name][heads[name]]
Security
[name][sec[name]]
Engineering
[name][eng[name]]
Medical
[name][med[name]]
Science
[name][sci[name]]
Supply
[name][sup[name]]
Civilian
[name][civ[name]]
Silicon
[name][bot[name]]
Miscellaneous
[name][misc[name]]
" - dat = replacetext(dat, "\n", "") - dat = replacetext(dat, "\t", "") - return dat - - -/datum/datacore/proc/manifest_inject(mob/living/carbon/human/H, client/C) - if(H.mind && (H.mind.assigned_role != H.mind.special_role)) - var/assignment - if(H.mind.assigned_role) - assignment = H.mind.assigned_role - else if(H.job) - assignment = H.job - else - assignment = "Unassigned" - - var/static/record_id_num = 1001 - var/id = num2hex(record_id_num++,6) - if(!C) - C = H.client - var/image = get_id_photo(H, C) - var/obj/item/photo/photo_front = new() - var/obj/item/photo/photo_side = new() - photo_front.photocreate(null, icon(image, dir = SOUTH)) - photo_side.photocreate(null, icon(image, dir = WEST)) - - //These records should ~really~ be merged or something - //General Record - var/datum/data/record/G = new() - G.fields["id"] = id - G.fields["name"] = H.real_name - G.fields["rank"] = assignment - G.fields["age"] = H.age - if(config.mutant_races) - G.fields["species"] = H.dna.species.name - G.fields["fingerprint"] = md5(H.dna.uni_identity) - G.fields["p_stat"] = "Active" - G.fields["m_stat"] = "Stable" - G.fields["sex"] = H.gender - G.fields["photo_front"] = photo_front - G.fields["photo_side"] = photo_side - general += G - - //Medical Record - var/datum/data/record/M = new() - M.fields["id"] = id - M.fields["name"] = H.real_name - M.fields["blood_type"] = H.dna.blood_type - M.fields["b_dna"] = H.dna.unique_enzymes - M.fields["mi_dis"] = "None" - M.fields["mi_dis_d"] = "No minor disabilities have been declared." - M.fields["ma_dis"] = "None" - M.fields["ma_dis_d"] = "No major disabilities have been diagnosed." - M.fields["alg"] = "None" - M.fields["alg_d"] = "No allergies have been detected in this patient." - M.fields["cdi"] = "None" - M.fields["cdi_d"] = "No diseases have been diagnosed at the moment." - M.fields["notes"] = "No notes." - medical += M - - //Security Record - var/datum/data/record/S = new() - S.fields["id"] = id - S.fields["name"] = H.real_name - S.fields["criminal"] = "None" - S.fields["mi_crim"] = list() - S.fields["ma_crim"] = list() - S.fields["notes"] = "No notes." - security += S - - //Locked Record - var/datum/data/record/L = new() - L.fields["id"] = md5("[H.real_name][H.mind.assigned_role]") //surely this should just be id, like the others? - L.fields["name"] = H.real_name - L.fields["rank"] = H.mind.assigned_role - L.fields["age"] = H.age - L.fields["sex"] = H.gender - L.fields["blood_type"] = H.dna.blood_type - L.fields["b_dna"] = H.dna.unique_enzymes - L.fields["enzymes"] = H.dna.struc_enzymes - L.fields["identity"] = H.dna.uni_identity - L.fields["species"] = H.dna.species.type - L.fields["features"] = H.dna.features - L.fields["image"] = image - L.fields["reference"] = H - locked += L - return - -/datum/datacore/proc/get_id_photo(mob/living/carbon/human/H, client/C) - var/datum/job/J = SSjob.GetJob(H.mind.assigned_role) - var/datum/preferences/P - if(!C) - C = H.client - if(C) - P = C.prefs - return get_flat_human_icon(null, J, P) +/datum/datacore + var/medical[] = list() + var/medicalPrintCount = 0 + var/general[] = list() + var/security[] = list() + var/securityPrintCount = 0 + var/securityCrimeCounter = 0 + //This list tracks characters spawned in the world and cannot be modified in-game. Currently referenced by respawn_character(). + var/locked[] = list() + +/datum/data + var/name = "data" + +/datum/data/record + name = "record" + var/list/fields = list() + +/datum/data/record/Destroy() + if(src in GLOB.data_core.medical) + GLOB.data_core.medical -= src + if(src in GLOB.data_core.security) + GLOB.data_core.security -= src + if(src in GLOB.data_core.general) + GLOB.data_core.general -= src + if(src in GLOB.data_core.locked) + GLOB.data_core.locked -= src + . = ..() + +/datum/data/crime + name = "crime" + var/crimeName = "" + var/crimeDetails = "" + var/author = "" + var/time = "" + var/dataId = 0 + +/datum/datacore/proc/createCrimeEntry(cname = "", cdetails = "", author = "", time = "") + var/datum/data/crime/c = new /datum/data/crime + c.crimeName = cname + c.crimeDetails = cdetails + c.author = author + c.time = time + c.dataId = ++securityCrimeCounter + return c + +/datum/datacore/proc/addMinorCrime(id = "", datum/data/crime/crime) + for(var/datum/data/record/R in security) + if(R.fields["id"] == id) + var/list/crimes = R.fields["mi_crim"] + crimes |= crime + return + +/datum/datacore/proc/removeMinorCrime(id, cDataId) + for(var/datum/data/record/R in security) + if(R.fields["id"] == id) + var/list/crimes = R.fields["mi_crim"] + for(var/datum/data/crime/crime in crimes) + if(crime.dataId == text2num(cDataId)) + crimes -= crime + return + +/datum/datacore/proc/removeMajorCrime(id, cDataId) + for(var/datum/data/record/R in security) + if(R.fields["id"] == id) + var/list/crimes = R.fields["ma_crim"] + for(var/datum/data/crime/crime in crimes) + if(crime.dataId == text2num(cDataId)) + crimes -= crime + return + +/datum/datacore/proc/addMajorCrime(id = "", datum/data/crime/crime) + for(var/datum/data/record/R in security) + if(R.fields["id"] == id) + var/list/crimes = R.fields["ma_crim"] + crimes |= crime + return + +/datum/datacore/proc/manifest() + for(var/mob/dead/new_player/N in GLOB.player_list) + if(ishuman(N.new_character)) + manifest_inject(N.new_character, N.client) + CHECK_TICK + +/datum/datacore/proc/manifest_modify(name, assignment) + var/datum/data/record/foundrecord = find_record("name", name, GLOB.data_core.general) + if(foundrecord) + foundrecord.fields["rank"] = assignment + +/datum/datacore/proc/get_manifest(monochrome, OOC) + var/list/heads = list() + var/list/sec = list() + var/list/eng = list() + var/list/med = list() + var/list/sci = list() + var/list/sup = list() + var/list/civ = list() + var/list/bot = list() + var/list/misc = list() + var/dat = {" + + + + "} + var/even = 0 + // sort mobs + for(var/datum/data/record/t in GLOB.data_core.general) + var/name = t.fields["name"] + var/rank = t.fields["rank"] + var/department = 0 + if(rank in GLOB.command_positions) + heads[name] = rank + department = 1 + if(rank in GLOB.security_positions) + sec[name] = rank + department = 1 + if(rank in GLOB.engineering_positions) + eng[name] = rank + department = 1 + if(rank in GLOB.medical_positions) + med[name] = rank + department = 1 + if(rank in GLOB.science_positions) + sci[name] = rank + department = 1 + if(rank in GLOB.supply_positions) + sup[name] = rank + department = 1 + if(rank in GLOB.civilian_positions) + civ[name] = rank + department = 1 + if(rank in GLOB.nonhuman_positions) + bot[name] = rank + department = 1 + if(!department && !(name in heads)) + misc[name] = rank + if(heads.len > 0) + dat += "" + for(var/name in heads) + dat += "" + even = !even + if(sec.len > 0) + dat += "" + for(var/name in sec) + dat += "" + even = !even + if(eng.len > 0) + dat += "" + for(var/name in eng) + dat += "" + even = !even + if(med.len > 0) + dat += "" + for(var/name in med) + dat += "" + even = !even + if(sci.len > 0) + dat += "" + for(var/name in sci) + dat += "" + even = !even + if(sup.len > 0) + dat += "" + for(var/name in sup) + dat += "" + even = !even + if(civ.len > 0) + dat += "" + for(var/name in civ) + dat += "" + even = !even + // in case somebody is insane and added them to the manifest, why not + if(bot.len > 0) + dat += "" + for(var/name in bot) + dat += "" + even = !even + // misc guys + if(misc.len > 0) + dat += "" + for(var/name in misc) + dat += "" + even = !even + + dat += "
NameRank
Heads
[name][heads[name]]
Security
[name][sec[name]]
Engineering
[name][eng[name]]
Medical
[name][med[name]]
Science
[name][sci[name]]
Supply
[name][sup[name]]
Civilian
[name][civ[name]]
Silicon
[name][bot[name]]
Miscellaneous
[name][misc[name]]
" + dat = replacetext(dat, "\n", "") + dat = replacetext(dat, "\t", "") + return dat + + +/datum/datacore/proc/manifest_inject(mob/living/carbon/human/H, client/C) + set waitfor = FALSE + if(H.mind && (H.mind.assigned_role != H.mind.special_role)) + var/assignment + if(H.mind.assigned_role) + assignment = H.mind.assigned_role + else if(H.job) + assignment = H.job + else + assignment = "Unassigned" + + var/static/record_id_num = 1001 + var/id = num2hex(record_id_num++,6) + if(!C) + C = H.client + var/image = get_id_photo(H, C) + var/obj/item/photo/photo_front = new() + var/obj/item/photo/photo_side = new() + photo_front.photocreate(null, icon(image, dir = SOUTH)) + photo_side.photocreate(null, icon(image, dir = WEST)) + + //These records should ~really~ be merged or something + //General Record + var/datum/data/record/G = new() + G.fields["id"] = id + G.fields["name"] = H.real_name + G.fields["rank"] = assignment + G.fields["age"] = H.age + if(config.mutant_races) + G.fields["species"] = H.dna.species.name + G.fields["fingerprint"] = md5(H.dna.uni_identity) + G.fields["p_stat"] = "Active" + G.fields["m_stat"] = "Stable" + G.fields["sex"] = H.gender + G.fields["photo_front"] = photo_front + G.fields["photo_side"] = photo_side + general += G + + //Medical Record + var/datum/data/record/M = new() + M.fields["id"] = id + M.fields["name"] = H.real_name + M.fields["blood_type"] = H.dna.blood_type + M.fields["b_dna"] = H.dna.unique_enzymes + M.fields["mi_dis"] = "None" + M.fields["mi_dis_d"] = "No minor disabilities have been declared." + M.fields["ma_dis"] = "None" + M.fields["ma_dis_d"] = "No major disabilities have been diagnosed." + M.fields["alg"] = "None" + M.fields["alg_d"] = "No allergies have been detected in this patient." + M.fields["cdi"] = "None" + M.fields["cdi_d"] = "No diseases have been diagnosed at the moment." + M.fields["notes"] = "No notes." + medical += M + + //Security Record + var/datum/data/record/S = new() + S.fields["id"] = id + S.fields["name"] = H.real_name + S.fields["criminal"] = "None" + S.fields["mi_crim"] = list() + S.fields["ma_crim"] = list() + S.fields["notes"] = "No notes." + security += S + + //Locked Record + var/datum/data/record/L = new() + L.fields["id"] = md5("[H.real_name][H.mind.assigned_role]") //surely this should just be id, like the others? + L.fields["name"] = H.real_name + L.fields["rank"] = H.mind.assigned_role + L.fields["age"] = H.age + L.fields["sex"] = H.gender + L.fields["blood_type"] = H.dna.blood_type + L.fields["b_dna"] = H.dna.unique_enzymes + L.fields["enzymes"] = H.dna.struc_enzymes + L.fields["identity"] = H.dna.uni_identity + L.fields["species"] = H.dna.species.type + L.fields["features"] = H.dna.features + L.fields["image"] = image + L.fields["mindref"] = H.mind + locked += L + return + +/datum/datacore/proc/get_id_photo(mob/living/carbon/human/H, client/C) + var/datum/job/J = SSjob.GetJob(H.mind.assigned_role) + var/datum/preferences/P + if(!C) + C = H.client + if(C) + P = C.prefs + return get_flat_human_icon(null, J, P, DUMMY_HUMAN_SLOT_MANIFEST) diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm index 4810b666e7..33f04d33b9 100644 --- a/code/modules/mob/dead/new_player/preferences_setup.dm +++ b/code/modules/mob/dead/new_player/preferences_setup.dm @@ -1,100 +1,84 @@ - - //The mob should have a gender you want before running this proc. Will run fine without H -/datum/preferences/proc/random_character(gender_override) - if(gender_override) - gender = gender_override - else - gender = pick(MALE,FEMALE) - skin_tone = random_skin_tone() - hair_style = random_hair_style(gender) - facial_hair_style = random_facial_hair_style(gender) - hair_color = random_short_color() - facial_hair_color = hair_color - eye_color = random_eye_color() - if(!pref_species) - var/rando_race = pick(config.roundstart_races) - pref_species = new rando_race() - features = random_features() - age = rand(AGE_MIN,AGE_MAX) - -/datum/preferences/proc/update_preview_icon(nude = 0) - var/wide_icon = 0 - var/stamp_x = 0 - var/stamp_y = 1 - if(features["taur"] != "None") - wide_icon = 1 - // Silicons only need a very basic preview since there is no customization for them. - if(job_engsec_high) - switch(job_engsec_high) - if(AI_JF) - preview_icon = icon('icons/mob/AI.dmi', "AI", SOUTH) - preview_icon.Scale(64, 64) - return - if(CYBORG) - preview_icon = icon('icons/mob/robots.dmi', "robot", SOUTH) - preview_icon.Scale(64, 64) - return - - // Set up the dummy for its photoshoot - var/mob/living/carbon/human/dummy/mannequin = new() - copy_to(mannequin) - - // 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(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 - - if(previewJob && !nude) - mannequin.job = previewJob.title - previewJob.equip(mannequin, TRUE) - mannequin.update_body() - CHECK_TICK - preview_icon = icon('icons/effects/effects.dmi', "nothing") - preview_icon.Scale((112), (32)) - CHECK_TICK - mannequin.setDir(NORTH) - - var/icon/stamp = getFlatIcon(mannequin) - CHECK_TICK - if(wide_icon) - stamp_x = 16 - else - stamp_x = 32 - preview_icon.Blend(stamp, ICON_OVERLAY, stamp_x, stamp_y) - CHECK_TICK - mannequin.setDir(WEST) - stamp = getFlatIcon(mannequin) - CHECK_TICK - if(wide_icon) - stamp_x = 48 - else - stamp_x = 64 - preview_icon.Blend(stamp, ICON_OVERLAY, stamp_x, stamp_y) - CHECK_TICK - mannequin.setDir(SOUTH) - stamp = getFlatIcon(mannequin) - CHECK_TICK - if(wide_icon) - stamp_x = -15 - else - stamp_x = 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 - qdel(mannequin) \ No newline at end of file +//The mob should have a gender you want before running this proc. Will run fine without H +/datum/preferences/proc/random_character(gender_override) + if(gender_override) + 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) + hair_color = random_short_color() + facial_hair_color = hair_color + eye_color = random_eye_color() + if(!pref_species) + var/rando_race = pick(config.roundstart_races) + pref_species = new rando_race() + features = random_features() + age = rand(AGE_MIN,AGE_MAX) + +/datum/preferences/proc/update_preview_icon() + // Silicons only need a very basic preview since there is no customization for them. + if(job_engsec_high) + switch(job_engsec_high) + if(AI_JF) + preview_icon = icon('icons/mob/ai.dmi', "AI", SOUTH) + preview_icon.Scale(64, 64) + return + if(CYBORG) + preview_icon = icon('icons/mob/robots.dmi', "robot", SOUTH) + preview_icon.Scale(64, 64) + return + + // Set up the dummy for its photoshoot + var/mob/living/carbon/human/dummy/mannequin = generate_or_wait_for_human_dummy(DUMMY_HUMAN_SLOT_PREFERENCES) + copy_to(mannequin) + + // 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(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 + + 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) + CHECK_TICK + mannequin.setDir(NORTH) + + var/icon/stamp = getFlatIcon(mannequin) + CHECK_TICK + preview_icon.Blend(stamp, ICON_OVERLAY, 25, 17) + CHECK_TICK + mannequin.setDir(WEST) + stamp = getFlatIcon(mannequin) + CHECK_TICK + preview_icon.Blend(stamp, ICON_OVERLAY, 1, 9) + CHECK_TICK + mannequin.setDir(SOUTH) + stamp = getFlatIcon(mannequin) + CHECK_TICK + preview_icon.Blend(stamp, ICON_OVERLAY, 49, 1) + CHECK_TICK + preview_icon.Scale(preview_icon.Width() * 2, preview_icon.Height() * 2) // Scaling here to prevent blurring in the browser. + CHECK_TICK + unset_busy_human_dummy(DUMMY_HUMAN_SLOT_PREFERENCES) diff --git a/code/modules/mob/living/carbon/human/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm new file mode 100644 index 0000000000..0492a0b5e6 --- /dev/null +++ b/code/modules/mob/living/carbon/human/dummy.dm @@ -0,0 +1,43 @@ + +/mob/living/carbon/human/dummy + real_name = "Test Dummy" + status_flags = GODMODE|CANPUSH + var/in_use = FALSE + +INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) + +/mob/living/carbon/human/dummy/Destroy() + in_use = FALSE + return ..() + +/mob/living/carbon/human/dummy/Life() + return + +/mob/living/carbon/human/dummy/proc/wipe_state() + QDEL_LIST(contents) + cut_overlays(TRUE) + +//Inefficient pooling/caching way. +GLOBAL_LIST_EMPTY(human_dummy_list) + +/proc/generate_or_wait_for_human_dummy(slotkey) + if(!slotkey) + return new /mob/living/carbon/human/dummy + var/mob/living/carbon/human/dummy/D = GLOB.human_dummy_list[slotkey] + if(istype(D)) + UNTIL(!D.in_use) + else + pass() + if(QDELETED(D)) + D = new + GLOB.human_dummy_list[slotkey] = D + D.in_use = TRUE + return D + +/proc/unset_busy_human_dummy(slotnumber) + if(!slotnumber) + return + var/mob/living/carbon/human/dummy/D = GLOB.human_dummy_list[slotnumber] + if(istype(D)) + D.wipe_state() + D.in_use = FALSE diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 0fd685e77c..58b0c673a7 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -5,15 +5,6 @@ icon = 'icons/mob/human.dmi' icon_state = "caucasian_m" -/mob/living/carbon/human/dummy - real_name = "Test Dummy" - status_flags = GODMODE|CANPUSH - -INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) - -/mob/living/carbon/human/dummy/Life() - return - /mob/living/carbon/human/Initialize() verbs += /mob/living/proc/mob_sleep verbs += /mob/living/proc/lay_down diff --git a/tgstation.dme b/tgstation.dme index 1814739f42..c035d52d60 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -1641,6 +1641,7 @@ #include "code\modules\mob\living\carbon\alien\special\facehugger.dm" #include "code\modules\mob\living\carbon\human\damage_procs.dm" #include "code\modules\mob\living\carbon\human\death.dm" +#include "code\modules\mob\living\carbon\human\dummy.dm" #include "code\modules\mob\living\carbon\human\emote.dm" #include "code\modules\mob\living\carbon\human\examine.dm" #include "code\modules\mob\living\carbon\human\examine_vr.dm"