diff --git a/.gitignore b/.gitignore index 423af10b7c0..03c676f53d8 100644 --- a/.gitignore +++ b/.gitignore @@ -14,7 +14,13 @@ vchat.db* data data/ cfg/ -.vscode + +#Visual studio stuff +*.vscode/* +!/.vscode/launch.json +!/.vscode/extensions.json +!/.vscode/settings.json +!/.vscode/tasks.json code/game/gamemodes/technomancer/spells/projectile/overload.dm code/game/gamemodes/technomancer/spells/projectile/overload.dm diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000000..24779e223e7 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "byond", + "request": "launch", + "name": "Launch DreamDaemon", + "preLaunchTask": "dm: build - ${command:CurrentDME}", + "dmb": "${workspaceFolder}/${command:CurrentDMB}", + "dreamDaemon": true + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000000..64cfc2bb26d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,36 @@ +{ + "eslint.nodePath": "./tgui/.yarn/sdks", + "eslint.workingDirectories": [ + "./tgui" + ], + "typescript.tsdk": "./tgui/.yarn/sdks/typescript/lib", + "typescript.enablePromptUseWorkspaceTsdk": true, + "search.exclude": { + "**/.yarn": true, + "**/.pnp.*": true + }, + "workbench.editorAssociations": { + "*.dmi": "imagePreview.previewEditor" + }, + "files.eol": "\n", + "gitlens.advanced.blame.customArguments": [ + "-w" + ], + "tgstationTestExplorer.project.resultsType": "json", + "[javascript]": { + "editor.rulers": [ + 120 + ] + }, + "[typescript]": { + "editor.rulers": [ + 120 + ] + }, + "[scss]": { + "editor.rulers": [ + 120 + ] + }, + "tgstationTestExplorer.project.DMEName": "tgmc.dme" +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000000..a3cb84d5a81 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,38 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "type": "dreammaker", + "dme": "vorestation.dme", + "problemMatcher": [ + "$dreammaker" + ], + "group": "build", + "label": "dm: build - vorestation.dme" + }, + { + "type": "shell", + "command": "tgui/bin/tgui", + "windows": { + "command": ".\\tgui\\bin\\tgui.bat" + }, + "problemMatcher": [ + "$tsc", + "$eslint-stylish" + ], + "group": "build", + "label": "tgui: build" + }, + { + "type": "shell", + "command": "yarn build", + "options": { + "cwd": "tgui/packages/tgfont/", + }, + "group": "build", + "problemMatcher": [], + "label": "tgui: build tgfont", + "detail": "node mkdist.cjs && fantasticon --config config.cjs" + } + ] +} \ No newline at end of file diff --git a/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm b/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm index f95b613466b..e43bc4b25ae 100644 --- a/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm +++ b/code/ATMOSPHERICS/components/binary_devices/algae_generator_vr.dm @@ -44,10 +44,10 @@ // TODO - Make these in actual icon states so its not silly like this var/image/I = image(icon = icon, icon_state = "algae-pipe-overlay", dir = dir) I.color = PIPE_COLOR_BLUE - overlays += I + add_overlay(I) I = image(icon = icon, icon_state = "algae-pipe-overlay", dir = reverse_dir[dir]) I.color = PIPE_COLOR_BLACK - overlays += I + add_overlay(I) /obj/machinery/atmospherics/binary/algae_farm/Destroy() . = ..() diff --git a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm index 86a87223ebc..896ad49eaca 100644 --- a/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm +++ b/code/ATMOSPHERICS/components/binary_devices/dp_vent_pump.dm @@ -64,7 +64,7 @@ if(!check_icon_cache()) return - overlays.Cut() + cut_overlays() var/vent_icon = "vent" @@ -80,7 +80,7 @@ else vent_icon += "[use_power ? "[pump_direction ? "out" : "in"]" : "off"]" - overlays += icon_manager.get_atmos_icon("device", , , vent_icon) + add_overlay(icon_manager.get_atmos_icon("device", , , vent_icon)) /obj/machinery/atmospherics/binary/dp_vent_pump/update_underlays() if(..()) diff --git a/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm b/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm index 7ef1858b2f5..c111b36b0a6 100644 --- a/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm +++ b/code/ATMOSPHERICS/components/binary_devices/pipeturbine.dm @@ -73,15 +73,15 @@ network2.update = 1 /obj/machinery/atmospherics/pipeturbine/update_icon() - overlays.Cut() + cut_overlays() if (dP > 10) - overlays += image('icons/obj/pipeturbine.dmi', "moto-turb") + add_overlay(image('icons/obj/pipeturbine.dmi', "moto-turb")) if (kin_energy > 100000) - overlays += image('icons/obj/pipeturbine.dmi', "low-turb") + add_overlay(image('icons/obj/pipeturbine.dmi', "low-turb")) if (kin_energy > 500000) - overlays += image('icons/obj/pipeturbine.dmi', "med-turb") + add_overlay(image('icons/obj/pipeturbine.dmi', "med-turb")) if (kin_energy > 1000000) - overlays += image('icons/obj/pipeturbine.dmi', "hi-turb") + add_overlay(image('icons/obj/pipeturbine.dmi', "hi-turb")) /obj/machinery/atmospherics/pipeturbine/attackby(obj/item/weapon/W as obj, mob/user as mob) if(W.is_wrench()) diff --git a/code/ATMOSPHERICS/components/unary/vent_pump.dm b/code/ATMOSPHERICS/components/unary/vent_pump.dm index 792d53d65d9..488855a71f6 100644 --- a/code/ATMOSPHERICS/components/unary/vent_pump.dm +++ b/code/ATMOSPHERICS/components/unary/vent_pump.dm @@ -19,6 +19,7 @@ power_rating = 30000 //7500 W ~ 10 HP //VOREStation Edit - 30000 W connect_types = CONNECT_TYPE_REGULAR|CONNECT_TYPE_SUPPLY //connects to regular and supply pipes + blocks_emissive = FALSE var/area/initial_loc level = 1 @@ -141,7 +142,7 @@ if(!check_icon_cache()) return - overlays.Cut() + cut_overlays() var/vent_icon = "vent" @@ -159,7 +160,7 @@ else vent_icon += "[pump_direction ? "out" : "in"]" - overlays += icon_manager.get_atmos_icon("device", , , vent_icon) + add_overlay(icon_manager.get_atmos_icon("device", , , vent_icon)) /obj/machinery/atmospherics/unary/vent_pump/update_underlays() if(..()) diff --git a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm index 1443b296d0e..515cd37e7f4 100644 --- a/code/ATMOSPHERICS/components/unary/vent_scrubber.dm +++ b/code/ATMOSPHERICS/components/unary/vent_scrubber.dm @@ -54,7 +54,7 @@ if(!check_icon_cache()) return - overlays.Cut() + cut_overlays() var/scrubber_icon = "scrubber" @@ -67,7 +67,7 @@ else scrubber_icon += "[use_power ? "[scrubbing ? "on" : "in"]" : "off"]" - overlays += icon_manager.get_atmos_icon("device", , , scrubber_icon) + add_overlay(icon_manager.get_atmos_icon("device", , , scrubber_icon)) /obj/machinery/atmospherics/unary/vent_scrubber/update_underlays() if(..()) diff --git a/code/ATMOSPHERICS/pipes/cap.dm b/code/ATMOSPHERICS/pipes/cap.dm index 2a63bb3a20a..72c9e829917 100644 --- a/code/ATMOSPHERICS/pipes/cap.dm +++ b/code/ATMOSPHERICS/pipes/cap.dm @@ -53,9 +53,9 @@ alpha = 255 - overlays.Cut() - overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "cap[icon_connect_type]") - + cut_overlays() + add_overlay(icon_manager.get_atmos_icon("pipe", , pipe_color, "cap[icon_connect_type]")) + /obj/machinery/atmospherics/pipe/cap/atmos_init() for(var/obj/machinery/atmospherics/target in get_step(src, dir)) if (can_be_node(target, 1)) diff --git a/code/ATMOSPHERICS/pipes/manifold.dm b/code/ATMOSPHERICS/pipes/manifold.dm index a17f78e50df..a02f0e66de0 100644 --- a/code/ATMOSPHERICS/pipes/manifold.dm +++ b/code/ATMOSPHERICS/pipes/manifold.dm @@ -102,9 +102,9 @@ alpha = 255 - overlays.Cut() - overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "core" + icon_connect_type) - overlays += icon_manager.get_atmos_icon("manifold", , , "clamps" + icon_connect_type) + cut_overlays() + add_overlay(icon_manager.get_atmos_icon("manifold", , pipe_color, "core" + icon_connect_type)) + add_overlay(icon_manager.get_atmos_icon("manifold", , , "clamps" + icon_connect_type)) underlays.Cut() var/turf/T = get_turf(src) diff --git a/code/ATMOSPHERICS/pipes/manifold4w.dm b/code/ATMOSPHERICS/pipes/manifold4w.dm index 7273ac5288e..eac8494a65d 100644 --- a/code/ATMOSPHERICS/pipes/manifold4w.dm +++ b/code/ATMOSPHERICS/pipes/manifold4w.dm @@ -102,9 +102,9 @@ alpha = 255 - overlays.Cut() - overlays += icon_manager.get_atmos_icon("manifold", , pipe_color, "4way" + icon_connect_type) - overlays += icon_manager.get_atmos_icon("manifold", , , "clamps_4way" + icon_connect_type) + cut_overlays() + add_overlay(icon_manager.get_atmos_icon("manifold", , pipe_color, "4way" + icon_connect_type)) + add_overlay(icon_manager.get_atmos_icon("manifold", , , "clamps_4way" + icon_connect_type)) underlays.Cut() var/turf/T = get_turf(src) diff --git a/code/ATMOSPHERICS/pipes/simple.dm b/code/ATMOSPHERICS/pipes/simple.dm index e0f6f7d9516..1f427fb151d 100644 --- a/code/ATMOSPHERICS/pipes/simple.dm +++ b/code/ATMOSPHERICS/pipes/simple.dm @@ -117,12 +117,12 @@ alpha = 255 - overlays.Cut() + cut_overlays() if(node1 && node2) - overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "[pipe_icon]intact[icon_connect_type]") + add_overlay(icon_manager.get_atmos_icon("pipe", , pipe_color, "[pipe_icon]intact[icon_connect_type]")) else - overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "[pipe_icon]exposed[node1?1:0][node2?1:0][icon_connect_type]") + add_overlay(icon_manager.get_atmos_icon("pipe", , pipe_color, "[pipe_icon]exposed[node1?1:0][node2?1:0][icon_connect_type]")) /obj/machinery/atmospherics/pipe/simple/update_underlays() return diff --git a/code/ATMOSPHERICS/pipes/universal.dm b/code/ATMOSPHERICS/pipes/universal.dm index a72ef219f78..e1df93ee673 100644 --- a/code/ATMOSPHERICS/pipes/universal.dm +++ b/code/ATMOSPHERICS/pipes/universal.dm @@ -16,8 +16,8 @@ alpha = 255 - overlays.Cut() - overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "universal") + cut_overlays() + add_overlay(icon_manager.get_atmos_icon("pipe", , pipe_color, "universal")) underlays.Cut() if (node1) @@ -54,8 +54,8 @@ alpha = 255 - overlays.Cut() - overlays += icon_manager.get_atmos_icon("pipe", , pipe_color, "universal") + cut_overlays() + add_overlay(icon_manager.get_atmos_icon("pipe", , pipe_color, "universal")) underlays.Cut() if (node1) diff --git a/code/ZAS/ConnectionGroup.dm b/code/ZAS/ConnectionGroup.dm index 11b1e22a0ba..2811ff6c77f 100644 --- a/code/ZAS/ConnectionGroup.dm +++ b/code/ZAS/ConnectionGroup.dm @@ -57,14 +57,12 @@ Class Procs: */ - -/connection_edge/var/zone/A - -/connection_edge/var/list/connecting_turfs = list() -/connection_edge/var/direct = 0 -/connection_edge/var/sleeping = 1 - -/connection_edge/var/coefficient = 0 +/connection_edge + var/zone/A + var/list/connecting_turfs = list() + var/direct = 0 + var/sleeping = 1 + var/coefficient = 0 /connection_edge/New() CRASH("Cannot make connection edge without specifications.") @@ -119,7 +117,8 @@ Class Procs: -/connection_edge/zone/var/zone/B +/connection_edge/zone + var/zone/B /connection_edge/zone/New(zone/A, zone/B) @@ -189,8 +188,11 @@ Class Procs: if(A == from) return B else return A -/connection_edge/unsimulated/var/turf/B -/connection_edge/unsimulated/var/datum/gas_mixture/air +/connection_edge/unsimulated + var/turf/B + +/connection_edge/unsimulated + var/datum/gas_mixture/air /connection_edge/unsimulated/New(zone/A, turf/B) src.A = A diff --git a/code/ZAS/Controller.dm b/code/ZAS/Controller.dm index be103e7a55f..7f7b5752469 100644 --- a/code/ZAS/Controller.dm +++ b/code/ZAS/Controller.dm @@ -170,7 +170,7 @@ Class Procs: if(T.needs_air_update) return tiles_to_update |= T #ifdef ZASDBG - T.overlays += mark + T.add_overlay(mark) #endif T.needs_air_update = 1 diff --git a/code/ZAS/Debug.dm b/code/ZAS/Debug.dm index 6f0a67fd3eb..5aa2c73df20 100644 --- a/code/ZAS/Debug.dm +++ b/code/ZAS/Debug.dm @@ -12,8 +12,8 @@ var/image/mark = image('icons/Testing/Zone.dmi', icon_state = "mark") /turf/var/tmp/dbg_img /turf/proc/dbg(image/img, d = 0) if(d > 0) img.dir = d - overlays -= dbg_img - overlays += img + cut_overlay(dbg_img) + add_overlay(img) dbg_img = img proc/soft_assert(thing,fail) diff --git a/code/ZAS/Phoron.dm b/code/ZAS/Phoron.dm index e12beb900ff..4017d0a74a7 100644 --- a/code/ZAS/Phoron.dm +++ b/code/ZAS/Phoron.dm @@ -63,11 +63,11 @@ obj/var/contaminated = 0 else if(!contaminated) contaminated = 1 - overlays += contamination_overlay + add_overlay(contamination_overlay) /obj/item/proc/decontaminate() contaminated = 0 - overlays -= contamination_overlay + cut_overlay(contamination_overlay) /mob/proc/contaminate() diff --git a/code/__defines/_planes+layers.dm b/code/__defines/_planes+layers.dm index 551e94183c1..639724eca25 100644 --- a/code/__defines/_planes+layers.dm +++ b/code/__defines/_planes+layers.dm @@ -50,10 +50,10 @@ What is the naming convention for planes or layers? #define PLANE_LOOKINGGLASS_IMG -77 // For the Looking Glass holodecks // 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) +#define OPENSPACE_PLANE -75 // /turf/simulated/open will use OPENSPACE_PLANE + z (Valid z's being 2 thru 27) //VOREStation Edit #define OPENSPACE_PLANE_START -73 -#define OPENSPACE_PLANE_END -58 -#define OVER_OPENSPACE_PLANE -57 +#define OPENSPACE_PLANE_END -48 //VOREStation Edit +#define OVER_OPENSPACE_PLANE -47 //VOREStation Edit // Turf Planes #define PLATING_PLANE -44 // Plating @@ -122,9 +122,21 @@ What is the naming convention for planes or layers? #define PLANE_ADMIN1 3 //Purely for shenanigans (below lighting) #define PLANE_PLANETLIGHTING 4 //Lighting on planets + #define PLANE_LIGHTING 5 //Where the lighting (and darkness) lives -#define PLANE_LIGHTING_ABOVE 6 //For glowy eyes etc. that shouldn't be affected by darkness -#define PLANE_RUNECHAT 7 + #define LIGHTING_RENDER_TARGET "LIGHT_PLANE" + +#define PLANE_O_LIGHTING_VISUAL 6 //For masking the lighting plane + #define O_LIGHTING_VISUAL_RENDER_TARGET "O_LIGHT_VISUAL_PLANE" + +#define PLANE_LIGHTING_ABOVE 7 //For glowy eyes etc. that shouldn't be affected by darkness + #define LIGHTING_ABOVE_RENDER_TARGET "LIGHTING_ABOVE_PLANE" + +#define PLANE_EMISSIVE 8 //Glowing lights in otherwise dark areas using overlays/sprites + #define EMISSIVE_RENDER_TARGET "*EMISSIVE_PLANE" + #define EMISSIVE_LAYER_UNBLOCKABLE 9999 + +#define PLANE_RUNECHAT 9 #define PLANE_GHOSTS 10 //Spooooooooky ghooooooosts #define PLANE_AI_EYE 11 //The AI eye lives here diff --git a/code/__defines/color.dm b/code/__defines/color.dm index c3db40eefb3..af112ef4d63 100644 --- a/code/__defines/color.dm +++ b/code/__defines/color.dm @@ -92,6 +92,7 @@ #define COLOR_LIGHT_VIOLET "#e7bfff" #define COLOR_SAN_MARINO_BLUE "#4b75ab" #define COLOR_OLIVE "#52613b" //VOREStation Addition +#define COLOR_HALF_TRANSPARENT_BLACK "#0000007A" #define PIPE_COLOR_GREY "#808080" #define PIPE_COLOR_RED "#ff0000" @@ -171,4 +172,40 @@ #define COLOR_WEBHOOK_DEFAULT 0x8bbbd5 // "#8bbbd5" #define COLOR_WEBHOOK_GOOD 0x2ECC71 // "#2ECC71" #define COLOR_WEBHOOK_POOR 0xE67E22 // "#E67E22" -#define COLOR_WEBHOOK_BAD 0xE74C3C // "#E74C3C" \ No newline at end of file +#define COLOR_WEBHOOK_BAD 0xE74C3C // "#E74C3C" + +//Some defines to generalise colours used in lighting. +//Important note on colors. Colors can end up significantly different from the basic html picture, especially when saturated +#define LIGHT_COLOR_RED "#FA8282" //Warm but extremely diluted red. rgb(250, 130, 130) +#define LIGHT_COLOR_GREEN "#64C864" //Bright but quickly dissipating neon green. rgb(100, 200, 100) +#define LIGHT_COLOR_BLUE "#6496FA" //Cold, diluted blue. rgb(100, 150, 250) + +#define LIGHT_COLOR_BLUEGREEN "#7DE1AF" //Light blueish green. rgb(125, 225, 175) +#define LIGHT_COLOR_CYAN "#7DE1E1" //Diluted cyan. rgb(125, 225, 225) +#define LIGHT_COLOR_LIGHT_CYAN "#40CEFF" //More-saturated cyan. rgb(64, 206, 255) +#define LIGHT_COLOR_DARK_BLUE "#6496FA" //Saturated blue. rgb(51, 117, 248) +#define LIGHT_COLOR_PINK "#E17DE1" //Diluted, mid-warmth pink. rgb(225, 125, 225) +#define LIGHT_COLOR_YELLOW "#E1E17D" //Dimmed yellow, leaning kaki. rgb(225, 225, 125) +#define LIGHT_COLOR_BROWN "#966432" //Clear brown, mostly dim. rgb(150, 100, 50) +#define LIGHT_COLOR_ORANGE "#FA9632" //Mostly pure orange. rgb(250, 150, 50) +#define LIGHT_COLOR_PURPLE "#952CF4" //Light Purple. rgb(149, 44, 244) +#define LIGHT_COLOR_LAVENDER "#9B51FF" //Less-saturated light purple. rgb(155, 81, 255) + +//These ones aren't a direct colour like the ones above, because nothing would fit +#define LIGHT_COLOR_FIRE "#FAA019" //Warm orange color, leaning strongly towards yellow. rgb(250, 160, 25) +#define LIGHT_COLOR_LAVA "#C48A18" //Very warm yellow, leaning slightly towards orange. rgb(196, 138, 24) +#define LIGHT_COLOR_FLARE "#FA644B" //Bright, non-saturated red. Leaning slightly towards pink for visibility. rgb(250, 100, 75) +#define LIGHT_COLOR_SLIME_LAMP "#AFC84B" //Weird color, between yellow and green, very slimy. rgb(175, 200, 75) +#define LIGHT_COLOR_TUNGSTEN "#FAE1AF" //Extremely diluted yellow, close to skin color (for some reason). rgb(250, 225, 175) +#define LIGHT_COLOR_HALOGEN "#F0FAFA" //Barely visible cyan-ish hue, as the doctor prescribed. rgb(240, 250, 250) + +//Lighting values used by the station lights +#define LIGHT_COLOR_FLUORESCENT_TUBE "#E0EFFF" +#define LIGHT_COLOR_FLUORESCENT_FLASHLIGHT "#CDDDFF" +#define LIGHT_COLOR_INCANDESCENT_TUBE "#fffed9" +#define LIGHT_COLOR_INCANDESCENT_BULB "#ffe7ce" +#define LIGHT_COLOR_INCANDESCENT_FLASHLIGHT "#FFCC66" +#define LIGHT_COLOR_NIGHTSHIFT "#EFCC86" + +//Fake ambient occlusion filter +#define AMBIENT_OCCLUSION filter(type="drop_shadow", x=0, y=-2, size=4, offset=3, color="#04080F80") diff --git a/code/__defines/dcs/flags.dm b/code/__defines/dcs/flags.dm index 128c9f19387..84d332bd567 100644 --- a/code/__defines/dcs/flags.dm +++ b/code/__defines/dcs/flags.dm @@ -15,7 +15,10 @@ * Only elements created with the same arguments given after `id_arg_index` share an element instance * The arguments are the same when the text and number values are the same and all other values have the same ref */ -#define ELEMENT_BESPOKE (1 << 1) +#define ELEMENT_BESPOKE (1 << 1) +/// Causes all detach arguments to be passed to detach instead of only being used to identify the element +/// When this is used your Detach proc should have the same signature as your Attach proc +#define ELEMENT_COMPLEX_DETACH (1 << 2) // How multiple components of the exact same type are handled in the same datum /// old component is deleted (default) diff --git a/code/__defines/dcs/signals.dm b/code/__defines/dcs/signals.dm index c6edaa80e4a..7079362659d 100644 --- a/code/__defines/dcs/signals.dm +++ b/code/__defines/dcs/signals.dm @@ -42,6 +42,9 @@ #define COMSIG_PARENT_QDELETING "parent_qdeleting" /// generic topic handler (usr, href_list) #define COMSIG_TOPIC "handle_topic" +/// from datum ui_act (usr, action) +#define COMSIG_UI_ACT "COMSIG_UI_ACT" + /// fires on the target datum when an element is attached to it (/datum/element) #define COMSIG_ELEMENT_ATTACH "element_attach" @@ -162,6 +165,8 @@ #define COMSIG_ATOM_ORBIT_BEGIN "atom_orbit_begin" ///called when an atom stops orbiting another atom: (atom) #define COMSIG_ATOM_ORBIT_STOP "atom_orbit_stop" +///from base of atom/set_opacity(): (new_opacity) +#define COMSIG_ATOM_SET_OPACITY "atom_set_opacity" ///////////////// ///from base of atom/attack_ghost(): (mob/dead/observer/ghost) #define COMSIG_ATOM_ATTACK_GHOST "atom_attack_ghost" @@ -737,4 +742,40 @@ #define COMSIG_TRIGGERED_ALARM "ssalarm_triggered" #define COMSIG_CANCELLED_ALARM "ssalarm_cancelled" -#define COMSIG_REAGENTS_CRAFTING_PING "reagents_crafting_ping" \ No newline at end of file +#define COMSIG_REAGENTS_CRAFTING_PING "reagents_crafting_ping" + +// Lighting: +///from base of [atom/proc/set_light]: (l_range, l_power, l_color, l_on) +#define COMSIG_ATOM_SET_LIGHT "atom_set_light" + /// Blocks [/atom/proc/set_light], [/atom/proc/set_light_power], [/atom/proc/set_light_range], [/atom/proc/set_light_color], [/atom/proc/set_light_on], and [/atom/proc/set_light_flags]. + #define COMPONENT_BLOCK_LIGHT_UPDATE (1<<0) +///Called right before the atom changes the value of light_power to a different one, from base [atom/proc/set_light_power]: (new_power) +#define COMSIG_ATOM_SET_LIGHT_POWER "atom_set_light_power" +///Called right after the atom changes the value of light_power to a different one, from base of [/atom/proc/set_light_power]: (old_power) +#define COMSIG_ATOM_UPDATE_LIGHT_POWER "atom_update_light_power" +///Called right before the atom changes the value of light_range to a different one, from base [atom/proc/set_light_range]: (new_range) +#define COMSIG_ATOM_SET_LIGHT_RANGE "atom_set_light_range" +///Called right after the atom changes the value of light_range to a different one, from base of [/atom/proc/set_light_range]: (old_range) +#define COMSIG_ATOM_UPDATE_LIGHT_RANGE "atom_update_light_range" +///Called right before the atom changes the value of light_color to a different one, from base [atom/proc/set_light_color]: (new_color) +#define COMSIG_ATOM_SET_LIGHT_COLOR "atom_set_light_color" +///Called right after the atom changes the value of light_color to a different one, from base of [/atom/proc/set_light_color]: (old_color) +#define COMSIG_ATOM_UPDATE_LIGHT_COLOR "atom_update_light_color" +///Called right before the atom changes the value of light_on to a different one, from base [atom/proc/set_light_on]: (new_value) +#define COMSIG_ATOM_SET_LIGHT_ON "atom_set_light_on" +///Called right after the atom changes the value of light_on to a different one, from base of [/atom/proc/set_light_on]: (old_value) +#define COMSIG_ATOM_UPDATE_LIGHT_ON "atom_update_light_on" +///Called right before the atom changes the value of light_flags to a different one, from base [atom/proc/set_light_flags]: (new_flags) +#define COMSIG_ATOM_SET_LIGHT_FLAGS "atom_set_light_flags" +///Called right after the atom changes the value of light_flags to a different one, from base of [/atom/proc/set_light_flags]: (old_flags) +#define COMSIG_ATOM_UPDATE_LIGHT_FLAGS "atom_update_light_flags" + +// /datum/element/light_eater +///from base of [/datum/element/light_eater/proc/table_buffet]: (list/light_queue, datum/light_eater) +#define COMSIG_LIGHT_EATER_QUEUE "light_eater_queue" +///from base of [/datum/element/light_eater/proc/devour]: (datum/light_eater) +#define COMSIG_LIGHT_EATER_ACT "light_eater_act" + ///Prevents the default light eater behavior from running in case of immunity or custom behavior + #define COMPONENT_BLOCK_LIGHT_EATER (1<<0) +///from base of [/datum/element/light_eater/proc/devour]: (atom/eaten_light) +#define COMSIG_LIGHT_EATER_DEVOUR "light_eater_devour" diff --git a/code/__defines/flags.dm b/code/__defines/flags.dm index 2ff8f44dbab..8ac15ebc535 100644 --- a/code/__defines/flags.dm +++ b/code/__defines/flags.dm @@ -13,6 +13,10 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768)) +/* Directions */ +///All the cardinal direction bitflags. +#define ALL_CARDINALS (NORTH|SOUTH|EAST|WEST) + // datum_flags #define DF_VAR_EDITED (1<<0) #define DF_ISPROCESSING (1<<1) diff --git a/code/__defines/lighting.dm b/code/__defines/lighting.dm index 999bb7473ad..bf854548760 100644 --- a/code/__defines/lighting.dm +++ b/code/__defines/lighting.dm @@ -1,88 +1,119 @@ -#define FOR_DVIEW(type, range, center, invis_flags) \ - dview_mob.loc = center; \ - dview_mob.see_invisible = invis_flags; \ - for(type in view(range, dview_mob)) +///Object doesn't use any of the light systems. Should be changed to add a light source to the object. +#define NO_LIGHT_SUPPORT 0 +///Light made with the lighting datums, applying a matrix. +#define STATIC_LIGHT 1 +///Light made by masking the lighting darkness plane. +#define MOVABLE_LIGHT 2 +///Light made by masking the lighting darkness plane, and is directional. +#define MOVABLE_LIGHT_DIRECTIONAL 3 -#define END_FOR_DVIEW dview_mob.loc = null +///Is a movable light source attached to another movable (its loc), meaning that the lighting component should go one level deeper. +#define LIGHT_ATTACHED (1<<0) -#define LIGHTING_FALLOFF 1 // type of falloff to use for lighting; 1 for circular, 2 for square -#define LIGHTING_LAMBERTIAN 0 // use lambertian shading for light sources -#define LIGHTING_HEIGHT 1 // height off the ground of light sources on the pseudo-z-axis, you should probably leave this alone +//Bay lighting engine shit, not in /code/modules/lighting because BYOND is being shit about it +/// frequency, in 1/10ths of a second, of the lighting process +#define LIGHTING_INTERVAL 5 -#define LIGHTING_ICON 'icons/effects/lighting_overlay.dmi' // icon used for lighting shading effects -#define LIGHTING_ICON_STATE_DARK "soft_dark" // Change between "soft_dark" and "dark" to swap soft darkvision +#define MINIMUM_USEFUL_LIGHT_RANGE 1.4 -#define LIGHTING_ROUND_VALUE (1 / 64) // Value used to round lumcounts, values smaller than 1/69 don't matter (if they do, thanks sinking points), greater values will make lighting less precise, but in turn increase performance, VERY SLIGHTLY. +/// type of falloff to use for lighting; 1 for circular, 2 for square +#define LIGHTING_FALLOFF 1 +/// use lambertian shading for light sources +#define LIGHTING_LAMBERTIAN 0 +/// height off the ground of light sources on the pseudo-z-axis, you should probably leave this alone +#define LIGHTING_HEIGHT 1 +/// Value used to round lumcounts, values smaller than 1/129 don't matter (if they do, thanks sinking points), greater values will make lighting less precise, but in turn increase performance, VERY SLIGHTLY. +#define LIGHTING_ROUND_VALUE (1 / 64) -#define LIGHTING_SOFT_THRESHOLD 0.05 // If the max of the lighting lumcounts of each spectrum drops below this, disable luminosity on the lighting overlays. This also should be the transparancy of the "soft_dark" icon state. +/// icon used for lighting shading effects +#define LIGHTING_ICON 'icons/effects/lighting_object.dmi' -#define LIGHTING_MULT_FACTOR 0.5 +/// If the max of the lighting lumcounts of each spectrum drops below this, disable luminosity on the lighting objects. +/// Set to zero to disable soft lighting. Luminosity changes then work if it's lit at all. +#define LIGHTING_SOFT_THRESHOLD 0 -// If I were you I'd leave this alone. +/// If I were you I'd leave this alone. #define LIGHTING_BASE_MATRIX \ list \ ( \ - LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \ - LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \ - LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \ - LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \ + 1, 1, 1, 0, \ + 1, 1, 1, 0, \ + 1, 1, 1, 0, \ + 1, 1, 1, 0, \ 0, 0, 0, 1 \ ) \ -// Helpers so we can (more easily) control the colour matrices. -#define CL_MATRIX_RR 1 -#define CL_MATRIX_RG 2 -#define CL_MATRIX_RB 3 -#define CL_MATRIX_RA 4 -#define CL_MATRIX_GR 5 -#define CL_MATRIX_GG 6 -#define CL_MATRIX_GB 7 -#define CL_MATRIX_GA 8 -#define CL_MATRIX_BR 9 -#define CL_MATRIX_BG 10 -#define CL_MATRIX_BB 11 -#define CL_MATRIX_BA 12 -#define CL_MATRIX_AR 13 -#define CL_MATRIX_AG 14 -#define CL_MATRIX_AB 15 -#define CL_MATRIX_AA 16 -#define CL_MATRIX_CR 17 -#define CL_MATRIX_CG 18 -#define CL_MATRIX_CB 19 -#define CL_MATRIX_CA 20 +///How many tiles standard fires glow. +#define LIGHT_RANGE_FIRE 3 -//Some defines to generalise colours used in lighting. -//Important note on colors. Colors can end up significantly different from the basic html picture, especially when saturated -#define LIGHT_COLOR_RED "#FA8282" //Warm but extremely diluted red. rgb(250, 130, 130) -#define LIGHT_COLOR_GREEN "#64C864" //Bright but quickly dissipating neon green. rgb(100, 200, 100) -#define LIGHT_COLOR_BLUE "#6496FA" //Cold, diluted blue. rgb(100, 150, 250) +#define LIGHTING_PLANE_ALPHA_VISIBLE 255 +#define LIGHTING_PLANE_ALPHA_NV_TRAIT 245 +#define LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE 192 +/// For lighting alpha, small amounts lead to big changes. even at 128 its hard to figure out what is dark and what is light, at 64 you almost can't even tell. +#define LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE 128 +#define LIGHTING_PLANE_ALPHA_INVISIBLE 0 -#define LIGHT_COLOR_BLUEGREEN "#7DE1AF" //Light blueish green. rgb(125, 225, 175) -#define LIGHT_COLOR_CYAN "#7DE1E1" //Diluted cyan. rgb(125, 225, 225) -#define LIGHT_COLOR_LIGHT_CYAN "#40CEFF" //More-saturated cyan. rgb(64, 206, 255) -#define LIGHT_COLOR_DARK_BLUE "#6496FA" //Saturated blue. rgb(51, 117, 248) -#define LIGHT_COLOR_PINK "#E17DE1" //Diluted, mid-warmth pink. rgb(225, 125, 225) -#define LIGHT_COLOR_YELLOW "#E1E17D" //Dimmed yellow, leaning kaki. rgb(225, 225, 125) -#define LIGHT_COLOR_BROWN "#966432" //Clear brown, mostly dim. rgb(150, 100, 50) -#define LIGHT_COLOR_ORANGE "#FA9632" //Mostly pure orange. rgb(250, 150, 50) -#define LIGHT_COLOR_PURPLE "#952CF4" //Light Purple. rgb(149, 44, 244) -#define LIGHT_COLOR_LAVENDER "#9B51FF" //Less-saturated light purple. rgb(155, 81, 255) +//lighting area defines +/// dynamic lighting disabled (area stays at full brightness) +#define DYNAMIC_LIGHTING_DISABLED 0 +/// dynamic lighting enabled +#define DYNAMIC_LIGHTING_ENABLED 1 +/// dynamic lighting enabled even if the area doesn't require power +#define DYNAMIC_LIGHTING_FORCED 2 +/// dynamic lighting enabled only if starlight is. +#define DYNAMIC_LIGHTING_IFSTARLIGHT 3 +#define IS_DYNAMIC_LIGHTING(A) A.dynamic_lighting -//These ones aren't a direct colour like the ones above, because nothing would fit -#define LIGHT_COLOR_FIRE "#FAA019" //Warm orange color, leaning strongly towards yellow. rgb(250, 160, 25) -#define LIGHT_COLOR_LAVA "#C48A18" //Very warm yellow, leaning slightly towards orange. rgb(196, 138, 24) -#define LIGHT_COLOR_FLARE "#FA644B" //Bright, non-saturated red. Leaning slightly towards pink for visibility. rgb(250, 100, 75) -#define LIGHT_COLOR_SLIME_LAMP "#AFC84B" //Weird color, between yellow and green, very slimy. rgb(175, 200, 75) -#define LIGHT_COLOR_TUNGSTEN "#FAE1AF" //Extremely diluted yellow, close to skin color (for some reason). rgb(250, 225, 175) -#define LIGHT_COLOR_HALOGEN "#F0FAFA" //Barely visible cyan-ish hue, as the doctor prescribed. rgb(240, 250, 250) -//Lighting values used by the station lights -#define LIGHT_COLOR_FLUORESCENT_TUBE "#E0EFFF" -#define LIGHT_COLOR_FLUORESCENT_FLASHLIGHT "#CDDDFF" -#define LIGHT_COLOR_INCANDESCENT_TUBE "#FFFEB8" -#define LIGHT_COLOR_INCANDESCENT_BULB "#FFDDBB" -#define LIGHT_COLOR_INCANDESCENT_FLASHLIGHT "#FFCC66" -#define LIGHT_COLOR_NIGHTSHIFT "#EFCC86" +//code assumes higher numbers override lower numbers. +#define LIGHTING_NO_UPDATE 0 +#define LIGHTING_VIS_UPDATE 1 +#define LIGHTING_CHECK_UPDATE 2 +#define LIGHTING_FORCE_UPDATE 3 -//Fake ambient occlusion filter -#define AMBIENT_OCCLUSION filter(type="drop_shadow", x=0, y=-1, size=2, offset=2, color="#04080F55") //VOREStation Edit for prettier visuals. +#define FLASH_LIGHT_DURATION 2 +#define FLASH_LIGHT_POWER 3 +#define FLASH_LIGHT_RANGE 3.8 + +// Emissive blocking. +/// Uses vis_overlays to leverage caching so that very few new items need to be made for the overlay. For anything that doesn't change outline or opaque area much or at all. +#define EMISSIVE_BLOCK_GENERIC 1 +/// Uses a dedicated render_target object to copy the entire appearance in real time to the blocking layer. For things that can change in appearance a lot from the base state, like humans. +#define EMISSIVE_BLOCK_UNIQUE 2 + +/// The color matrix applied to all emissive overlays. Should be solely dependent on alpha and not have RGB overlap with [EM_BLOCK_COLOR]. +#define EMISSIVE_COLOR list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 1,1,1,0) +/// A globaly cached version of [EMISSIVE_COLOR] for quick access. +GLOBAL_LIST_INIT(emissive_color, EMISSIVE_COLOR) +/// The color matrix applied to all emissive blockers. Should be solely dependent on alpha and not have RGB overlap with [EMISSIVE_COLOR]. +#define EM_BLOCK_COLOR list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) +/// A globaly cached version of [EM_BLOCK_COLOR] for quick access. +GLOBAL_LIST_INIT(em_block_color, EM_BLOCK_COLOR) +/// The color matrix used to mask out emissive blockers on the emissive plane. Alpha should default to zero, be solely dependent on the RGB value of [EMISSIVE_COLOR], and be independant of the RGB value of [EM_BLOCK_COLOR]. +#define EM_MASK_MATRIX list(0,0,0,1/3, 0,0,0,1/3, 0,0,0,1/3, 0,0,0,0, 1,1,1,0) +/// A globaly cached version of [EM_MASK_MATRIX] for quick access. +GLOBAL_LIST_INIT(em_mask_matrix, EM_MASK_MATRIX) + +/// Returns the red part of a #RRGGBB hex sequence as number +#define GETREDPART(hexa) hex2num(copytext(hexa, 2, 4)) + +/// Returns the green part of a #RRGGBB hex sequence as number +#define GETGREENPART(hexa) hex2num(copytext(hexa, 4, 6)) + +/// Returns the blue part of a #RRGGBB hex sequence as number +#define GETBLUEPART(hexa) hex2num(copytext(hexa, 6, 8)) + +/// Parse the hexadecimal color into lumcounts of each perspective. +#define PARSE_LIGHT_COLOR(source) \ +do { \ + if (source.light_color != COLOR_WHITE) { \ + var/__light_color = source.light_color; \ + source.lum_r = GETREDPART(__light_color) / 255; \ + source.lum_g = GETGREENPART(__light_color) / 255; \ + source.lum_b = GETBLUEPART(__light_color) / 255; \ + } else { \ + source.lum_r = 1; \ + source.lum_g = 1; \ + source.lum_b = 1; \ + }; \ +} while (FALSE) diff --git a/code/__defines/lighting_vr.dm b/code/__defines/lighting_vr.dm index 0cd6b060a17..a7f51e8bbc2 100644 --- a/code/__defines/lighting_vr.dm +++ b/code/__defines/lighting_vr.dm @@ -1,2 +1,4 @@ #define LIGHT_COLOR_INCANDESCENT_TUBE "#E0EFF0" -#define LIGHT_COLOR_INCANDESCENT_BULB "#FFFEB8" \ No newline at end of file +#define LIGHT_COLOR_INCANDESCENT_BULB "#FFFEB8" +//Fake ambient occlusion filter +#define AMBIENT_OCCLUSION filter(type="drop_shadow", x=0, y=-1, size=2, offset=2, color="#04080F55") //VOREStation Edit for prettier visuals. \ No newline at end of file diff --git a/code/__defines/map.dm b/code/__defines/map.dm index 9b8856c70ea..9bb14692125 100644 --- a/code/__defines/map.dm +++ b/code/__defines/map.dm @@ -8,7 +8,7 @@ #define MAP_LEVEL_CONSOLES 0x040 // Z-levels available to various consoles, such as the crew monitor (when that gets coded in). Defaults to station_levels if unset. #define MAP_LEVEL_XENOARCH_EXEMPT 0x080 // Z-levels exempt from xenoarch digsite generation. #define MAP_LEVEL_PERSIST 0x100 // Z-levels where SSpersistence should persist between rounds -#define MAP_LEVEL_MAPPABLE 0x200 // Z-levels where SSpersistence should persist between rounds +#define MAP_LEVEL_MAPPABLE 0x200 // Z-levels where mapping units will work fully // Misc map defines. -#define SUBMAP_MAP_EDGE_PAD 8 // Automatically created submaps are forbidden from being this close to the main map's edge. //VOREStation Edit \ No newline at end of file +#define SUBMAP_MAP_EDGE_PAD 8 // Automatically created submaps are forbidden from being this close to the main map's edge. //VOREStation Edit diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm index 824155f93eb..b853f4e9b55 100644 --- a/code/__defines/misc.dm +++ b/code/__defines/misc.dm @@ -20,6 +20,7 @@ #define SEE_INVISIBLE_MINIMUM 5 #define INVISIBILITY_MAXIMUM 100 +#define INVISIBILITY_ABSTRACT 101 //only used for abstract objects, things that are not really there. // Pseudo-Invis, like Ninja, Ling, Etc. #define EFFECTIVE_INVIS 50 // Below this, can't be examined, may as well be invisible to the game diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index 7513ab3c006..b70001cbd61 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -377,37 +377,40 @@ //Vision flags, for dealing with plane visibility #define VIS_FULLBRIGHT 1 #define VIS_LIGHTING 2 -#define VIS_GHOSTS 3 -#define VIS_AI_EYE 4 +#define VIS_O_LIGHT 3 +#define VIS_EMISSIVE 4 -#define VIS_CH_STATUS 5 -#define VIS_CH_HEALTH 6 -#define VIS_CH_LIFE 7 -#define VIS_CH_ID 8 -#define VIS_CH_WANTED 9 -#define VIS_CH_IMPLOYAL 10 -#define VIS_CH_IMPTRACK 11 -#define VIS_CH_IMPCHEM 12 -#define VIS_CH_SPECIAL 13 -#define VIS_CH_STATUS_OOC 14 +#define VIS_GHOSTS 5 +#define VIS_AI_EYE 6 -#define VIS_ADMIN1 15 -#define VIS_ADMIN2 16 -#define VIS_ADMIN3 17 +#define VIS_CH_STATUS 7 +#define VIS_CH_HEALTH 8 +#define VIS_CH_LIFE 9 +#define VIS_CH_ID 10 +#define VIS_CH_WANTED 11 +#define VIS_CH_IMPLOYAL 12 +#define VIS_CH_IMPTRACK 13 +#define VIS_CH_IMPCHEM 14 +#define VIS_CH_SPECIAL 15 +#define VIS_CH_STATUS_OOC 16 -#define VIS_MESONS 18 +#define VIS_ADMIN1 17 +#define VIS_ADMIN2 18 +#define VIS_ADMIN3 19 -#define VIS_TURFS 19 -#define VIS_OBJS 20 -#define VIS_MOBS 21 +#define VIS_MESONS 20 -#define VIS_BUILDMODE 22 +#define VIS_TURFS 21 +#define VIS_OBJS 22 +#define VIS_MOBS 23 -#define VIS_CLOAKED 23 +#define VIS_BUILDMODE 24 -#define VIS_STATUS 24 +#define VIS_CLOAKED 25 -#define VIS_COUNT 24 //Must be highest number from above. +#define VIS_STATUS 26 + +#define VIS_COUNT 26 //Must be highest number from above. //Some mob icon layering defines #define BODY_LAYER -100 diff --git a/code/__defines/mobs_vr.dm b/code/__defines/mobs_vr.dm index dbd66d90620..116358e5779 100644 --- a/code/__defines/mobs_vr.dm +++ b/code/__defines/mobs_vr.dm @@ -1,13 +1,13 @@ #undef VIS_COUNT -#define VIS_CH_STATUS_R 24 -#define VIS_CH_HEALTH_VR 25 -#define VIS_CH_BACKUP 26 -#define VIS_CH_VANTAG 27 +#define VIS_CH_STATUS_R 27 +#define VIS_CH_HEALTH_VR 28 +#define VIS_CH_BACKUP 29 +#define VIS_CH_VANTAG 30 -#define VIS_AUGMENTED 28 +#define VIS_AUGMENTED 31 -#define VIS_COUNT 28 +#define VIS_COUNT 31 //Protean organs #define O_ORCH "orchestrator" diff --git a/code/__defines/subsystems.dm b/code/__defines/subsystems.dm index 0847e447dbb..9ad2af05047 100644 --- a/code/__defines/subsystems.dm +++ b/code/__defines/subsystems.dm @@ -56,6 +56,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G #define INIT_ORDER_SQLITE 40 #define INIT_ORDER_MEDIA_TRACKS 38 // Gotta get that lobby music up, yo #define INIT_ORDER_CHEMISTRY 35 +#define INIT_ORDER_VIS 32 #define INIT_ORDER_SKYBOX 30 #define INIT_ORDER_MAPPING 25 #define INIT_ORDER_SOUNDS 23 @@ -94,6 +95,7 @@ var/global/list/runlevel_flags = list(RUNLEVEL_LOBBY, RUNLEVEL_SETUP, RUNLEVEL_G #define FIRE_PRIORITY_SUPPLY 5 #define FIRE_PRIORITY_NIGHTSHIFT 5 #define FIRE_PRIORITY_PLANTS 5 +#define FIRE_PRIORITY_VIS 5 #define FIRE_PRIORITY_ORBIT 7 #define FIRE_PRIORITY_VOTE 8 #define FIRE_PRIORITY_INSTRUMENTS 9 diff --git a/code/__defines/tgui.dm b/code/__defines/tgui.dm index 3d706a4e0fa..c261e5ecdcf 100644 --- a/code/__defines/tgui.dm +++ b/code/__defines/tgui.dm @@ -18,6 +18,14 @@ /// Get a pool index of the provided window id #define TGUI_WINDOW_INDEX(window_id) text2num(copytext(window_id, 13)) +/// Creates a message packet for sending via output() +// This is {"type":type,"payload":payload}, but pre-encoded. This is much faster +// than doing it the normal way. +// To ensure this is correct, this is unit tested in tgui_create_message. +#define TGUI_CREATE_MESSAGE(type, payload) ( \ + "%7b%22type%22%3a%22[type]%22%2c%22payload%22%3a[url_encode(json_encode(payload))]%7d" \ +) + /// Max length for Modal Input #define TGUI_MODAL_INPUT_MAX_LENGTH 1024 /// Max length for Modal Input for names diff --git a/code/__defines/turfs.dm b/code/__defines/turfs.dm index 64593f6e114..770d58573f8 100644 --- a/code/__defines/turfs.dm +++ b/code/__defines/turfs.dm @@ -17,4 +17,6 @@ #define SMOOTH_GREYLIST 4 // Use a whitelist and a blacklist at the same time. atom smoothing only #define isCardinal(x) (x == NORTH || x == SOUTH || x == EAST || x == WEST) -#define isDiagonal(x) (x == NORTHEAST || x == SOUTHEAST || x == NORTHWEST || x == SOUTHWEST) \ No newline at end of file +#define isDiagonal(x) (x == NORTHEAST || x == SOUTHEAST || x == NORTHWEST || x == SOUTHWEST) + +#define IS_OPAQUE_TURF(turf) (turf.directional_opacity == ALL_CARDINALS) diff --git a/code/_global_vars/bitfields.dm b/code/_global_vars/bitfields.dm index 891c50ce88b..be3de4adeb5 100644 --- a/code/_global_vars/bitfields.dm +++ b/code/_global_vars/bitfields.dm @@ -2,6 +2,38 @@ GLOBAL_LIST_INIT(bitfields, list( "datum_flags" = list( "DF_VAR_EDITED" = DF_VAR_EDITED, "DF_ISPROCESSING" = DF_ISPROCESSING - ) - + ), + "appearance_flags" = list( + "KEEP_APART" = KEEP_APART, + "KEEP_TOGETHER" = KEEP_TOGETHER, + "LONG_GLIDE" = LONG_GLIDE, + "NO_CLIENT_COLOR" = NO_CLIENT_COLOR, + "PIXEL_SCALE" = PIXEL_SCALE, + "PLANE_MASTER" = PLANE_MASTER, + "RESET_ALPHA" = RESET_ALPHA, + "RESET_COLOR" = RESET_COLOR, + "RESET_TRANSFORM" = RESET_TRANSFORM, + "TILE_BOUND" = TILE_BOUND, + ), + "vis_flags" = list( + "VIS_HIDE" = VIS_HIDE, + "VIS_INHERIT_DIR" = VIS_INHERIT_DIR, + "VIS_INHERIT_ICON" = VIS_INHERIT_ICON, + "VIS_INHERIT_ICON_STATE" = VIS_INHERIT_ICON_STATE, + "VIS_INHERIT_ID" = VIS_INHERIT_ID, + "VIS_INHERIT_LAYER" = VIS_INHERIT_LAYER, + "VIS_INHERIT_PLANE" = VIS_INHERIT_PLANE, + "VIS_UNDERLAY" = VIS_UNDERLAY, + ), + "sight" = list( + "BLIND" = BLIND, + "SEE_BLACKNESS" = SEE_BLACKNESS, + "SEE_INFRA" = SEE_INFRA, + "SEE_MOBS" = SEE_MOBS, + "SEE_OBJS" = SEE_OBJS, + "SEE_PIXELS" = SEE_PIXELS, + "SEE_SELF" = SEE_SELF, + "SEE_THRU" = SEE_THRU, + "SEE_TURFS" = SEE_TURFS, + ), )) diff --git a/code/_helpers/atom_movables.dm b/code/_helpers/atom_movables.dm index b838f868e64..fbe2ab2a021 100644 --- a/code/_helpers/atom_movables.dm +++ b/code/_helpers/atom_movables.dm @@ -21,6 +21,8 @@ //Find coordinates var/turf/T = get_turf(AM) //use AM's turfs, as it's coords are the same as AM's AND AM's coords are lost if it is inside another atom + if(!T) + return null var/final_x = T.x + rough_x var/final_y = T.y + rough_y diff --git a/code/_helpers/global_lists_vr.dm b/code/_helpers/global_lists_vr.dm index 6c1fd9d261e..0d2ed5e5d63 100644 --- a/code/_helpers/global_lists_vr.dm +++ b/code/_helpers/global_lists_vr.dm @@ -232,6 +232,7 @@ var/global/list/contamination_flavors = list( "Dirty" = contamination_flavors_dirty, "Musky" = contamination_flavors_musky, "Smelly" = contamination_flavors_smelly, + "Slimy" = contamination_flavors_slimy, "Wet" = contamination_flavors_wet) var/global/list/contamination_flavors_generic = list("acrid", @@ -435,6 +436,21 @@ var/global/list/contamination_flavors_musky = list("drenched", "sticky", "tainted") +var/global/list/contamination_flavors_slimy = list("slimy", + "sloppy", + "drippy", + "glistening", + "dripping", + "gunky", + "slimed", + "mucky", + "viscous", + "dank", + "glutinous", + "syrupy", + "slippery", + "gelatinous") + var/global/list/contamination_colors = list("green", "white", "black", @@ -522,4 +538,4 @@ var/global/list/remainless_species = list(SPECIES_PROMETHEAN, return 1 // Hooks must return 1 var/global/list/weavable_structures = list() -var/global/list/weavable_items = list() \ No newline at end of file +var/global/list/weavable_items = list() diff --git a/code/_helpers/lighting.dm b/code/_helpers/lighting.dm new file mode 100644 index 00000000000..7cfd434e699 --- /dev/null +++ b/code/_helpers/lighting.dm @@ -0,0 +1,10 @@ +/// Produces a mutable appearance glued to the [EMISSIVE_PLANE] dyed to be the [EMISSIVE_COLOR]. +/proc/emissive_appearance(icon, icon_state = "", layer = FLOAT_LAYER, alpha = 255, appearance_flags = NONE) + var/mutable_appearance/appearance = mutable_appearance(icon, icon_state, layer, PLANE_EMISSIVE, alpha, appearance_flags) + appearance.color = GLOB.emissive_color + return appearance + +/proc/em_block_image_generic(var/image/I) + var/mutable_appearance/em_overlay = mutable_appearance(I.icon, I.icon_state, plane = PLANE_EMISSIVE, alpha = I.alpha, appearance_flags = KEEP_APART) + em_overlay.color = GLOB.em_block_color + return em_overlay diff --git a/code/_helpers/sorts/comparators.dm b/code/_helpers/sorts/comparators.dm index de64ad26f7a..dc2419b0b06 100644 --- a/code/_helpers/sorts/comparators.dm +++ b/code/_helpers/sorts/comparators.dm @@ -57,12 +57,6 @@ if (!.) . = B[STAT_ENTRY_COUNT] - A[STAT_ENTRY_COUNT] -// Compares complexity of recipes for use in cooking, etc. This is for telling which recipe to make, not for showing things to the player. -/proc/cmp_recipe_complexity_dsc(datum/recipe/A, datum/recipe/B) - var/a_score = LAZYLEN(A.items) + LAZYLEN(A.reagents) + LAZYLEN(A.fruit) - var/b_score = LAZYLEN(B.items) + LAZYLEN(B.reagents) + LAZYLEN(B.fruit) - return b_score - a_score - /proc/cmp_typepaths_asc(A, B) return sorttext("[B]","[A]") @@ -88,3 +82,6 @@ /proc/cmp_media_track_asc(datum/track/A, datum/track/B) var/genre_sort = sorttext(B.genre || "Uncategorized", A.genre || "Uncategorized") return genre_sort || sorttext(B.title, A.title) + +/proc/cmp_filter_data_priority(list/A, list/B) + return A["priority"] - B["priority"] diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index 5701521ec52..69f705a9693 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -1621,6 +1621,9 @@ GLOBAL_REAL_VAR(list/stack_trace_storage) // 'Utility' planes . += new /obj/screen/plane_master/fullbright //Lighting system (lighting_overlay objects) . += new /obj/screen/plane_master/lighting //Lighting system (but different!) + . += new /obj/screen/plane_master/o_light_visual //Object lighting (using masks) + . += new /obj/screen/plane_master/emissive //Emissive overlays + . += new /obj/screen/plane_master/ghosts //Ghosts! . += new /obj/screen/plane_master{plane = PLANE_AI_EYE} //AI Eye! diff --git a/code/_helpers/visual_filters.dm b/code/_helpers/visual_filters.dm index 6cafa5a04d2..96f68710000 100644 --- a/code/_helpers/visual_filters.dm +++ b/code/_helpers/visual_filters.dm @@ -1,20 +1,306 @@ -// These involve BYOND's built in filters that do visual effects, and not stuff that distinguishes between things. +#define ICON_NOT_SET "Not Set" +//This is stored as a nested list instead of datums or whatever because it json encodes nicely for usage in tgui +GLOBAL_LIST_INIT(master_filter_info, list( + "alpha" = list( + "defaults" = list( + "x" = 0, + "y" = 0, + "icon" = ICON_NOT_SET, + "render_source" = "", + "flags" = 0 + ), + "flags" = list( + "MASK_INVERSE" = MASK_INVERSE, + "MASK_SWAP" = MASK_SWAP + ) + ), + "angular_blur" = list( + "defaults" = list( + "x" = 0, + "y" = 0, + "size" = 1 + ) + ), + /* Not supported because making a proper matrix editor on the frontend would be a huge dick pain. + Uncomment if you ever implement it + "color" = list( + "defaults" = list( + "color" = matrix(), + "space" = FILTER_COLOR_RGB + ) + ), + */ + "displace" = list( + "defaults" = list( + "x" = 0, + "y" = 0, + "size" = null, + "icon" = ICON_NOT_SET, + "render_source" = "" + ) + ), + "drop_shadow" = list( + "defaults" = list( + "x" = 1, + "y" = -1, + "size" = 1, + "offset" = 0, + "color" = COLOR_HALF_TRANSPARENT_BLACK + ) + ), + "blur" = list( + "defaults" = list( + "size" = 1 + ) + ), + "layer" = list( + "defaults" = list( + "x" = 0, + "y" = 0, + "icon" = ICON_NOT_SET, + "render_source" = "", + "flags" = FILTER_OVERLAY, + "color" = "", + "transform" = null, + "blend_mode" = BLEND_DEFAULT + ) + ), + "motion_blur" = list( + "defaults" = list( + "x" = 0, + "y" = 0 + ) + ), + "outline" = list( + "defaults" = list( + "size" = 0, + "color" = COLOR_BLACK, + "flags" = NONE + ), + "flags" = list( + "OUTLINE_SHARP" = OUTLINE_SHARP, + "OUTLINE_SQUARE" = OUTLINE_SQUARE + ) + ), + "radial_blur" = list( + "defaults" = list( + "x" = 0, + "y" = 0, + "size" = 0.01 + ) + ), + "rays" = list( + "defaults" = list( + "x" = 0, + "y" = 0, + "size" = 16, + "color" = COLOR_WHITE, + "offset" = 0, + "density" = 10, + "threshold" = 0.5, + "factor" = 0, + "flags" = FILTER_OVERLAY | FILTER_UNDERLAY + ), + "flags" = list( + "FILTER_OVERLAY" = FILTER_OVERLAY, + "FILTER_UNDERLAY" = FILTER_UNDERLAY + ) + ), + "ripple" = list( + "defaults" = list( + "x" = 0, + "y" = 0, + "size" = 1, + "repeat" = 2, + "radius" = 0, + "falloff" = 1, + "flags" = NONE + ), + "flags" = list( + "WAVE_BOUNDED" = WAVE_BOUNDED + ) + ), + "wave" = list( + "defaults" = list( + "x" = 0, + "y" = 0, + "size" = 1, + "offset" = 0, + "flags" = NONE + ), + "flags" = list( + "WAVE_SIDEWAYS" = WAVE_SIDEWAYS, + "WAVE_BOUNDED" = WAVE_BOUNDED + ) + ) +)) -// All of this ported from TG. -/atom/movable - var/list/filter_data // For handling persistent filters +#undef ICON_NOT_SET -/proc/cmp_filter_data_priority(list/A, list/B) - return A["priority"] - B["priority"] +//Helpers to generate lists for filter helpers +//This is the only practical way of writing these that actually produces sane lists +/proc/alpha_mask_filter(x, y, icon/icon, render_source, flags) + . = list("type" = "alpha") + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + if(!isnull(icon)) + .["icon"] = icon + if(!isnull(render_source)) + .["render_source"] = render_source + if(!isnull(flags)) + .["flags"] = flags -/atom/movable/proc/add_filter(filter_name, priority, list/params) +/proc/angular_blur_filter(x, y, size) + . = list("type" = "angular_blur") + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + if(!isnull(size)) + .["size"] = size + +/proc/color_matrix_filter(matrix/in_matrix, space) + . = list("type" = "color") + .["color"] = in_matrix + if(!isnull(space)) + .["space"] = space + +/proc/displacement_map_filter(icon, render_source, x, y, size = 32) + . = list("type" = "displace") + if(!isnull(icon)) + .["icon"] = icon + if(!isnull(render_source)) + .["render_source"] = render_source + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + if(!isnull(size)) + .["size"] = size + +/proc/drop_shadow_filter(x, y, size, offset, color) + . = list("type" = "drop_shadow") + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + if(!isnull(size)) + .["size"] = size + if(!isnull(offset)) + .["offset"] = offset + if(!isnull(color)) + .["color"] = color + +/proc/gauss_blur_filter(size) + . = list("type" = "blur") + if(!isnull(size)) + .["size"] = size + +/proc/layering_filter(icon, render_source, x, y, flags, color, transform, blend_mode) + . = list("type" = "layer") + if(!isnull(icon)) + .["icon"] = icon + if(!isnull(render_source)) + .["render_source"] = render_source + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + if(!isnull(color)) + .["color"] = color + if(!isnull(flags)) + .["flags"] = flags + if(!isnull(transform)) + .["transform"] = transform + if(!isnull(blend_mode)) + .["blend_mode"] = blend_mode + +/proc/motion_blur_filter(x, y) + . = list("type" = "motion_blur") + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + +/proc/outline_filter(size, color, flags) + . = list("type" = "outline") + if(!isnull(size)) + .["size"] = size + if(!isnull(color)) + .["color"] = color + if(!isnull(flags)) + .["flags"] = flags + +/proc/radial_blur_filter(size, x, y) + . = list("type" = "radial_blur") + if(!isnull(size)) + .["size"] = size + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + +/proc/rays_filter(size, color, offset, density, threshold, factor, x, y, flags) + . = list("type" = "rays") + if(!isnull(size)) + .["size"] = size + if(!isnull(color)) + .["color"] = color + if(!isnull(offset)) + .["offset"] = offset + if(!isnull(density)) + .["density"] = density + if(!isnull(threshold)) + .["threshold"] = threshold + if(!isnull(factor)) + .["factor"] = factor + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + if(!isnull(flags)) + .["flags"] = flags + +/proc/ripple_filter(radius, size, falloff, repeat, x, y, flags) + . = list("type" = "ripple") + if(!isnull(radius)) + .["radius"] = radius + if(!isnull(size)) + .["size"] = size + if(!isnull(falloff)) + .["falloff"] = falloff + if(!isnull(repeat)) + .["repeat"] = repeat + if(!isnull(flags)) + .["flags"] = flags + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + +/proc/wave_filter(x, y, size, offset, flags) + . = list("type" = "wave") + if(!isnull(size)) + .["size"] = size + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + if(!isnull(offset)) + .["offset"] = offset + if(!isnull(flags)) + .["flags"] = flags + +/atom/proc/add_filter(name,priority,list/params) LAZYINITLIST(filter_data) var/list/p = params.Copy() p["priority"] = priority - filter_data[filter_name] = p + filter_data[name] = p update_filters() -/atom/movable/proc/update_filters() +/atom/proc/update_filters() filters = null filter_data = sortTim(filter_data, /proc/cmp_filter_data_priority, TRUE) for(var/f in filter_data) @@ -22,15 +308,77 @@ var/list/arguments = data.Copy() arguments -= "priority" filters += filter(arglist(arguments)) + UNSETEMPTY(filter_data) -/atom/movable/proc/get_filter(filter_name) - if(filter_data && filter_data[filter_name]) - return filters[filter_data.Find(filter_name)] +/atom/proc/transition_filter(name, time, list/new_params, easing, loop) + var/filter = get_filter(name) + if(!filter) + return -// Polaris Extensions -/atom/movable/proc/remove_filter(filter_name) - var/thing = get_filter(filter_name) - if(thing) - LAZYREMOVE(filter_data, filter_name) - filters -= thing - update_filters() \ No newline at end of file + var/list/old_filter_data = filter_data[name] + + var/list/params = old_filter_data.Copy() + for(var/thing in new_params) + params[thing] = new_params[thing] + + animate(filter, new_params, time = time, easing = easing, loop = loop) + for(var/param in params) + filter_data[name][param] = params[param] + +/atom/proc/change_filter_priority(name, new_priority) + if(!filter_data || !filter_data[name]) + return + + filter_data[name]["priority"] = new_priority + update_filters() + +/obj/item/update_filters() + . = ..() + /* Will port this from TG + for(var/X in actions) + var/datum/action/A = X + A.UpdateButtonIcon() + */ + +/atom/proc/get_filter(name) + if(filter_data && filter_data[name]) + return filters[filter_data.Find(name)] + +/atom/proc/remove_filter(name_or_names) + if(!filter_data) + return + + var/list/names = islist(name_or_names) ? name_or_names : list(name_or_names) + + for(var/name in names) + if(filter_data[name]) + filter_data -= name + update_filters() + +/atom/proc/clear_filters() + filter_data = null + filters = null + +/proc/apply_wibbly_filters(atom/in_atom, length) + for(var/i in 1 to 7) + //This is a very baffling and strange way of doing this but I am just preserving old functionality + var/X + var/Y + var/rsq + do + X = 60*rand() - 30 + Y = 60*rand() - 30 + rsq = X*X + Y*Y + while(rsq<100 || rsq>900) // Yeah let's just loop infinitely due to bad luck what's the worst that could happen? + var/random_roll = rand() + in_atom.add_filter("wibbly-[i]", 5, wave_filter(x = X, y = Y, size = rand() * 2.5 + 0.5, offset = random_roll)) + var/filter = in_atom.get_filter("wibbly-[i]") + animate(filter, offset = random_roll, time = 0, loop = -1, flags = ANIMATION_PARALLEL) + animate(offset = random_roll - 1, time = rand() * 20 + 10) + +/proc/remove_wibbly_filters(atom/in_atom) + var/filter + for(var/i in 1 to 7) + filter = in_atom.get_filter("wibbly-[i]") + animate(filter) + in_atom.remove_filter("wibbly-[i]") diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index 076a0d740c2..c9fe06d47c1 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -355,7 +355,7 @@ facedir(direction) /obj/screen/click_catcher - name = "Darkness" + name = "" // Empty string names don't show up in context menu clicks icon = 'icons/mob/screen_gen.dmi' icon_state = "click_catcher" plane = CLICKCATCHER_PLANE diff --git a/code/_onclick/hud/ability_screen_objects.dm b/code/_onclick/hud/ability_screen_objects.dm index 23a29367c0b..cb500b4fe3a 100644 --- a/code/_onclick/hud/ability_screen_objects.dm +++ b/code/_onclick/hud/ability_screen_objects.dm @@ -218,7 +218,7 @@ // if((last_charge == spell.charge_counter || !handle_icon_updates) && !forced_update) // return //nothing to see here -// overlays -= spell.hud_state +// cut_overlay(spell.hud_state) // if(spell.charge_type == Sp_RECHARGE || spell.charge_type == Sp_CHARGES) // if(spell.charge_counter < spell.charge_max) @@ -228,27 +228,27 @@ // partial_charge.Crop(1, 1, partial_charge.Width(), round(partial_charge.Height() * spell.charge_counter / spell.charge_max)) // overlays += partial_charge // if(last_charged_icon) -// overlays -= last_charged_icon +// cut_overlay(last_charged_icon) // last_charged_icon = partial_charge // else if(last_charged_icon) -// overlays -= last_charged_icon +// cut_overlay(last_charged_icon) // last_charged_icon = null // else // icon_state = "[spell_base]_spell_ready" // if(last_charged_icon) -// overlays -= last_charged_icon +// cut_overlay(last_charged_icon) // else // icon_state = "[spell_base]_spell_ready" - overlays.Cut() + cut_overlays() icon_state = "[background_base_state]_spell_base" overlays += ability_icon_state // last_charge = spell.charge_counter -// overlays -= "silence" +// cut_overlay("silence") // if(spell.silenced) -// overlays += "silence" +// add_overlay("silence") /obj/screen/ability/Click() if(!usr) diff --git a/code/_onclick/hud/action.dm b/code/_onclick/hud/action.dm index 160413135b0..d725fb8064e 100644 --- a/code/_onclick/hud/action.dm +++ b/code/_onclick/hud/action.dm @@ -134,7 +134,7 @@ icon = owner.button_icon icon_state = owner.background_icon_state - overlays.Cut() + cut_overlays() var/image/img if(owner.action_type == AB_ITEM && owner.target) var/obj/item/I = owner.target @@ -143,7 +143,7 @@ img = image(owner.button_icon,src,owner.button_icon_state) img.pixel_x = 0 img.pixel_y = 0 - overlays += img + add_overlay(img) if(!owner.IsAvailable()) color = rgb(128,0,0,128) @@ -178,9 +178,9 @@ return /obj/screen/movable/action_button/hide_toggle/UpdateIcon() - overlays.Cut() + cut_overlays() var/image/img = image(icon,src,hidden?"show":"hide") - overlays += img + add_overlay(img) return //This is the proc used to update all the action buttons. Properly defined in /mob/living/ diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index ddd7ac5dcc6..38646ccbc33 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -5,25 +5,22 @@ condition ? overlay_fullscreen(screen_name, screen_type, arg) : clear_fullscreen(screen_name) /mob/proc/overlay_fullscreen(category, type, severity) - var/obj/screen/fullscreen/screen = screens[category] + var/obj/screen/fullscreen/screen = screens[category] + if (!screen || screen.type != type) + // needs to be recreated + clear_fullscreen(category, FALSE) + screens[category] = screen = new type() + else if ((!severity || severity == screen.severity) && (!client || screen.screen_loc != "CENTER-7,CENTER-7" || screen.view == client.view)) + // doesn't need to be updated + return screen - if(screen) - if(screen.type != type) - clear_fullscreen(category, FALSE) - screen = null - else if(!severity || severity == screen.severity) - return screen + screen.icon_state = "[initial(screen.icon_state)][severity]" + screen.severity = severity + if (client && screen.should_show_to(src)) + screen.update_for_view(client.view) + client.screen += screen - if(!screen) - screen = new type() - - screen.icon_state = "[initial(screen.icon_state)][severity]" - screen.severity = severity - - screens[category] = screen - if(client && stat != DEAD) - client.screen += screen - return screen + return screen /mob/proc/clear_fullscreen(category, animated = 10) var/obj/screen/fullscreen/screen = screens[category] @@ -64,13 +61,26 @@ screen_loc = "CENTER-7,CENTER-7" layer = FULLSCREEN_LAYER plane = PLANE_FULLSCREEN - mouse_opacity = 0 + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + var/view = 7 var/severity = 0 + var/show_when_dead = FALSE /obj/screen/fullscreen/Destroy() severity = 0 return ..() +/obj/screen/fullscreen/proc/update_for_view(client_view) + if (screen_loc == "CENTER-7,CENTER-7" && view != client_view) + var/list/actualview = getviewsize(client_view) + view = client_view + transform = matrix(actualview[1]/15, 0, 0, 0, actualview[2]/15, 0) + +/obj/screen/fullscreen/proc/should_show_to(mob/mymob) + if(!show_when_dead && mymob.stat == DEAD) + return FALSE + return TRUE + /obj/screen/fullscreen/brute icon_state = "brutedamageoverlay" layer = DAMAGE_LAYER @@ -123,3 +133,21 @@ /obj/screen/fullscreen/fishbed icon_state = "fishbed" + +/obj/screen/fullscreen/lighting_backdrop + icon = 'icons/mob/screen_gen.dmi' + icon_state = "flash" + transform = matrix(200, 0, 0, 0, 200, 0) + plane = PLANE_LIGHTING + blend_mode = BLEND_OVERLAY + show_when_dead = TRUE + +//Provides darkness to the back of the lighting plane +/obj/screen/fullscreen/lighting_backdrop/lit + invisibility = INVISIBILITY_LIGHTING + layer = BACKGROUND_LAYER+21 + color = "#000" + +//Provides whiteness in case you don't see lights so everything is still visible +/obj/screen/fullscreen/lighting_backdrop/unlit + layer = BACKGROUND_LAYER+20 diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index 22e8e459fc5..45c94e9fcfd 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -291,8 +291,8 @@ zone_sel.icon = HUD.ui_style zone_sel.color = HUD.ui_color zone_sel.alpha = HUD.ui_alpha - zone_sel.overlays.Cut() - zone_sel.overlays += image('icons/mob/zone_sel.dmi', "[zone_sel.selecting]") + zone_sel.cut_overlays() + zone_sel.add_overlay(image('icons/mob/zone_sel.dmi', "[zone_sel.selecting]")) hud_elements |= zone_sel //Handle the gun settings buttons diff --git a/code/_onclick/hud/picture_in_picture.dm b/code/_onclick/hud/picture_in_picture.dm index 3df659a6873..4f9450db289 100644 --- a/code/_onclick/hud/picture_in_picture.dm +++ b/code/_onclick/hud/picture_in_picture.dm @@ -139,7 +139,7 @@ y_off = -height * world.icon_size - 16 - overlays.Cut() + cut_overlays() add_background() add_buttons() if(do_refresh) diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index 95ff6e1104f..22ea9bf5628 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -141,8 +141,8 @@ var/obj/screen/robot_inventory zone_sel = new /obj/screen/zone_sel() zone_sel.icon = HUD.ui_style zone_sel.alpha = HUD.ui_alpha - zone_sel.overlays.Cut() - zone_sel.overlays += image('icons/mob/zone_sel.dmi', "[zone_sel.selecting]") + zone_sel.cut_overlays() + zone_sel.add_overlay(image('icons/mob/zone_sel.dmi', "[zone_sel.selecting]")) //Handle the gun settings buttons gun_setting_icon = new /obj/screen/gun/mode(null) diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index f3568b3e40a..06b51def249 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -602,11 +602,11 @@ if(!handcuff_overlay) var/state = (hud.l_hand_hud_object == src) ? "l_hand_hud_handcuffs" : "r_hand_hud_handcuffs" handcuff_overlay = image("icon"='icons/mob/screen_gen.dmi', "icon_state"=state) - overlays.Cut() + cut_overlays() if(hud.mymob && iscarbon(hud.mymob)) var/mob/living/carbon/C = hud.mymob if(C.handcuffed) - overlays |= handcuff_overlay + add_overlay(handcuff_overlay) // PIP stuff /obj/screen/component_button @@ -630,6 +630,13 @@ return ..() // Background 'floor' +/obj/screen/setup_preview/pm_helper + icon = null + icon_state = null + appearance_flags = PLANE_MASTER + plane = PLANE_EMISSIVE + alpha = 0 + /obj/screen/setup_preview/bg mouse_over_pointer = MOUSE_HAND_POINTER @@ -711,7 +718,7 @@ var/obj/item/device/mapping_unit/owner var/obj/screen/mapper/extras_holder/extras_holder -/obj/screen/movable/mapper_holder/New(newloc, newowner) +/obj/screen/movable/mapper_holder/Initialize(mapload, newowner) owner = newowner mask_full = new(src) // Full white square mask @@ -849,15 +856,15 @@ /obj/screen/mapper/powbutton/Click() if(!usr.checkClickCooldown()) - return 1 + return TRUE if(usr.stat || usr.paralysis || usr.stunned || usr.weakened) - return 1 + return TRUE if(istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech - return 1 + return TRUE parent.powerClick() flick("powClick",src) usr << get_sfx("button") - return 1 + return TRUE /obj/screen/mapper/mapbutton icon = 'icons/effects/gpshud.dmi' @@ -867,15 +874,15 @@ /obj/screen/mapper/mapbutton/Click() if(!usr.checkClickCooldown()) - return 1 + return TRUE if(usr.stat || usr.paralysis || usr.stunned || usr.weakened) - return 1 + return TRUE if(istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech - return 1 + return TRUE parent.mapClick() flick("mapClick",src) usr << get_sfx("button") - return 1 + return TRUE // Markers are 16x16, people have apparently settled on centering them on the 8,8 pixel /obj/screen/mapper/marker diff --git a/code/_onclick/hud/spell_screen_objects.dm b/code/_onclick/hud/spell_screen_objects.dm index 92d9487401b..1215218ebe1 100644 --- a/code/_onclick/hud/spell_screen_objects.dm +++ b/code/_onclick/hud/spell_screen_objects.dm @@ -181,7 +181,7 @@ if((last_charge == spell.charge_counter || !handle_icon_updates) && !forced_update) return //nothing to see here - overlays -= spell.hud_state + cut_overlay(spell.hud_state) if(spell.charge_type == Sp_RECHARGE || spell.charge_type == Sp_CHARGES) if(spell.charge_counter < spell.charge_max) @@ -191,23 +191,23 @@ partial_charge.Crop(1, 1, partial_charge.Width(), round(partial_charge.Height() * spell.charge_counter / spell.charge_max)) overlays += partial_charge if(last_charged_icon) - overlays -= last_charged_icon + cut_overlay(last_charged_icon) last_charged_icon = partial_charge else if(last_charged_icon) - overlays -= last_charged_icon + cut_overlay(last_charged_icon) last_charged_icon = null else icon_state = "[spell_base]_spell_ready" if(last_charged_icon) - overlays -= last_charged_icon + cut_overlay(last_charged_icon) else icon_state = "[spell_base]_spell_ready" - overlays += spell.hud_state + add_overlay(spell.hud_state) last_charge = spell.charge_counter - overlays -= "silence" + cut_overlay("silence") if(spell.silenced) overlays += "silence" diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index bb31527126b..bf1b337e770 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -41,11 +41,6 @@ avoid code duplication. This includes items that may sometimes act as a standard return TRUE return FALSE -/atom/movable/attackby(obj/item/W, mob/user, var/attack_modifier, var/click_parameters) - . = ..() - if(!. && !(W.flags & NOBLUDGEON)) - visible_message("[src] has been hit by [user] with [W].") - /mob/living/attackby(obj/item/I, mob/user, var/attack_modifier, var/click_parameters) if(!ismob(user)) return 0 diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm index 4398dbf7e60..049db78c3af 100644 --- a/code/_onclick/telekinesis.dm +++ b/code/_onclick/telekinesis.dm @@ -163,7 +163,7 @@ var/const/tk_maxrange = 15 return /obj/item/tk_grab/update_icon() - overlays.Cut() + cut_overlays() if(focus && focus.icon && focus.icon_state) - overlays += icon(focus.icon,focus.icon_state) + add_overlay(icon(focus.icon, focus.icon_state)) return diff --git a/code/controllers/subsystems/air.dm b/code/controllers/subsystems/air.dm index 548e0bdb5c4..fa091ca5257 100644 --- a/code/controllers/subsystems/air.dm +++ b/code/controllers/subsystems/air.dm @@ -57,9 +57,44 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun if(active_edges.len) var/list/edge_log = list() for(var/connection_edge/E in active_edges) + + var/a_temp = E.A.air.temperature + var/a_moles = E.A.air.total_moles + var/a_vol = E.A.air.volume + var/a_gas = "" + for(var/gas in E.A.air.gas) + a_gas += "[gas]=[E.A.air.gas[gas]]" + + var/b_temp + var/b_moles + var/b_vol + var/b_gas = "" + + // Two zones mixing + if(istype(E, /connection_edge/zone)) + var/connection_edge/zone/Z = E + b_temp = Z.B.air.temperature + b_moles = Z.B.air.total_moles + b_vol = Z.B.air.volume + for(var/gas in Z.B.air.gas) + b_gas += "[gas]=[Z.B.air.gas[gas]]" + + // Zone and unsimulated turfs mixing + if(istype(E, /connection_edge/unsimulated)) + var/connection_edge/unsimulated/U = E + b_temp = U.B.temperature + b_moles = "Unsim" + b_vol = "Unsim" + for(var/gas in U.air.gas) + b_gas += "[gas]=[U.air.gas[gas]]" + edge_log += "Active Edge [E] ([E.type])" + edge_log += "Edge side A: T:[a_temp], Mol:[a_moles], Vol:[a_vol], Gas:[a_gas]" + edge_log += "Edge side B: T:[b_temp], Mol:[b_moles], Vol:[b_vol], Gas:[b_gas]" + for(var/turf/T in E.connecting_turfs) edge_log += "+--- Connecting Turf [T] ([T.type]) @ [T.x], [T.y], [T.z] ([T.loc])" + log_debug("Active Edges on ZAS Startup\n" + edge_log.Join("\n")) startup_active_edge_log = edge_log.Copy() @@ -124,7 +159,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun T.post_update_air_properties() T.needs_air_update = 0 #ifdef ZASDBG - T.overlays -= mark + T.cut_overlay(mark) #endif if(MC_TICK_CHECK) return @@ -139,7 +174,7 @@ Total Unsimulated Turfs: [world.maxx*world.maxy*world.maxz - simulated_turf_coun T.post_update_air_properties() T.needs_air_update = 0 #ifdef ZASDBG - T.overlays -= mark + T.cut_overlay(mark) #endif if(MC_TICK_CHECK) return diff --git a/code/controllers/subsystems/lighting.dm b/code/controllers/subsystems/lighting.dm index 5c7b15d8985..f851e3edf2d 100644 --- a/code/controllers/subsystems/lighting.dm +++ b/code/controllers/subsystems/lighting.dm @@ -1,171 +1,91 @@ -/* -** Lighting Subsystem - Process the lighting! Do it! -*/ - -#define SSLIGHTING_STAGE_LIGHTS 1 -#define SSLIGHTING_STAGE_CORNERS 2 -#define SSLIGHTING_STAGE_OVERLAYS 3 -#define SSLIGHTING_STAGE_DONE 4 -// This subsystem's fire() method also gets called once during Master.Initialize(). -// During this fire we need to use CHECK_TICK to sleep and continue, but in all other fires we need to use MC_CHECK_TICK to pause and return. -// This leads us to a rather annoying little tidbit of code that I have stuffed into this macro so I don't have to see it. -#define DUAL_TICK_CHECK if (init_tick_checks) { CHECK_TICK; } else if (MC_TICK_CHECK) { return; } - -// Globals -/var/lighting_overlays_initialised = FALSE -/var/list/lighting_update_lights = list() // List of lighting sources queued for update. -/var/list/lighting_update_corners = list() // List of lighting corners queued for update. -/var/list/lighting_update_overlays = list() // List of lighting overlays queued for update. - SUBSYSTEM_DEF(lighting) name = "Lighting" - wait = 2 // Ticks, not deciseconds + wait = 2 init_order = INIT_ORDER_LIGHTING flags = SS_TICKER + var/static/list/sources_queue = list() // List of lighting sources queued for update. + var/static/list/corners_queue = list() // List of lighting corners queued for update. + var/static/list/objects_queue = list() // List of lighting objects queued for update. - var/list/currentrun = list() - var/stage = null - - var/cost_lights = 0 - var/cost_corners = 0 - var/cost_overlays = 0 - -/datum/controller/subsystem/lighting/Initialize(timeofday) - if(!lighting_overlays_initialised) - // TODO - TG initializes starlight here. - create_all_lighting_overlays() - lighting_overlays_initialised = TRUE - - // Pre-process lighting once before the round starts. - internal_process_lights(FALSE, TRUE) - internal_process_corners(FALSE, TRUE) - internal_process_overlays(FALSE, TRUE) +/datum/controller/subsystem/lighting/stat_entry(msg) + msg = "L:[length(sources_queue)]|C:[length(corners_queue)]|O:[length(objects_queue)]" return ..() -/datum/controller/subsystem/lighting/fire(resumed = FALSE) - var/timer - if(!resumed) - // Santity checks to make sure we don't somehow have items left over from last cycle - // Or somehow didn't finish all the steps from last cycle - if(LAZYLEN(currentrun) || stage) - log_and_message_admins("SSlighting: Was told to start a new run, but the previous run wasn't finished! currentrun.len=[currentrun.len], stage=[stage]") - resumed = TRUE - else - stage = SSLIGHTING_STAGE_LIGHTS // Start with Step 1 of course - if(stage == SSLIGHTING_STAGE_LIGHTS) - timer = TICK_USAGE - internal_process_lights(resumed) - cost_lights = MC_AVERAGE(cost_lights, TICK_DELTA_TO_MS(TICK_USAGE - timer)) - if(state != SS_RUNNING) - return - resumed = 0 - stage = SSLIGHTING_STAGE_CORNERS +/datum/controller/subsystem/lighting/Initialize(timeofday) + if(!subsystem_initialized) + if (config.starlight) + for(var/area/A in world) + if (A.dynamic_lighting == DYNAMIC_LIGHTING_IFSTARLIGHT) + A.luminosity = 0 - if(stage == SSLIGHTING_STAGE_CORNERS) - timer = TICK_USAGE - internal_process_corners(resumed) - cost_corners = MC_AVERAGE(cost_corners, TICK_DELTA_TO_MS(TICK_USAGE - timer)) - if(state != SS_RUNNING) - return - resumed = 0 - stage = SSLIGHTING_STAGE_OVERLAYS + subsystem_initialized = TRUE + create_all_lighting_objects() - if(stage == SSLIGHTING_STAGE_OVERLAYS) - timer = TICK_USAGE - internal_process_overlays(resumed) - cost_overlays = MC_AVERAGE(cost_overlays, TICK_DELTA_TO_MS(TICK_USAGE - timer)) - if(state != SS_RUNNING) - return - resumed = 0 - stage = SSLIGHTING_STAGE_DONE + fire(FALSE, TRUE) - // Okay, we're done! Woo! Got thru a whole air_master cycle! - if(LAZYLEN(currentrun) || stage != SSLIGHTING_STAGE_DONE) - log_and_message_admins("SSlighting: Was not able to complete a full lighting cycle despite reaching the end of fire(). This shouldn't happen.") - else - currentrun = null - stage = null + return ..() -/datum/controller/subsystem/lighting/proc/internal_process_lights(resumed = FALSE, init_tick_checks = FALSE) - if (!resumed) - // We swap out the lists so any additions to the global list during a pause don't make things wierd. - src.currentrun = global.lighting_update_lights - global.lighting_update_lights = list() +/datum/controller/subsystem/lighting/fire(resumed, init_tick_checks) + MC_SPLIT_TICK_INIT(3) + if(!init_tick_checks) + MC_SPLIT_TICK + var/list/queue = sources_queue + var/i = 0 + for (i in 1 to length(queue)) + var/datum/light_source/L = queue[i] - //cache for sanic speed (lists are references anyways) - var/list/currentrun = src.currentrun - while(currentrun.len) - var/datum/light_source/L = currentrun[currentrun.len] - currentrun.len-- + L.update_corners() - if(!L) continue - if(L.check() || L.destroyed || L.force_update) - L.remove_lum() - if(!L.destroyed) - L.apply_lum() + L.needs_update = LIGHTING_NO_UPDATE - else if(L.vis_update) //We smartly update only tiles that became (in) visible to use. - L.smart_vis_update() + if(init_tick_checks) + CHECK_TICK + else if (MC_TICK_CHECK) + break + if (i) + queue.Cut(1, i+1) + i = 0 - L.vis_update = FALSE - L.force_update = FALSE - L.needs_update = FALSE + if(!init_tick_checks) + MC_SPLIT_TICK - DUAL_TICK_CHECK + queue = corners_queue + for (i in 1 to length(queue)) + var/datum/lighting_corner/C = queue[i] -/datum/controller/subsystem/lighting/proc/internal_process_corners(resumed = FALSE, init_tick_checks = FALSE) - if (!resumed) - // We swap out the lists so any additions to the global list during a pause don't make things wierd. - src.currentrun = global.lighting_update_corners - global.lighting_update_corners = list() + C.needs_update = FALSE //update_objects() can call qdel if the corner is storing no data + C.update_objects() + + if(init_tick_checks) + CHECK_TICK + else if (MC_TICK_CHECK) + break + if (i) + queue.Cut(1, i+1) + i = 0 - //cache for sanic speed (lists are references anyways) - var/list/currentrun = src.currentrun - while(currentrun.len) - var/datum/lighting_corner/C = currentrun[currentrun.len] - currentrun.len-- - if(!C) continue - C.update_overlays() - C.needs_update = FALSE + if(!init_tick_checks) + MC_SPLIT_TICK - DUAL_TICK_CHECK + queue = objects_queue + for (i in 1 to length(queue)) + var/datum/lighting_object/O = queue[i] -/datum/controller/subsystem/lighting/proc/internal_process_overlays(resumed = FALSE, init_tick_checks = FALSE) - if (!resumed) - // We swap out the lists so any additions to the global list during a pause don't make things wierd. - src.currentrun = global.lighting_update_overlays - global.lighting_update_overlays = list() + if (QDELETED(O)) + continue - //cache for sanic speed (lists are references anyways) - var/list/currentrun = src.currentrun - while(currentrun.len) - var/atom/movable/lighting_overlay/O = currentrun[currentrun.len] - currentrun.len-- - - if(!O) continue - O.update_overlay() + O.update() O.needs_update = FALSE + if(init_tick_checks) + CHECK_TICK + else if (MC_TICK_CHECK) + break + if (i) + queue.Cut(1, i+1) - DUAL_TICK_CHECK -/datum/controller/subsystem/lighting/stat_entry(msg_prefix) - var/list/msg = list(msg_prefix) - msg += "T:{" - msg += "S [total_lighting_sources] | " - msg += "C [total_lighting_corners] | " - msg += "O [total_lighting_overlays]" - msg += "}" - msg += "C:{" - msg += "S [round(cost_lights, 1)] | " - msg += "C [round(cost_corners, 1)] | " - msg += "O [round(cost_overlays, 1)]" - msg += "}" - ..(msg.Join()) - -#undef DUAL_TICK_CHECK -#undef SSLIGHTING_STAGE_LIGHTS -#undef SSLIGHTING_STAGE_CORNERS -#undef SSLIGHTING_STAGE_OVERLAYS -#undef SSLIGHTING_STAGE_STATS \ No newline at end of file +/datum/controller/subsystem/lighting/Recover() + subsystem_initialized = SSlighting.subsystem_initialized + ..() diff --git a/code/controllers/subsystems/overlays.dm b/code/controllers/subsystems/overlays.dm index 77c9d3ab94a..16662cc042e 100644 --- a/code/controllers/subsystems/overlays.dm +++ b/code/controllers/subsystems/overlays.dm @@ -224,6 +224,32 @@ var/global/image/appearance_bro = new() // Temporarily super-global because of B else if(cut_old) cut_overlays() +/** + * Returns a list of overlays that the target atom has + * + * @param priority If true, returns priority overlays as well + * @param special If true, returns special overlays like emissives and em_blockers + */ +/proc/get_overlays(atom/other, priority, special) + var/list/including = list() + if(!other) + return including + + for(var/image/I as anything in other.our_overlays) + if(!special && I.plane > 0) + continue + including += I + + if(!priority) + return including + + for(var/image/I as anything in other.priority_overlays) + if(!special && I.plane > 0) + continue + including += I + + return including + #undef NOT_QUEUED_ALREADY #undef QUEUE_FOR_COMPILE diff --git a/code/controllers/subsystems/planets.dm b/code/controllers/subsystems/planets.dm index d1c2de2410c..c9a4a2db43c 100644 --- a/code/controllers/subsystems/planets.dm +++ b/code/controllers/subsystems/planets.dm @@ -44,9 +44,8 @@ SUBSYSTEM_DEF(planets) P.planet_walls += T else if(istype(T, /turf/simulated) && T.outdoors) P.planet_floors += T - T.vis_contents |= P.weather_holder.visuals - T.vis_contents |= P.weather_holder.special_visuals - + P.weather_holder.apply_to_turf(T) + P.sun_holder.apply_to_turf(T) /datum/controller/subsystem/planets/proc/removeTurf(var/turf/T,var/is_edge) if(z_to_planet.len >= T.z) @@ -57,8 +56,8 @@ SUBSYSTEM_DEF(planets) P.planet_walls -= T else P.planet_floors -= T - T.vis_contents -= P.weather_holder.visuals - T.vis_contents -= P.weather_holder.special_visuals + P.weather_holder.remove_from_turf(T) + P.sun_holder.remove_from_turf(T) /datum/controller/subsystem/planets/fire(resumed = 0) @@ -72,7 +71,8 @@ SUBSYSTEM_DEF(planets) updateSunlight(P) if(MC_TICK_CHECK) return - + + #ifndef UNIT_TEST // Don't be updating temperatures and such during unit tests var/list/needs_temp_update = src.needs_temp_update while(needs_temp_update.len) var/datum/planet/P = needs_temp_update[needs_temp_update.len] @@ -80,6 +80,7 @@ SUBSYSTEM_DEF(planets) updateTemp(P) if(MC_TICK_CHECK) return + #endif var/list/currentrun = src.currentrun while(currentrun.len) @@ -102,39 +103,11 @@ SUBSYSTEM_DEF(planets) return /datum/controller/subsystem/planets/proc/updateSunlight(var/datum/planet/P) - // Remove old value from corners - var/list/sunlit_corners = P.sunlit_corners - var/old_lum_r = -P.sun["lum_r"] - var/old_lum_g = -P.sun["lum_g"] - var/old_lum_b = -P.sun["lum_b"] - if(old_lum_r || old_lum_g || old_lum_b) - for(var/C in sunlit_corners) - var/datum/lighting_corner/LC = C - LC.update_lumcount(old_lum_r, old_lum_g, old_lum_b) - CHECK_TICK - sunlit_corners.Cut() - - // Calculate new values to apply var/new_brightness = P.sun["brightness"] + P.sun_holder.update_brightness(new_brightness) + var/new_color = P.sun["color"] - var/lum_r = new_brightness * GetRedPart (new_color) / 255 - var/lum_g = new_brightness * GetGreenPart(new_color) / 255 - var/lum_b = new_brightness * GetBluePart (new_color) / 255 - var/static/update_gen = -1 // Used to prevent double-processing corners. Otherwise would happen when looping over adjacent turfs. - for(var/turf/simulated/T as anything in P.planet_floors) - if(!T.lighting_corners_initialised) - T.generate_missing_corners() - for(var/C in T.get_corners()) - var/datum/lighting_corner/LC = C - if(LC.update_gen != update_gen && LC.active) - sunlit_corners += LC - LC.update_gen = update_gen - LC.update_lumcount(lum_r, lum_g, lum_b) - CHECK_TICK - update_gen-- - P.sun["lum_r"] = lum_r - P.sun["lum_g"] = lum_g - P.sun["lum_b"] = lum_b + P.sun_holder.update_color(new_color) /datum/controller/subsystem/planets/proc/updateTemp(var/datum/planet/P) //Set new temperatures diff --git a/code/controllers/subsystems/skybox.dm b/code/controllers/subsystems/skybox.dm index 6befac0b605..05053fbb0f7 100644 --- a/code/controllers/subsystems/skybox.dm +++ b/code/controllers/subsystems/skybox.dm @@ -37,7 +37,8 @@ SUBSYSTEM_DEF(skybox) im.alpha = 128 //80 im.blend_mode = BLEND_ADD - MA.overlays = list(im) + MA.cut_overlays() + MA.add_overlay(im) dust_cache["[i]"] = MA @@ -48,7 +49,8 @@ SUBSYSTEM_DEF(skybox) var/image/im = image('icons/turf/space_dust_transit.dmi', "speedspace_ns_[i]") im.plane = DUST_PLANE im.blend_mode = BLEND_ADD - MA.overlays = list(im) + MA.cut_overlays() + MA.add_overlay(im) speedspace_cache["NS_[i]"] = MA // EAST/WEST MA = new(normal_space) @@ -56,7 +58,8 @@ SUBSYSTEM_DEF(skybox) im.plane = DUST_PLANE im.blend_mode = BLEND_ADD - MA.overlays = list(im) + MA.cut_overlays() + MA.add_overlay(im) speedspace_cache["EW_[i]"] = MA diff --git a/code/controllers/subsystems/tgui.dm b/code/controllers/subsystems/tgui.dm index e94830a5f03..a0d96cf80c1 100644 --- a/code/controllers/subsystems/tgui.dm +++ b/code/controllers/subsystems/tgui.dm @@ -22,7 +22,7 @@ SUBSYSTEM_DEF(tgui) var/basehtml /datum/controller/subsystem/tgui/PreInit() - basehtml = file2text('tgui/packages/tgui/public/tgui.html') + basehtml = file2text('tgui/public/tgui.html') /datum/controller/subsystem/tgui/Shutdown() close_all_uis() diff --git a/code/controllers/subsystems/vis_overlays.dm b/code/controllers/subsystems/vis_overlays.dm new file mode 100644 index 00000000000..0806e4c954d --- /dev/null +++ b/code/controllers/subsystems/vis_overlays.dm @@ -0,0 +1,77 @@ +SUBSYSTEM_DEF(vis_overlays) + name = "Vis contents overlays" + wait = 1 MINUTES + priority = FIRE_PRIORITY_VIS + init_order = INIT_ORDER_VIS + + var/list/vis_overlay_cache + var/list/currentrun + +/datum/controller/subsystem/vis_overlays/Initialize() + vis_overlay_cache = list() + return ..() + +/datum/controller/subsystem/vis_overlays/fire(resumed = FALSE) + if(!resumed) + currentrun = vis_overlay_cache.Copy() + var/list/current_run = currentrun + + while(current_run.len) + var/key = current_run[current_run.len] + var/obj/effect/overlay/vis/overlay = current_run[key] + current_run.len-- + if(!overlay.unused && !length(overlay.vis_locs)) + overlay.unused = world.time + else if(overlay.unused && overlay.unused + overlay.cache_expiration < world.time) + vis_overlay_cache -= key + qdel(overlay) + if(MC_TICK_CHECK) + return + +//the "thing" var can be anything with vis_contents which includes images - in the future someone should totally allow vis overlays to be passed in as an arg instead of all this bullshit +/datum/controller/subsystem/vis_overlays/proc/add_vis_overlay(atom/movable/thing, icon, iconstate, layer, plane, dir, alpha = 255, add_appearance_flags = NONE, unique = FALSE) + var/obj/effect/overlay/vis/overlay + if(!unique) + . = "[icon]|[iconstate]|[layer]|[plane]|[dir]|[alpha]|[add_appearance_flags]" + overlay = vis_overlay_cache[.] + if(!overlay) + overlay = _create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags) + vis_overlay_cache[.] = overlay + else + overlay.unused = 0 + else + overlay = _create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags) + overlay.cache_expiration = -1 + var/cache_id = "\ref[overlay]@{[world.time]}" + vis_overlay_cache[cache_id] = overlay + . = overlay + thing.vis_contents += overlay + + if(!isatom(thing)) + return overlay + + if(!thing.managed_vis_overlays) + thing.managed_vis_overlays = list(overlay) + else + thing.managed_vis_overlays += overlay + return overlay + +/datum/controller/subsystem/vis_overlays/proc/_create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags) + var/obj/effect/overlay/vis/overlay = new + overlay.icon = icon + overlay.icon_state = iconstate + overlay.layer = layer + overlay.plane = plane + overlay.dir = dir + overlay.alpha = alpha + overlay.appearance_flags |= add_appearance_flags + return overlay + + +/datum/controller/subsystem/vis_overlays/proc/remove_vis_overlay(atom/movable/thing, list/overlays) + thing.vis_contents -= overlays + if(!isatom(thing)) + return + thing.managed_vis_overlays -= overlays + if(!length(thing.managed_vis_overlays)) + thing.managed_vis_overlays = null diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index 58a66923c42..4a9c3b48a7c 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -4,6 +4,7 @@ // Clickable stat() button. /obj/effect/statclick name = "Initializing..." + blocks_emissive = FALSE var/target /obj/effect/statclick/New(loc, text, target) //Don't port this to Initialize it's too critical diff --git a/code/datums/browser.dm b/code/datums/browser.dm index e78833c9580..18472c854cb 100644 --- a/code/datums/browser.dm +++ b/code/datums/browser.dm @@ -306,13 +306,9 @@ var/output = {"