diff --git a/code/__defines/_planes+layers.dm b/code/__defines/_planes+layers.dm index 01d890b1522..c36e238329e 100644 --- a/code/__defines/_planes+layers.dm +++ b/code/__defines/_planes+layers.dm @@ -42,6 +42,8 @@ What is the naming convention for planes or layers? #define SPACE_PLANE -82 // Reserved for use in space/parallax #define PARALLAX_PLANE -80 // Reserved for use in space/parallax +#define SKYBOX_PLANE -79 // Skybox parallax +#define DUST_PLANE -78 // For dust overlay on space turfs. Should be above skybox for parallax effect. // OPENSPACE_PLANE reserves all planes between OPENSPACE_PLANE_START and OPENSPACE_PLANE_END inclusive #define OPENSPACE_PLANE -75 // /turf/simulated/open will use OPENSPACE_PLANE + z (Valid z's being 2 thru 17) @@ -50,7 +52,7 @@ What is the naming convention for planes or layers? #define OVER_OPENSPACE_PLANE -57 // Turf Planes -#define SPACE_PLANE -43 // Space turfs themselves +#define SPACE_PLANE -82 // Space turfs themselves #define PLATING_PLANE -44 // Plating #define DISPOSAL_LAYER 2.1 // Under objects, even when planeswapped #define PIPES_LAYER 2.2 // Under objects, even when planeswapped diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm index e12772842de..8ec18fc0a70 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -52,10 +52,11 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G // Subsystem init_order, from highest priority to lowest priority // Subsystems shutdown in the reverse of the order they initialize in // The numbers just define the ordering, they are meaningless otherwise. -#define INIT_ORDER_SQLITE 19 -#define INIT_ORDER_CHEMISTRY 18 -#define INIT_ORDER_MAPPING 17 -#define INIT_ORDER_DECALS 16 +#define INIT_ORDER_SQLITE 40 +#define INIT_ORDER_CHEMISTRY 35 +#define INIT_ORDER_SKYBOX 30 +#define INIT_ORDER_MAPPING 25 +#define INIT_ORDER_DECALS 20 #define INIT_ORDER_ATOMS 15 #define INIT_ORDER_MACHINES 10 #define INIT_ORDER_SHUTTLES 3 diff --git a/code/_macros.dm b/code/_macros.dm index 6893ebbb6f5..4b57623a7cd 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -2,6 +2,12 @@ #define get_turf(A) get_step(A,0) +#define get_x(A) (get_step(A, 0)?.x || 0) + +#define get_y(A) (get_step(A, 0)?.y || 0) + +#define get_z(A) (get_step(A, 0)?.z || 0) + #define RANDOM_BLOOD_TYPE pick(4;"O-", 36;"O+", 3;"A-", 28;"A+", 1;"B-", 20;"B+", 1;"AB-", 5;"AB+") // #define to_chat(target, message) target << message Not anymore! diff --git a/code/_onclick/hud/skybox.dm b/code/_onclick/hud/skybox.dm new file mode 100644 index 00000000000..11159720b1d --- /dev/null +++ b/code/_onclick/hud/skybox.dm @@ -0,0 +1,42 @@ +// Skybox screen object. +/obj/skybox + name = "skybox" + mouse_opacity = 0 + anchored = TRUE + simulated = FALSE + screen_loc = "CENTER:-352,CENTER:-352" // (736/2 - 32/2) + plane = SKYBOX_PLANE + blend_mode = BLEND_MULTIPLY // You actually need to do it this way or you see it in occlusion. + +/client + var/obj/skybox/skybox + +/client/proc/update_skybox(rebuild) + if(!skybox) + skybox = new() + screen += skybox + rebuild = 1 + + var/turf/T = get_turf(eye) + if(T) + if(rebuild) + skybox.overlays.Cut() + skybox.overlays += SSskybox.get_skybox(T.z) + screen |= skybox + skybox.screen_loc = "CENTER:[-352 + (world.maxx>>1) - T.x],CENTER:[-352 + (world.maxy>>1) - T.y]" + +/mob/Login() + . = ..() + client.update_skybox(TRUE) + +/mob/Move() + var/old_z = get_z(src) + . = ..() + if(. && client) + client.update_skybox(old_z != get_z(src)) + +/mob/forceMove() + var/old_z = get_z(src) + . = ..() + if(. && client) + client.update_skybox(old_z != get_z(src)) diff --git a/code/controllers/subsystems/skybox.dm b/code/controllers/subsystems/skybox.dm new file mode 100644 index 00000000000..b876c6a2c8d --- /dev/null +++ b/code/controllers/subsystems/skybox.dm @@ -0,0 +1,82 @@ + +//Exists to handle a few global variables that change enough to justify this. Technically a parallax, but it exhibits a skybox effect. +SUBSYSTEM_DEF(skybox) + name = "Space skybox" + init_order = INIT_ORDER_SKYBOX + flags = SS_NO_FIRE + var/list/skybox_cache = list() + +/datum/controller/subsystem/skybox/Initialize() + . = ..() + +/datum/controller/subsystem/skybox/Recover() + skybox_cache = SSskybox.skybox_cache + +/datum/controller/subsystem/skybox/proc/get_skybox(z) + if(!skybox_cache["[z]"]) + skybox_cache["[z]"] = generate_skybox(z) + if(global.using_map.use_overmap) + var/obj/effect/overmap/visitable/O = map_sectors["[z]"] + if(istype(O)) + for(var/zlevel in O.map_z) + skybox_cache["[zlevel]"] = skybox_cache["[z]"] + return skybox_cache["[z]"] + +/datum/controller/subsystem/skybox/proc/generate_skybox(z) + var/datum/skybox_settings/settings = global.using_map.get_skybox_datum(z) + + var/image/res = image(settings.icon) + res.appearance_flags = KEEP_TOGETHER + + var/image/base = image(settings.icon, settings.icon_state) + //base.color = background_color + + if(settings.use_stars) + var/image/stars = image(settings.icon, settings.star_state) + stars.appearance_flags = RESET_COLOR + base.overlays += stars + + res.overlays += base + + if(global.using_map.use_overmap && settings.use_overmap_details) + var/obj/effect/overmap/visitable/O = map_sectors["[z]"] + if(istype(O)) + var/image/overmap = image(settings.icon_state) + overmap.overlays += O.generate_skybox() + for(var/obj/effect/overmap/visitable/other in O.loc) + if(other != O) + overmap.overlays += other.get_skybox_representation() + overmap.appearance_flags = RESET_COLOR + res.overlays += overmap + + // TODO - Allow events to apply custom overlays to skybox! (Awesome!) + //for(var/datum/event/E in SSevent.active_events) + // if(E.has_skybox_image && E.isRunning && (z in E.affecting_z)) + // res.overlays += E.get_skybox_image() + + return res + +/datum/controller/subsystem/skybox/proc/rebuild_skyboxes(var/list/zlevels) + for(var/z in zlevels) + skybox_cache["[z]"] = generate_skybox(z) + + for(var/client/C) + C.update_skybox(1) + +// Settings datum that maps can override to play with their skyboxes +/datum/skybox_settings + var/icon = 'icons/skybox/skybox.dmi' //Path to our background. Lets us use anything we damn well please. Skyboxes need to be 736x736 + var/icon_state = "dyable" + var/color + var/random_color = FALSE + + var/use_stars = TRUE + var/star_icon = 'icons/skybox/skybox.dmi' + var/star_state = "stars" + + var/use_overmap_details = TRUE //Do we try to draw overmap visitables in our sector on the map? + +/datum/skybox_settings/New() + ..() + if(random_color) + color = rgb(rand(0,255), rand(0,255), rand(0,255)) diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index a3bc0494caa..edee66fc97c 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -3,18 +3,32 @@ name = "\proper space" icon_state = "0" dynamic_lighting = 0 + plane = SPACE_PLANE temperature = T20C thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT can_build_into_floor = TRUE var/keep_sprite = FALSE // heat_capacity = 700000 No. + var/static/list/dust_cache + +/turf/space/proc/build_dust_cache() + LAZYINITLIST(dust_cache) + for (var/i in 0 to 25) + var/image/im = image('icons/turf/space_dust.dmi', "[i]") + im.plane = DUST_PLANE + im.alpha = 128 //80 + im.blend_mode = BLEND_ADD + dust_cache["[i]"] = im /turf/space/Initialize() . = ..() if(!keep_sprite) - icon_state = "[((x + y) ^ ~(x * y) + z) % 25]" + icon_state = "white" update_starlight() + if (!dust_cache) + build_dust_cache() + add_overlay(dust_cache["[((x + y) ^ ~(x * y) + z) % 25]"]) /turf/space/is_space() return 1 diff --git a/icons/skybox/skybox.dmi b/icons/skybox/skybox.dmi new file mode 100644 index 00000000000..2a16a2f81d5 Binary files /dev/null and b/icons/skybox/skybox.dmi differ diff --git a/icons/turf/space.dmi b/icons/turf/space.dmi index 3e3afc355b9..5c5d6fd7473 100644 Binary files a/icons/turf/space.dmi and b/icons/turf/space.dmi differ diff --git a/icons/turf/space_dust.dmi b/icons/turf/space_dust.dmi new file mode 100644 index 00000000000..8328b3dba9b Binary files /dev/null and b/icons/turf/space_dust.dmi differ diff --git a/maps/~map_system/maps.dm b/maps/~map_system/maps.dm index 48cf80b860d..a51bfa9748b 100644 --- a/maps/~map_system/maps.dm +++ b/maps/~map_system/maps.dm @@ -104,6 +104,8 @@ var/list/all_maps = list() var/overmap_z = 0 // If 0 will generate overmap zlevel on init. Otherwise will populate the zlevel provided. var/overmap_event_areas = 0 // How many event "clouds" will be generated + var/default_skybox = /datum/skybox_settings // What skybox do we use if a zlevel doesn't have a custom one? + var/lobby_icon = 'icons/misc/title.dmi' // The icon which contains the lobby image(s) var/list/lobby_screens = list("mockingjay00") // The list of lobby screen to pick() from. If left unset the first icon state is always selected. @@ -179,6 +181,33 @@ var/list/all_maps = list() var/datum/map_z_level/Z = zlevels["[index]"] return Z.name +// Access check is of the type requires one. These have been carefully selected to avoid allowing the janitor to see channels he shouldn't +// This list needs to be purged but people insist on adding more cruft to the radio. +/datum/map/proc/default_internal_channels() + return list( + num2text(PUB_FREQ) = list(), + num2text(AI_FREQ) = list(access_synth), + num2text(ENT_FREQ) = list(), + num2text(ERT_FREQ) = list(access_cent_specops), + num2text(COMM_FREQ) = list(access_heads), + num2text(ENG_FREQ) = list(access_engine_equip, access_atmospherics), + num2text(MED_FREQ) = list(access_medical_equip), + num2text(MED_I_FREQ) = list(access_medical_equip), + num2text(SEC_FREQ) = list(access_security), + num2text(SEC_I_FREQ) = list(access_security), + num2text(SCI_FREQ) = list(access_tox,access_robotics,access_xenobiology), + num2text(SUP_FREQ) = list(access_cargo), + num2text(SRV_FREQ) = list(access_janitor, access_hydroponics), + ) + +/datum/map/proc/get_skybox_datum(z) + if(map_levels["[z]"]) + var/datum/map_z_level/picked = map_levels["[z]"] + if(picked.custom_skybox) + return new picked.custom_skybox + + return new default_skybox + // Another way to setup the map datum that can be convenient. Just declare all your zlevels as subtypes of a common // subtype of /datum/map_z_level and set zlevel_datum_type on /datum/map to have the lists auto-initialized. @@ -196,6 +225,9 @@ var/list/all_maps = list() var/holomap_legend_x = 96 // x position of the holomap legend for this z var/holomap_legend_y = 96 // y position of the holomap legend for this z +// Skybox + var/custom_skybox = null // Can override skybox type here for this z + // Default constructor applies itself to the parent map datum /datum/map_z_level/New(var/datum/map/map) if(!z) return @@ -235,22 +267,3 @@ var/list/all_maps = list() if (using_map.zlevels["[z]"] == src) using_map.zlevels -= "[z]" return ..() - -// Access check is of the type requires one. These have been carefully selected to avoid allowing the janitor to see channels he shouldn't -// This list needs to be purged but people insist on adding more cruft to the radio. -/datum/map/proc/default_internal_channels() - return list( - num2text(PUB_FREQ) = list(), - num2text(AI_FREQ) = list(access_synth), - num2text(ENT_FREQ) = list(), - num2text(ERT_FREQ) = list(access_cent_specops), - num2text(COMM_FREQ) = list(access_heads), - num2text(ENG_FREQ) = list(access_engine_equip, access_atmospherics), - num2text(MED_FREQ) = list(access_medical_equip), - num2text(MED_I_FREQ) = list(access_medical_equip), - num2text(SEC_FREQ) = list(access_security), - num2text(SEC_I_FREQ) = list(access_security), - num2text(SCI_FREQ) = list(access_tox,access_robotics,access_xenobiology), - num2text(SUP_FREQ) = list(access_cargo), - num2text(SRV_FREQ) = list(access_janitor, access_hydroponics), - ) diff --git a/vorestation.dme b/vorestation.dme index 1673969857d..237a29511a1 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -156,6 +156,7 @@ #include "code\_onclick\hud\robot_vr.dm" #include "code\_onclick\hud\screen_objects.dm" #include "code\_onclick\hud\screen_objects_vr.dm" +#include "code\_onclick\hud\skybox.dm" #include "code\_onclick\hud\spell_screen_objects.dm" #include "code\ATMOSPHERICS\_atmos_setup.dm" #include "code\ATMOSPHERICS\_atmospherics_helpers.dm" @@ -251,6 +252,7 @@ #include "code\controllers\subsystems\planets.dm" #include "code\controllers\subsystems\radiation.dm" #include "code\controllers\subsystems\shuttles.dm" +#include "code\controllers\subsystems\skybox.dm" #include "code\controllers\subsystems\sqlite.dm" #include "code\controllers\subsystems\sun.dm" #include "code\controllers\subsystems\time_track.dm"