diff --git a/code/datums/browser.dm b/code/datums/browser.dm
index ea6695280e3..8099248c4c6 100644
--- a/code/datums/browser.dm
+++ b/code/datums/browser.dm
@@ -463,4 +463,3 @@
// so just reset the user mob's machine var
if(src && src.mob)
src.mob.unset_machine()
- return
diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm
index 988c8546f1e..f0297cfc261 100644
--- a/code/modules/client/client_defines.dm
+++ b/code/modules/client/client_defines.dm
@@ -73,3 +73,5 @@
var/list/credits //lazy list of all credit object bound to this client
var/datum/player_details/player_details //these persist between logins/logouts during the same round.
+
+ var/list/char_render_holders //Should only be a key-value list of north/south/east/west = obj/screen.
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index 254db81dc26..61c3e082e9e 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -425,6 +425,7 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
GLOB.ahelp_tickets.ClientLogout(src)
GLOB.directory -= ckey
GLOB.clients -= src
+ QDEL_LIST_ASSOC_VAL(char_render_holders)
if(movingmob != null)
movingmob.client_mobs_in_contents -= mob
UNSETEMPTY(movingmob.client_mobs_in_contents)
@@ -839,3 +840,23 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
/client/proc/AnnouncePR(announcement)
if(prefs && prefs.chat_toggles & CHAT_PULLR)
to_chat(src, announcement)
+
+/client/proc/show_character_previews(mutable_appearance/MA)
+ var/pos = 0
+ for(var/D in GLOB.cardinals)
+ pos++
+ var/obj/screen/O = LAZYACCESS(char_render_holders, "[D]")
+ if(!O)
+ O = new
+ LAZYSET(char_render_holders, "[D]", O)
+ screen |= O
+ O.appearance = MA
+ O.dir = D
+ O.screen_loc = "character_preview_map:0,[pos]"
+
+/client/proc/clear_character_previews()
+ for(var/index in char_render_holders)
+ var/obj/screen/S = char_render_holders[index]
+ screen -= S
+ qdel(S)
+ char_render_holders = null
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 7588343de32..fc8b38cb60b 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -25,7 +25,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
//If it's 0, that's good, if it's anything but 0, the owner of this prefs file's antag choices were,
//autocorrected this round, not that you'd need to check that.
-
var/UI_style = null
var/buttons_locked = FALSE
var/hotkeys = FALSE
@@ -71,9 +70,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/preferred_ai_core_display = "Blue"
var/prefered_security_department = SEC_DEPT_RANDOM
- //Mob preview
- var/icon/preview_icon = null
-
//Quirk list
var/list/positive_quirks = list()
var/list/negative_quirks = list()
@@ -151,7 +147,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(!user || !user.client)
return
update_preview_icon()
- user << browse_rsc(preview_icon, "previewicon.png")
var/list/dat = list("
")
dat += "Character Settings"
@@ -221,11 +216,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "Preferred AI Core Display: [preferred_ai_core_display]
"
dat += "Preferred Security Department: [prefered_security_department]
"
- dat += ""
-
- dat += ""
-
- dat += " | "
+ dat += ""
dat += "Body
"
dat += "Random Body "
@@ -616,9 +607,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "Reset Setup"
dat += ""
- var/datum/browser/popup = new(user, "preferences", "Character Setup
", 640, 770)
+ winshow(user, "preferences_window", TRUE)
+ var/datum/browser/popup = new(user, "preferences_browser", "Character Setup
", 640, 770)
popup.set_content(dat.Join())
popup.open(FALSE)
+ onclose(user, "preferences_window", src)
#undef APPEARANCE_CATEGORY_COLUMN
#undef MAX_MUTANT_ROWS
@@ -744,12 +737,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
HTML += "
[message]"
HTML += "Reset Preferences"
- user << browse(null, "window=preferences")
var/datum/browser/popup = new(user, "mob_occupation", "Occupation Preferences
", width, height)
popup.set_window_options("can_close=0")
popup.set_content(HTML)
popup.open(FALSE)
- return
/datum/preferences/proc/SetJobPreferenceLevel(datum/job/job, level)
if (!job)
@@ -938,12 +929,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
[quirk_name] - [initial(T.desc)]
"
dat += "
Reset Quirks"
- user << browse(null, "window=preferences")
var/datum/browser/popup = new(user, "mob_occupation", "Quirk Preferences
", 900, 600) //no reason not to reuse the occupation window, as it's cleaner that way
popup.set_window_options("can_close=0")
popup.set_content(dat.Join())
popup.open(FALSE)
- return
/datum/preferences/proc/GetQuirkBalance()
var/bal = 0
@@ -952,6 +941,13 @@ GLOBAL_LIST_EMPTY(preferences_datums)
bal -= initial(T.value)
return bal
+/datum/preferences/Topic(href, href_list, hsrc) //yeah, gotta do this I guess..
+ . = ..()
+ if(href_list["close"])
+ var/client/C = usr.client
+ if(C)
+ C.clear_character_previews()
+
/datum/preferences/proc/process_link(mob/user, list/href_list)
if(href_list["bancheck"])
var/list/ban_details = is_banned_from_with_details(user.ckey, user.client.address, user.client.computer_id, href_list["bancheck"])
diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm
index 6588c08ebbc..b74dd1b28be 100644
--- a/code/modules/mob/dead/new_player/preferences_setup.dm
+++ b/code/modules/mob/dead/new_player/preferences_setup.dm
@@ -25,12 +25,10 @@
if(job_engsec_high)
switch(job_engsec_high)
if(AI_JF)
- preview_icon = icon('icons/mob/ai.dmi', resolve_ai_icon(preferred_ai_core_display), SOUTH)
- preview_icon.Scale(64, 64)
+ parent.show_character_previews(image('icons/mob/ai.dmi', icon_state = resolve_ai_icon(preferred_ai_core_display), dir = SOUTH))
return
if(CYBORG)
- preview_icon = icon('icons/mob/robots.dmi', "robot", SOUTH)
- preview_icon.Scale(64, 64)
+ parent.show_character_previews(image('icons/mob/robots.dmi', icon_state = "robot", dir = SOUTH))
return
// Set up the dummy for its photoshoot
@@ -61,26 +59,5 @@
mannequin.job = previewJob.title
previewJob.equip(mannequin, TRUE)
COMPILE_OVERLAYS(mannequin)
- 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
+ parent.show_character_previews(new /mutable_appearance(mannequin))
unset_busy_human_dummy(DUMMY_HUMAN_SLOT_PREFERENCES)
diff --git a/interface/skin.dmf b/interface/skin.dmf
index 99850c34bad..af55fc8f0da 100644
--- a/interface/skin.dmf
+++ b/interface/skin.dmf
@@ -1,5 +1,6 @@
macro "default"
+
menu "menu"
elem
name = "&File"
@@ -250,6 +251,34 @@ window "outputwindow"
is-default = true
saved-params = ""
+window "preferences_window"
+ elem "preferences_window"
+ type = MAIN
+ pos = 372,0
+ size = 1120x1000
+ anchor1 = none
+ anchor2 = none
+ background-color = none
+ is-visible = false
+ saved-params = "pos;size;is-minimized;is-maximized"
+ statusbar = false
+ elem "preferences_browser"
+ type = BROWSER
+ pos = -8,-8
+ size = 896x1008
+ anchor1 = 0,0
+ anchor2 = 90,100
+ background-color = none
+ saved-params = ""
+ elem "character_preview_map"
+ type = MAP
+ pos = 887,0
+ size = 313x1000
+ anchor1 = 90,0
+ anchor2 = 100,100
+ right-click = true
+ saved-params = "zoom;letterbox;zoom-mode"
+
window "statwindow"
elem "statwindow"
type = MAIN