diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm
index 99079fd81bb..a2f487086ae 100644
--- a/code/__DEFINES/misc.dm
+++ b/code/__DEFINES/misc.dm
@@ -332,4 +332,6 @@
#define STATION_GOAL_BUDGET 1
#define FIRST_DIAG_STEP 1
-#define SECOND_DIAG_STEP 2
\ No newline at end of file
+#define SECOND_DIAG_STEP 2
+
+#define ARBITRARY_VIEWRANGE_NOHUD 2
\ No newline at end of file
diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm
index 2e1d87f605e..f4b43516cd0 100644
--- a/code/_onclick/hud/hud.dm
+++ b/code/_onclick/hud/hud.dm
@@ -100,6 +100,15 @@
if(display_hud_version > HUD_VERSIONS) //If the requested version number is greater than the available versions, reset back to the first version
display_hud_version = 1
+ if(mymob.client.view < world.view)
+ if(mymob.client.view < ARBITRARY_VIEWRANGE_NOHUD)
+ to_chat(mymob, "HUD is unavailable with this view range.")
+ display_hud_version = HUD_STYLE_NOHUD
+ else
+ if(display_hud_version == HUD_STYLE_STANDARD)
+ to_chat(mymob, "Standard HUD mode is unavailable with a smaller-than-normal view range.")
+ display_hud_version = HUD_STYLE_REDUCED
+
switch(display_hud_version)
if(HUD_STYLE_STANDARD) //Default HUD
hud_shown = 1 //Governs behavior of other procs
diff --git a/code/game/mecha/combat/marauder.dm b/code/game/mecha/combat/marauder.dm
index 1a901f4a71e..a08f4bea77a 100644
--- a/code/game/mecha/combat/marauder.dm
+++ b/code/game/mecha/combat/marauder.dm
@@ -157,10 +157,10 @@
log_message("Toggled zoom mode.")
occupant_message("Zoom mode [zoom?"en":"dis"]abled.")
if(zoom)
- occupant.client.view = 12
+ occupant.client.AddViewMod("mecha", 12)
to_chat(occupant, sound('sound/mecha/imag_enh.ogg',volume=50))
else
- occupant.client.view = initial(occupant.client.view)
+ occupant.client.RemoveViewMod("mecha")
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 9eab3e88cee..1daa7300b1d 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -1309,7 +1309,7 @@
dir = dir_in
if(L && L.client)
- L.client.view = world.view
+ L.client.RemoveViewMod("mecha")
/////////////////////////
////// Access stuff /////
diff --git a/code/game/objects/structures/artstuff.dm b/code/game/objects/structures/artstuff.dm
index 9636e1407b6..f3ab646c952 100644
--- a/code/game/objects/structures/artstuff.dm
+++ b/code/game/objects/structures/artstuff.dm
@@ -1,10 +1,3 @@
-/////////////////
-// NEW DEFINES //
-/////////////////
-
-/client
- var/viewingCanvas = 0 //If this is 1, as soon as client /TRIES/ to move the view resets.
-
///////////
// EASEL //
///////////
@@ -140,20 +133,4 @@ var/global/list/globalBlankCanvases[AMT_OF_CANVASES]
icon = blank
user.visible_message("[user] cleans the canvas.","You clean the canvas.")
-//Examine to enlarge
-/obj/item/weapon/canvas/examine(mob/user)
- ..(user)
- if(in_range(user, src) && get_turf(src) && user.client && ishuman(user)) //Let only humans be the robust zoominators. I'm too spooked other mobs trying to use it may get broken huds.
- if(src.loc == user || get_turf(src) == get_turf(user))
- to_chat(user, "[src] has to be on the ground to focus on it!")
- return
- to_chat(user, "You focus on \the [src].")
- user.client.screen = list() //This is because screen objects go way past the view bounds we set, therefore not allowing stretch to fit to zoom in properly.
- user.client.reset_stretch = winget(user.client, "mapwindow.map", "icon-size") //Remember previous icon-size
- user.client.view = 3 //Decrease view
- winset(user.client, "mapwindow.map", "icon-size=0") //Enable stretch-to-fit
- user.client.viewingCanvas = 1 //Reset everything we just changed as soon as client tries to move
- else
- to_chat(user, "It is too far away.")
-
#undef AMT_OF_CANVASES
\ No newline at end of file
diff --git a/code/modules/client/client defines.dm b/code/modules/client/client defines.dm
index d547a9a582f..ca3d17e9c50 100644
--- a/code/modules/client/client defines.dm
+++ b/code/modules/client/client defines.dm
@@ -76,8 +76,6 @@
"off" = "borgmacro")
)
- var/reset_stretch = 0 //Used by things that fiddle with client's stretch-to-fit.
-
var/topic_debugging = 0 //if set to true, allows client to see nanoUI errors -- yes i realize this is messy but it'll make live testing infinitely easier
control_freak = CONTROL_FREAK_ALL | CONTROL_FREAK_SKIN | CONTROL_FREAK_MACROS
@@ -93,7 +91,7 @@
// Donator stuff.
var/donator_level = DONATOR_LEVEL_NONE
-
+
// If set to true, this client can interact with atoms such as buttons and doors on top of regular machinery interaction
var/advanced_admin_interaction = FALSE
diff --git a/code/modules/client/view.dm b/code/modules/client/view.dm
new file mode 100644
index 00000000000..f4e74e203e8
--- /dev/null
+++ b/code/modules/client/view.dm
@@ -0,0 +1,90 @@
+/*
+ * ViewMods Client module
+ * This should be used by anything that wants to change a client's view range.
+ * Also includes
+ */
+
+/* Defines */
+#define CUSTOM_VIEWRANGES list(1, 2, 3, 4, 5, 6, "RESET")
+
+/* Viewmods */
+/client
+ var/list/ViewMods = list()
+ var/ViewModsActive = FALSE
+ var/ViewPreferedIconSize = 0
+
+/client/proc/AddViewMod(id, size)
+ var/datum/viewmod/V = new /datum/viewmod(id, size)
+ ViewMods[V.id] = V
+ UpdateView()
+
+/client/proc/CheckViewMod(id)
+ . = 0
+ if(ViewMods[id])
+ . = 1
+
+/client/proc/RemoveViewMod(id)
+ if(CheckViewMod(id))
+ qdel(ViewMods[id])
+ ViewMods.Remove(id)
+ UpdateView()
+
+/client/proc/UpdateView()
+ if(!ViewModsActive)
+ ViewPreferedIconSize = winget(src, "mapwindow.map", "icon-size")
+
+ var/highest_range = 0
+ for(var/mod_id in ViewMods)
+ var/datum/viewmod/V = ViewMods[mod_id]
+ highest_range = max(highest_range, V.size)
+
+ SetView(highest_range ? highest_range : world.view)
+ ViewModsActive = (highest_range > 0)
+
+/client/proc/SetView(view_range)
+ if(view_range == world.view)
+ winset(src, "mapwindow.map", "icon-size=[ViewPreferedIconSize]")
+ else
+ winset(src, "mapwindow.map", "icon-size=0")
+
+ view = view_range
+
+ if(mob && mob.hud_used)
+ // If view range is less than world.view, assume the HUD will not fit under normal mode and turn it to reduced
+ if(view_range < world.view)
+ // If it's really tiny, turn their hud off completely
+ if(view_range <= ARBITRARY_VIEWRANGE_NOHUD)
+ mob.hud_used.show_hud(HUD_STYLE_NOHUD)
+ else
+ mob.hud_used.show_hud(HUD_STYLE_REDUCED)
+ else
+ mob.hud_used.show_hud(HUD_STYLE_STANDARD)
+
+/* Viewmod datums */
+/datum/viewmod
+ var/id = ""
+ var/size = -1
+
+/datum/viewmod/New(new_id, new_size = world.view)
+ . = ..()
+ id = new_id
+ size = new_size
+
+/* Client verbs */
+/proc/viewNum_to_text(view)
+ return "[(view * 2) + 1]x[(view * 2) + 1]"
+
+/client/verb/set_view_range(view_range as null|anything in CUSTOM_VIEWRANGES)
+ set name = "Set View Range"
+ set category = "Preferences"
+
+ if(!view_range)
+ return
+
+ RemoveViewMod("custom")
+ if(view_range == "RESET")
+ to_chat(src, "View range reset.")
+ return
+
+ to_chat(src, "View range set to [viewNum_to_text(view_range)]")
+ AddViewMod("custom", view_range)
\ No newline at end of file
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 03ba9618bd4..20e08001754 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -149,14 +149,6 @@
/client/Move(n, direct)
- if(viewingCanvas)
- view = world.view //Reset the view
- winset(src, "mapwindow.map", "icon-size=[src.reset_stretch]")
- viewingCanvas = 0
- mob.reset_perspective()
- if(mob.hud_used)
- mob.hud_used.show_hud(HUD_STYLE_STANDARD)
-
if(world.time < move_delay)
return
diff --git a/paradise.dme b/paradise.dme
index 3b4107b4f57..be3e5494802 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -1138,6 +1138,7 @@
#include "code\modules\client\client defines.dm"
#include "code\modules\client\client procs.dm"
#include "code\modules\client\message.dm"
+#include "code\modules\client\view.dm"
#include "code\modules\client\preference\preferences.dm"
#include "code\modules\client\preference\preferences_mysql.dm"
#include "code\modules\client\preference\preferences_spawnpoints.dm"