diff --git a/code/datums/view.dm b/code/datums/view.dm index 860ccb8bf1f..dffbc90a4f2 100644 --- a/code/datums/view.dm +++ b/code/datums/view.dm @@ -1,10 +1,23 @@ //This is intended to be a full wrapper. DO NOT directly modify its values ///Container for client viewsize /datum/view_data + /// Width offset to apply to the default view string if we're not supressed for some reason var/width = 0 + /// Height offset to apply to the default view string, see above var/height = 0 + /// This client's current "default" view, in the format "WidthxHeight" + /// We add/remove from this when we want to change their window size var/default = "" + /// This client's current zoom level, if it's not being supressed + /// If it's 0, we autoscale to the size of the window. Otherwise it's treated as the ratio between + /// the pixels on the map and output pixels. Only looks proper nice in increments of whole numbers (iirc) + /// Stored here so other parts of the code have a non blocking way of getting a user's functional zoom + var/zoom = 0 + /// If the view is currently being supressed by some other "monitor" + /// For when you want to own the client's eye without fucking with their viewport + /// Doesn't make sense for a binocoler to effect your view in a camera console var/is_suppressed = FALSE + /// The client that owns this view packet var/client/chief = null /datum/view_data/New(client/owner, view_string) @@ -12,6 +25,10 @@ chief = owner apply() +/datum/view_data/Destroy() + chief = null + return ..() + /datum/view_data/proc/setDefault(string) default = string apply() @@ -24,12 +41,15 @@ /datum/view_data/proc/assertFormat()//T-Pose winset(chief, "mapwindow.map", "zoom=0") + zoom = 0 /datum/view_data/proc/resetFormat()//Cuck - winset(chief, "mapwindow.map", "zoom=[chief.prefs.read_preference(/datum/preference/numeric/pixel_size)]") + zoom = chief?.prefs.read_preference(/datum/preference/numeric/pixel_size) + winset(chief, "mapwindow.map", "zoom=[zoom]") + chief?.attempt_auto_fit_viewport() // If you change zoom mode, fit the viewport /datum/view_data/proc/setZoomMode() - winset(chief, "mapwindow.map", "zoom-mode=[chief.prefs.read_preference(/datum/preference/choiced/scaling_method)]") + winset(chief, "mapwindow.map", "zoom-mode=[chief?.prefs.read_preference(/datum/preference/choiced/scaling_method)]") /datum/view_data/proc/isZooming() return (width || height) @@ -78,7 +98,7 @@ apply() /datum/view_data/proc/apply() - chief.change_view(getView()) + chief?.change_view(getView()) safeApplyFormat() /datum/view_data/proc/supress() diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index de58ddfb8c9..fe324b6d665 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -251,3 +251,6 @@ /// Whether or not this client has the combo HUD enabled var/combo_hud_enabled = FALSE + + /// If this client has been fully initialized or not + var/fully_created = FALSE diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 11d669cef6b..d3628060cdc 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -488,6 +488,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( view_size.setZoomMode() Master.UpdateTickRate() SEND_GLOBAL_SIGNAL(COMSIG_GLOB_CLIENT_CONNECT, src) + fully_created = TRUE ////////////// //DISCONNECT// @@ -1039,8 +1040,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if (isliving(mob)) var/mob/living/M = mob M.update_damage_hud() - if (prefs.read_preference(/datum/preference/toggle/auto_fit_viewport)) - addtimer(CALLBACK(src,.verb/fit_viewport,10)) //Delayed to avoid wingets from Login calls. + attempt_auto_fit_viewport() /client/proc/generate_clickcatcher() if(!void) diff --git a/code/modules/client/verbs/ooc.dm b/code/modules/client/verbs/ooc.dm index d8eaa5c4c78..a8932c107b3 100644 --- a/code/modules/client/verbs/ooc.dm +++ b/code/modules/client/verbs/ooc.dm @@ -359,13 +359,23 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8") var/list/map_size = splittext(sizes["mapwindow.size"], "x") - // Looks like we expect mapwindow.size to be "ixj" where i and j are numbers. - // If we don't get our expected 2 outputs, let's give some useful error info. - if(length(map_size) != 2) - CRASH("map_size of incorrect length --- map_size var: [map_size] --- map_size length: [length(map_size)]") + // Gets the type of zoom we're currently using from our view datum + // If it's 0 we do our pixel calculations based off the size of the mapwindow + // If it's not, we already know how big we want our window to be, since zoom is the exact pixel ratio of the map + var/zoom_value = src.view_size?.zoom || 0 + + var/desired_width = 0 + if(zoom_value) + desired_width = round(view_size[1] * zoom_value * world.icon_size) + else + + // Looks like we expect mapwindow.size to be "ixj" where i and j are numbers. + // If we don't get our expected 2 outputs, let's give some useful error info. + if(length(map_size) != 2) + CRASH("map_size of incorrect length --- map_size var: [map_size] --- map_size length: [length(map_size)]") + var/height = text2num(map_size[2]) + desired_width = round(height * aspect_ratio) - var/height = text2num(map_size[2]) - var/desired_width = round(height * aspect_ratio) if (text2num(map_size[1]) == desired_width) // Nothing to do return @@ -401,6 +411,14 @@ GLOBAL_VAR_INIT(normal_ooc_colour, "#002eb8") pct += delta winset(src, "mainwindow.split", "splitter=[pct]") +/// Attempt to automatically fit the viewport, assuming the user wants it +/client/proc/attempt_auto_fit_viewport() + if (!prefs.read_preference(/datum/preference/toggle/auto_fit_viewport)) + return + if(fully_created) + INVOKE_ASYNC(src, .verb/fit_viewport) + else //Delayed to avoid wingets from Login calls. + addtimer(CALLBACK(src, .verb/fit_viewport, 1 SECONDS)) /client/verb/policy() set name = "Show Policy"