diff --git a/aurorastation.dme b/aurorastation.dme index f36a13e5db0..0d59ddf337d 100644 --- a/aurorastation.dme +++ b/aurorastation.dme @@ -57,7 +57,6 @@ #include "code\__DEFINES\drinks.dm" #include "code\__DEFINES\dview.dm" #include "code\__DEFINES\economy.dm" -#include "code\__DEFINES\emissives.dm" #include "code\__DEFINES\emitter.dm" #include "code\__DEFINES\empulse.dm" #include "code\__DEFINES\evacuation.dm" @@ -331,7 +330,6 @@ #include "code\controllers\subsystems\ai_obfuscation.dm" #include "code\controllers\subsystems\air.dm" #include "code\controllers\subsystems\alarm.dm" -#include "code\controllers\subsystems\ao.dm" #include "code\controllers\subsystems\arrivals.dm" #include "code\controllers\subsystems\asset_loading.dm" #include "code\controllers\subsystems\assets.dm" @@ -476,6 +474,7 @@ #include "code\datums\components\leanable.dm" #include "code\datums\components\local_network.dm" #include "code\datums\components\orbiter.dm" +#include "code\datums\components\overlay_lighting.dm" #include "code\datums\components\armor\armor.dm" #include "code\datums\components\base_name\base_name.dm" #include "code\datums\components\eye\_eye.dm" @@ -490,6 +489,7 @@ #include "code\datums\elements\_element.dm" #include "code\datums\elements\connect_loc.dm" #include "code\datums\elements\empprotection.dm" +#include "code\datums\elements\light_blocking.dm" #include "code\datums\elements\temporary.dm" #include "code\datums\ert\corporate.dm" #include "code\datums\ert\outsider.dm" @@ -1687,8 +1687,6 @@ #include "code\modules\alarm\fire_alarm.dm" #include "code\modules\alarm\motion_alarm.dm" #include "code\modules\alarm\power_alarm.dm" -#include "code\modules\ambient_occlusion\ao_turf.dm" -#include "code\modules\ambient_occlusion\ao_verbs.dm" #include "code\modules\assembly\assembly.dm" #include "code\modules\assembly\bomb.dm" #include "code\modules\assembly\helpers.dm" @@ -2504,19 +2502,21 @@ #include "code\modules\law\laws\med_severity.dm" #include "code\modules\library\lib_items.dm" #include "code\modules\library\lib_machines.dm" -#include "code\modules\lighting\__lighting_docs.dm" -#include "code\modules\lighting\_lighting_defs.dm" +#include "code\modules\lighting\emissive_blocker.dm" #include "code\modules\lighting\lighting_area.dm" #include "code\modules\lighting\lighting_atom.dm" -#include "code\modules\lighting\lighting_corner.dm" -#include "code\modules\lighting\lighting_overlay.dm" -#include "code\modules\lighting\lighting_profiler.dm" -#include "code\modules\lighting\lighting_setup.dm" -#include "code\modules\lighting\lighting_source.dm" -#include "code\modules\lighting\lighting_source_sunlight.dm" #include "code\modules\lighting\lighting_turf.dm" -#include "code\modules\lighting\lighting_verbs.dm" -#include "code\modules\lighting\~lighting_undefs.dm" +#include "code\modules\lighting\lighting_mask\dynamic_lighting_source.dm" +#include "code\modules\lighting\lighting_mask\lighting_mask.dm" +#include "code\modules\lighting\lighting_mask\lighting_mask_holder.dm" +#include "code\modules\lighting\lighting_mask\shadow_calculator.dm" +#include "code\modules\lighting\lighting_static\static_lighting_area.dm" +#include "code\modules\lighting\lighting_static\static_lighting_atom.dm" +#include "code\modules\lighting\lighting_static\static_lighting_corner.dm" +#include "code\modules\lighting\lighting_static\static_lighting_object.dm" +#include "code\modules\lighting\lighting_static\static_lighting_setup.dm" +#include "code\modules\lighting\lighting_static\static_lighting_source.dm" +#include "code\modules\lighting\lighting_static\static_lighting_turf.dm" #include "code\modules\liquid\splash_simulation.dm" #include "code\modules\lock\key.dm" #include "code\modules\lock\lock.dm" @@ -2625,7 +2625,6 @@ #include "code\modules\mob\abstract\freelook\ai\update_triggers.dm" #include "code\modules\mob\abstract\freelook\blueprints\blueprints.dm" #include "code\modules\mob\abstract\ghost\ghost.dm" -#include "code\modules\mob\abstract\ghost\observer\login.dm" #include "code\modules\mob\abstract\ghost\observer\logout.dm" #include "code\modules\mob\abstract\ghost\observer\observer.dm" #include "code\modules\mob\abstract\ghost\observer\say.dm" @@ -3868,7 +3867,6 @@ #include "code\unit_tests\chemistry_tests.dm" #include "code\unit_tests\cooking_tests.dm" #include "code\unit_tests\create_and_destroy.dm" -#include "code\unit_tests\equipment_tests.dm" #include "code\unit_tests\foundation_tests.dm" #include "code\unit_tests\gamemode_tests.dm" #include "code\unit_tests\hydroponics_tests.dm" diff --git a/code/ZAS/Fire.dm b/code/ZAS/Fire.dm index c3dd7946134..6c926260c9d 100644 --- a/code/ZAS/Fire.dm +++ b/code/ZAS/Fire.dm @@ -161,11 +161,11 @@ If it gains pressure too slowly, it may leak or just rupture instead of explodin var/datum/gas_mixture/air_contents = my_tile.return_air() if(firelevel > 6) - set_light(9, FIRE_LIGHT_3, no_update = TRUE) // We set color later in the proc, that should trigger an update. + set_light(9, FIRE_LIGHT_3) // We set color later in the proc, that should trigger an update. else if(firelevel > 2.5) - set_light(7, FIRE_LIGHT_2, no_update = TRUE) + set_light(7, FIRE_LIGHT_2) else - set_light(5, FIRE_LIGHT_1, no_update = TRUE) + set_light(5, FIRE_LIGHT_1) air_contents.adjust_gas(GAS_CO2, firelevel * 0.07) diff --git a/code/__DEFINES/_macros.dm b/code/__DEFINES/_macros.dm index 7d8df104543..8ccae0598f6 100644 --- a/code/__DEFINES/_macros.dm +++ b/code/__DEFINES/_macros.dm @@ -40,6 +40,7 @@ #define isweakref(target) istype(target, /datum/weakref) #define isopenspace(A) istype(A, /turf/simulated/open) #define isatom(D) istype(D, /atom) +#define ismovableatom(A) (ismovable(A)) #define isdatum(target) istype(target, /datum) #define isitem(D) istype(D, /obj/item) #define islist(D) istype(D, /list) diff --git a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm index a6f77c71fdb..f5d03812dcd 100644 --- a/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm +++ b/code/__DEFINES/dcs/signals/signals_atom/signals_atom_main.dm @@ -23,6 +23,9 @@ ///from base of atom/has_gravity(): (turf/location, list/forced_gravities) #define COMSIG_ATOM_HAS_GRAVITY "atom_has_gravity" +///from base of atom/set_dir(): (old_dir, new_dir). Called before the direction changes. +#define COMSIG_ATOM_DIR_CHANGE "atom_dir_change" + ///called when an atom starts orbiting another atom: (atom) #define COMSIG_ATOM_ORBIT_BEGIN "atom_orbit_begin" ///called when an atom stops orbiting another atom: (atom) @@ -42,3 +45,20 @@ /// From /atom/proc/set_density(new_value) for when an atom changes density #define COMSIG_ATOM_DENSITY_CHANGED "atom_density_change" + +//from atom/set_light(): (l_range, l_power, l_color) +#define COMSIG_ATOM_SET_LIGHT "atom_set_light" + +///Called right before the atom changes the value of light_range to a different one, from base atom/set_light_range(): (new_range) +#define COMSIG_ATOM_SET_LIGHT_RANGE "atom_set_light_range" +///Called right before the atom changes the value of light_power to a different one, from base atom/set_light_power(): (new_power) +#define COMSIG_ATOM_SET_LIGHT_POWER "atom_set_light_power" +///Called right before the atom changes the value of light_color to a different one, from base atom/set_light_color(): (new_color) +#define COMSIG_ATOM_SET_LIGHT_COLOR "atom_set_light_color" +///Called right before the atom changes the value of light_on to a different one, from base atom/set_light_on(): (new_value) +#define COMSIG_ATOM_SET_LIGHT_ON "atom_set_light_on" +///Called right before the atom changes the value of light_flags to a different one, from base atom/set_light_flags(): (new_value) +#define COMSIG_ATOM_SET_LIGHT_FLAGS "atom_set_light_flags" + +///from base of atom/set_opacity(): (new_opacity) +#define COMSIG_ATOM_SET_OPACITY "atom_set_opacity" diff --git a/code/__DEFINES/emissives.dm b/code/__DEFINES/emissives.dm deleted file mode 100644 index b9311b81ed3..00000000000 --- a/code/__DEFINES/emissives.dm +++ /dev/null @@ -1,28 +0,0 @@ -// Emissive blockers -/// For anything that shouldn't block emissives. Small objects or translucent objects primarily -#define EMISSIVE_BLOCK_NONE 0 -/// 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 - -#define _EMISSIVE_COLOR(val) list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, val,val,val,0) -/// 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 _EMISSIVE_COLOR(1) -/// A globally cached version of [EMISSIVE_COLOR] for quick access. -GLOBAL_LIST_INIT(emissive_color, EMISSIVE_COLOR) - -#define _EM_BLOCK_COLOR(val) list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,val, 0,0,0,0) -/// 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 _EM_BLOCK_COLOR(1) -/// A globally 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 globally cached version of [EM_MASK_MATRIX] for quick access. -GLOBAL_LIST_INIT(em_mask_matrix, EM_MASK_MATRIX) - -/// A set of appearance flags applied to all emissive and emissive blocker overlays. -#define EMISSIVE_APPEARANCE_FLAGS (KEEP_APART|KEEP_TOGETHER|RESET_COLOR|NO_CLIENT_COLOR) diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index fdf4f4c766d..41bc149831e 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -12,7 +12,6 @@ // Movable flags. #define ZMM_IGNORE 1 //! Do not copy this movable. -#define ZMM_MANGLE_PLANES 2 //! Check this movable's overlays/underlays for explicit plane use and mangle for compatibility with Z-Mimic. If you're using emissive overlays, you probably should be using this flag. Expensive, only use if necessary. // Convenience flag. #define ZM_MIMIC_DEFAULTS (ZM_MIMIC_BELOW) @@ -115,3 +114,5 @@ GLOBAL_LIST_INIT(mimic_defines, list("ZM_MIMIC_BELOW", /// Can be used for surgery, giving the "You're not sure what you can do with this." message if no surgery is available. #define ITEM_FLAG_SURGERY FLAG(13) +///All the cardinal direction bitflags. +#define ALL_CARDINALS (NORTH|SOUTH|EAST|WEST) diff --git a/code/__DEFINES/global.dm b/code/__DEFINES/global.dm index 157df823171..92d332e0b6e 100644 --- a/code/__DEFINES/global.dm +++ b/code/__DEFINES/global.dm @@ -171,3 +171,5 @@ GLOBAL_LIST_INIT(department_funds, list( //List of exosuit tracking beacons, to save performance GLOBAL_LIST_EMPTY(exo_beacons) + +GLOBAL_VAR_INIT(minimum_exterior_lighting_alpha, 255) diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 54903e7ea00..aaeab50a661 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -78,3 +78,5 @@ #define isprojectile(A) istype(A, /obj/projectile) #define isbeam(A) istype(A, /obj/projectile/beam) #define isenergy(A) istype(A, /obj/projectile/energy) + +#define istransparentturf(A) (HAS_TRAIT(A, TURF_Z_TRANSPARENT_TRAIT)) diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 8f5c706d47e..ab11c972e6d 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -38,13 +38,11 @@ #define OPEN_SPACE_PLANE_END -70 #define OPENTURF_MAX_DEPTH 10 // The maxiumum number of planes deep we'll go before we just dump everything on the same plane. -#define HEAT_EFFECT_PLANE -4 -#define WARP_EFFECT_PLANE -3 - -#define BLACKNESS_PLANE 0 //Blackness plane as per DM documentation. +#define HEAT_EFFECT_PLANE -8 +#define WARP_EFFECT_PLANE -7 /// Game Plane, where most of the game objects reside -#define GAME_PLANE 1 +#define GAME_PLANE -6 #define PLATING_LAYER 1 //ABOVE PLATING #define HOLOMAP_LAYER 1.01 @@ -145,20 +143,34 @@ #define AREA_LAYER 999 /// Above Game Plane. For things which are above game objects, but below screen effects. -#define ABOVE_GAME_PLANE 2 +#define ABOVE_GAME_PLANE -5 -#define ROOF_PLANE 3 +#define ROOF_PLANE -4 -#define DISPLACEMENT_PLATE_RENDER_LAYER 4 +#define BLACKNESS_PLANE 0 //Blackness plane as per DM documentation. + +#define DISPLACEMENT_PLATE_RENDER_LAYER 1 #define DISPLACEMENT_PLATE_RENDER_TARGET "*DISPLACEMENT_PLATE_RENDER_TARGET" #define GHOST_PLANE 80 #define LIGHTING_PLANE 100 #define LIGHTING_LAYER 1 +#define EXTERIOR_LIGHTING_PLANE 101 +#define NVG_PLANE 110 #define BALLOON_CHAT_PLANE 110 +#define O_LIGHTING_VISUAL_PLANE 120 +#define O_LIGHTING_VISUAL_LAYER 16 +#define O_LIGHTING_VISUAL_RENDER_TARGET "O_LIGHT_VISUAL_PLANE" + +#define LIGHTING_PRIMARY_LAYER 15 //The layer for the main lights of the station +#define LIGHTING_PRIMARY_DIMMER_LAYER 15.1 //The layer that dims the main lights of the station +#define LIGHTING_SECONDARY_LAYER 16 //The colourful, usually small lights that go on top + +#define LIGHTING_SHADOW_LAYER 17 //Where the shadows happen + #define ABOVE_LIGHTING_PLANE 150 #define EYE_GLOW_LAYER 1 #define BEAM_PROJECTILE_LAYER 2 @@ -167,7 +179,7 @@ #define RUNECHAT_PLANE 501 -#define FULLSCREEN_PLANE 9 +#define FULLSCREEN_PLANE 900 #define FULLSCREEN_LAYER 1 #define DAMAGE_LAYER 2 #define IMPAIRED_LAYER 3 @@ -208,11 +220,16 @@ /// This plane masks out lighting, to create an "emissive" effect for e.g glowing screens in otherwise dark areas. #define EMISSIVE_PLANE 90 #define EMISSIVE_TARGET "*emissive" - /// The layer you should use when you -really- don't want an emissive overlay to be blocked. - #define EMISSIVE_LAYER_UNBLOCKABLE 9999 - /// The render target used by the emissive layer. #define EMISSIVE_RENDER_TARGET "*EMISSIVE_PLANE" +/// The layer you should use when you -really- don't want an emissive overlay to be blocked. +#define EMISSIVE_LAYER_UNBLOCKABLE 9999 + +#define LIGHTING_BACKPLANE_LAYER 14.5 + +#define LIGHTING_RENDER_TARGET "LIGHT_PLANE" + +#define SHADOW_RENDER_TARGET "SHADOW_RENDER_TARGET" #define DEFAULT_APPEARANCE_FLAGS (PIXEL_SCALE) diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm index 69a5fdb2ac6..9de84a857f4 100644 --- a/code/__DEFINES/lighting.dm +++ b/code/__DEFINES/lighting.dm @@ -1,73 +1,3 @@ -#define LIGHTING_INTERVAL 1 // Frequency, in 1/10ths of a second, of the lighting process. - -#define LIGHTING_HEIGHT 1 // height off the ground of light sources on the pseudo-z-axis, you should probably leave this alone -#define LIGHTING_Z_FACTOR 10 // Z diff is multiplied by this and LIGHTING_HEIGHT to get the final height of a light source. Affects how much darker A Z light gets with each level transitioned. -#define LIGHTING_ROUND_VALUE 1 / 200 //Value used to round lumcounts, values smaller than 1/255 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_ICON 'icons/effects/lighting_overlay.dmi' // icon used for lighting shading effects -#define LIGHTING_BASE_ICON_STATE "matrix" // icon_state used for normal color-matrix based lighting overlays. -#define LIGHTING_STATION_ICON_STATE "tubedefault" // icon_state used for lighting overlays that are just displaying standard station lighting. -#define LIGHTING_DARKNESS_ICON_STATE "black" // icon_state used for lighting overlays with no luminosity. -#define LIGHTING_TRANSPARENT_ICON_STATE "blank" - -#define LIGHTING_SOFT_THRESHOLD 0.001 // If the max of the lighting lumcounts of each spectrum drops below this, disable luminosity on the lighting overlays. -#define LIGHTING_BLOCKED_FACTOR 0.5 // How much the range of a directional light will be reduced while facing a wall. - -// If defined, instant updates will be used whenever server load permits. Otherwise queued updates are always used. -#define USE_INTELLIGENT_LIGHTING_UPDATES - -// If defined, lighting corners will 'bleed' luminosity to corners above them to simulate cross-Z lighting upwards. Downwards Z-lighting will continue to work with this disabled. -#define USE_CORNER_ZBLEED - -#define TURF_IS_DYNAMICALLY_LIT(T) (isturf(T) && T:dynamic_lighting && T:loc:dynamic_lighting) -// mostly identical to above, but doesn't make sure T is valid first. Should only be used by lighting code. -#define TURF_IS_DYNAMICALLY_LIT_UNSAFE(T) (T:dynamic_lighting && T:loc:dynamic_lighting) - -// If I were you I'd leave this alone. -#define LIGHTING_BASE_MATRIX \ - list \ - ( \ - 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 - -// Higher numbers override lower. -#define LIGHTING_NO_UPDATE 0 -#define LIGHTING_VIS_UPDATE 1 -#define LIGHTING_CHECK_UPDATE 2 -#define LIGHTING_FORCE_UPDATE 3 - -// This color of overlay is very common - most of the station is this color when lit fully. -// Tube lights are a bluish-white, so we can't just assume 1-1-1 is full-illumination. -#define LIGHTING_DEFAULT_TUBE_R 0.96 -#define LIGHTING_DEFAULT_TUBE_G 1 -#define LIGHTING_DEFAULT_TUBE_B 1 - //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) @@ -112,17 +42,11 @@ #define LIGHT_EMERGENCY_POWER_USE 0.2 //How much power emergency lights will consume per tick -// Some angle presets for directional lighting. -#define LIGHT_OMNI null -#define LIGHT_SEMI 180 -#define LIGHT_WIDE 90 -#define LIGHT_NARROW 45 - // Some brightness/range defines for objects. -#define L_WALLMOUNT_POWER 1.3 -#define L_WALLMOUNT_RANGE 2 +#define L_WALLMOUNT_POWER 0.5 +#define L_WALLMOUNT_RANGE 1 #define L_WALLMOUNT_HI_POWER 1 // For red/delta alert on fire alarms. -#define L_WALLMOUNT_HI_RANGE 4 +#define L_WALLMOUNT_HI_RANGE 2 // This controls by how much console sprites are dimmed before being overlayed. #define HOLOSCREEN_MULTIPLICATION_FACTOR 0.5 #define HOLOSCREEN_ADDITION_OPACITY 0.75 @@ -132,19 +56,115 @@ // Just so we can avoid unneeded proc calls when profiling is disabled. #define L_PROF(O,T) if (GLOB.lighting_profiling) {lprof_write(O,T);} -// -- Ambient Occlusion -- - -// Not handled by the lighting engine, but related. Controls the alpha of the ambient occlusion effect on opaque atoms and openturfs. -#define WALL_AO_ALPHA 80 - -#define AO_UPDATE_NONE 0 -#define AO_UPDATE_OVERLAY 1 -#define AO_UPDATE_REBUILD 2 - -// If ao_neighbors equals this, no AO shadows are present. -#define AO_ALL_NEIGHBORS 1910 - -// If defined, integrate with the lighting engine and use its opacity value. Otherwise a simple turf opacity check is used. This may cause visual artifacts with opaque non-square movables. -//#define AO_USE_LIGHTING_OPACITY - #define MINIMUM_USEFUL_LIGHT_RANGE 1.4 + +///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 +///A mix of the above, cheaper on moving items than dynamic, but heavier on rendering than movable +#define HYBRID_LIGHT 3 +///Pointy light +#define DIRECTIONAL_LIGHT 4 + +#define LIGHT_ATTACHED (1<<0) + +#define LIGHTING_ICON 'icons/effects/lighting_object.dmi' // icon used for lighting shading effects +#define LIGHTING_ICON_BIG 'icons/effects/lighting_object_big.dmi' //! icon used for lighting shading effects + +#define ALPHA_TO_INTENSITY(alpha) (-(((clamp(alpha, 0, 22) - 22) / 6) ** 4) + 255) + + +#define LIGHT_RANGE_FIRE 3 //How many tiles standard fires glow. + +#define LIGHTING_PLANE_ALPHA_VISIBLE 255 +#define LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE 192 +#define LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE 127 +#define LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE 80 +#define LIGHTING_PLANE_ALPHA_INVISIBLE 0 + +#define FLASH_LIGHT_DURATION 2 +#define FLASH_LIGHT_POWER 3 +#define FLASH_LIGHT_RANGE 3.8 + +#define IS_OPAQUE_TURF(turf) (turf.directional_opacity == ALL_CARDINALS) + +// Emissive blocking. +/// For anything that shouldn't block emissives. Small objects or translucent objects primarily +#define EMISSIVE_BLOCK_NONE 0 +/// 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) +/// A set of appearance flags applied to all emissive and emissive blocker overlays. +#define EMISSIVE_APPEARANCE_FLAGS (KEEP_APART|KEEP_TOGETHER|RESET_COLOR|RESET_TRANSFORM) +/// 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 independent 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) + + +//Bay lighting engine shit, not in /code/modules/lighting because BYOND is being shit about it //thats how defines work, hello? +#define LIGHTING_INTERVAL 5 // frequency, in 1/10ths of a second, of the lighting process + +#define MOVABLE_MAX_RANGE 7 + +#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 +#define LIGHTING_ROUND_VALUE (1 / 64) //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. + +/// 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. +#define LIGHTING_BASE_MATRIX \ + list \ + ( \ + 1, 1, 1, 0, \ + 1, 1, 1, 0, \ + 1, 1, 1, 0, \ + 1, 1, 1, 0, \ + 0, 0, 0, 1 \ + ) \ + +#define LIGHTING_NO_UPDATE 0 +#define LIGHTING_VIS_UPDATE 1 +#define LIGHTING_CHECK_UPDATE 2 +#define LIGHTING_FORCE_UPDATE 3 diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 1181d91963d..b8e2918b953 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -17,7 +17,6 @@ #define INVISIBILITY_SYSTEM 99 #define SEE_INVISIBLE_LIVING 25 -#define SEE_INVISIBLE_NOLIGHTING 15 #define SEE_INVISIBLE_LEVEL_ONE 35 #define SEE_INVISIBLE_LEVEL_TWO 45 #define SEE_INVISIBLE_CULT 60 diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index abea96f8a82..cc61bc58d66 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -121,6 +121,7 @@ #define GENERIC_ITEM_TRAIT "generic_item" #define DISABILITY_TRAIT "disability" +#define TRAIT_SOURCE_INHERENT "t_s_inherent" /// cannot be removed without admin intervention #define ROUNDSTART_TRAIT "roundstart" #define CULTURE_TRAIT "culture" @@ -220,3 +221,6 @@ /// A trait gained by leaning against something #define TRAIT_LEANING "leaning" + +/// traits transparent turf +#define TURF_Z_TRANSPARENT_TRAIT "turf_z_transparent" diff --git a/code/__DEFINES/turfs.dm b/code/__DEFINES/turfs.dm index 9af116da7ab..af9e5b12e34 100644 --- a/code/__DEFINES/turfs.dm +++ b/code/__DEFINES/turfs.dm @@ -36,14 +36,6 @@ MACROS/FUNCTIONS ################################*/ -/** - * Checks if a turf is opaque, - * NOT the same inner-working as the TG version, but should be equivalent - * - * * turf - The `/turf` to check - */ -#define IS_OPAQUE_TURF(turf) (turf.opacity || turf.has_opaque_atom) - //supposedly the fastest way to do this according to https://gist.github.com/Giacom/be635398926bb463b42a ///Returns a list of turf in a square #define RANGE_TURFS(RADIUS, CENTER) \ diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index 1a33d1e43b0..c0832ebb15f 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -159,6 +159,32 @@ };\ } while(FALSE) +// binary search sorted insert +// IN: Object to be inserted +// LIST: List to insert object into +#define BINARY_INSERT_NUM(IN, LIST) \ + var/__BIN_CTTL = length(LIST);\ + if(!__BIN_CTTL) {\ + LIST += IN;\ + } else {\ + var/__BIN_LEFT = 1;\ + var/__BIN_RIGHT = __BIN_CTTL;\ + var/__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\ + var/__BIN_ITEM;\ + while(__BIN_LEFT < __BIN_RIGHT) {\ + __BIN_ITEM = LIST[__BIN_MID];\ + if(__BIN_ITEM <= IN) {\ + __BIN_LEFT = __BIN_MID + 1;\ + } else {\ + __BIN_RIGHT = __BIN_MID;\ + };\ + __BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\ + };\ + __BIN_ITEM = LIST[__BIN_MID];\ + __BIN_MID = __BIN_ITEM > IN ? __BIN_MID : __BIN_MID + 1;\ + LIST.Insert(__BIN_MID, IN);\ + } + /** * Custom binary search sorted insert utilising comparison procs instead of vars. * INPUT: Object to be inserted diff --git a/code/__HELPERS/emissives.dm b/code/__HELPERS/emissives.dm index 1c584e6f90c..08c360849b5 100644 --- a/code/__HELPERS/emissives.dm +++ b/code/__HELPERS/emissives.dm @@ -1,21 +1,11 @@ /// Produces a mutable appearance glued to the [EMISSIVE_PLANE] dyed to be the [EMISSIVE_COLOR]. -/// 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, EMISSIVE_PLANE, alpha, appearance_flags | EMISSIVE_APPEARANCE_FLAGS) - if(alpha == 255) - appearance.color = GLOB.emissive_color - else - var/alpha_ratio = alpha/255 - appearance.color = _EMISSIVE_COLOR(alpha_ratio) + appearance.color = GLOB.emissive_color return appearance /// Produces a mutable appearance glued to the [EMISSIVE_PLANE] dyed to be the [EM_BLOCK_COLOR]. -/proc/emissive_blocker(icon, icon_state = "", layer = FLOAT_LAYER, alpha = 255, appearance_flags = EMPTY_BITFIELD, source = null) +/proc/emissive_blocker(icon, icon_state = "", layer = FLOAT_LAYER, alpha = 255, appearance_flags = NONE) var/mutable_appearance/appearance = mutable_appearance(icon, icon_state, layer, EMISSIVE_PLANE, alpha, appearance_flags | EMISSIVE_APPEARANCE_FLAGS) - if(alpha == 255) - appearance.color = GLOB.em_block_color - else - var/alpha_ratio = alpha/255 - appearance.color = _EM_BLOCK_COLOR(alpha_ratio) + appearance.color = GLOB.em_block_color return appearance - diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 291b7afcd03..7d416d13f84 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -880,9 +880,6 @@ lighting determines lighting capturing (optional), suppress_errors suppreses err for(var/turf/T in turfstocapture) atoms += T for(var/atom/A in T) - if(istype(A, /atom/movable/lighting_overlay)) //Special case for lighting - continue - if(A.invisibility) continue @@ -905,14 +902,6 @@ lighting determines lighting capturing (optional), suppress_errors suppreses err var/yoff = (A.y - ty) * 32 cap.Blend(img, blendMode2iconMode(A.blend_mode), A.pixel_x + xoff, A.pixel_y + yoff) - if (lighting) - for (var/turf/T in turfstocapture) - var/icon/im = new(LIGHTING_ICON, "blank") - var/color = T.get_avg_color() // We're going to lose some detail, but it's all we can do without color matrixes. - if (color) - im.Blend(color, ICON_MULTIPLY) - cap.Blend(im, ICON_MULTIPLY, (T.x - tx) * 32, (T.y - ty) * 32) - return cap /proc/percentage_to_colour(var/P) diff --git a/code/__HELPERS/spatial_info.dm b/code/__HELPERS/spatial_info.dm index 31618be8c8c..89b8f7a5741 100644 --- a/code/__HELPERS/spatial_info.dm +++ b/code/__HELPERS/spatial_info.dm @@ -206,16 +206,16 @@ ///Calculate if two atoms are in sight, returns TRUE or FALSE /proc/inLineOfSight(X1,Y1,X2,Y2,Z=1,PX1=16.5,PY1=16.5,PX2=16.5,PY2=16.5) var/turf/T - if(X1 == X2) - if(Y1 == Y2) - return TRUE //Light cannot be blocked on same tile + if(X1==X2) + if(Y1==Y2) + return 1 //Light cannot be blocked on same tile else var/s = SIGN(Y2-Y1) Y1+=s - while(Y1 != Y2) + while(Y1!=Y2) T=locate(X1,Y1,Z) - if(IS_OPAQUE_TURF(T)) - return FALSE + if(T.opacity) + return 0 Y1+=s else var/m=(32*(Y2-Y1)+(PY2-PY1))/(32*(X2-X1)+(PX2-PX1)) @@ -224,17 +224,16 @@ var/signY = SIGN(Y2-Y1) if(X1 !!current_turf.lighting_overlay) - for (var/thing in current_turf) - var/atom/movable/AM = thing - if (AM.simulated && AM.explosion_resistance) - current_power -= AM.explosion_resistance - if (current_power <= 0) CHECK_TICK continue @@ -395,7 +388,7 @@ SUBSYSTEM_DEF(explosives) if (T.simulated) T.ex_act(severity) - if (T.contents.len > !!T.lighting_overlay) + if (T.contents.len) for (var/subthing in T) var/atom/movable/AM = subthing if (AM.simulated) diff --git a/code/controllers/subsystems/lighting.dm b/code/controllers/subsystems/lighting.dm index c2e129f6f5d..231ac9980b7 100644 --- a/code/controllers/subsystems/lighting.dm +++ b/code/controllers/subsystems/lighting.dm @@ -1,217 +1,123 @@ -GLOBAL_VAR_INIT(lighting_profiling, FALSE) -GLOBAL_VAR_INIT(lighting_overlays_initialized, FALSE) - SUBSYSTEM_DEF(lighting) name = "Lighting" - wait = LIGHTING_INTERVAL - runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY - - priority = SS_PRIORITY_LIGHTING + wait = 2 init_order = INIT_ORDER_LIGHTING - var/total_lighting_overlays = 0 - var/total_lighting_sources = 0 - var/list/lighting_corners = list() // List of all lighting corners in the world. + //debug var for tracking updates before init is complete + var/duplicate_shadow_updates_in_init = 0 + ///Total times shadows were updated, debug + var/total_shadow_calculations = 0 - var/list/light_queue = list() // lighting sources queued for update. - var/lq_idex = 1 - var/list/corner_queue = list() // lighting corners queued for update. - var/cq_idex = 1 - var/list/overlay_queue = list() // lighting overlays queued for update. - var/oq_idex = 1 + ///Whether the SS has begun setting up yet + var/started = FALSE - var/tmp/processed_lights = 0 - var/tmp/processed_corners = 0 - var/tmp/processed_overlays = 0 + var/static/list/static_sources_queue = list() //! List of static 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/total_ss_updates = 0 - var/total_instant_updates = 0 - -#ifdef USE_INTELLIGENT_LIGHTING_UPDATES - var/force_queued = TRUE - var/force_override = FALSE // For admins. -#endif - -/datum/controller/subsystem/lighting/stat_entry(msg) - var/list/out = list( -#ifdef USE_INTELLIGENT_LIGHTING_UPDATES - "IUR: [total_ss_updates ? round(total_instant_updates/(total_instant_updates+total_ss_updates)*100, 0.1) : "NaN"]%\n", -#endif - "\tT:{L:[total_lighting_sources] C:[lighting_corners.len] O:[total_lighting_overlays]}\n", - "\tP:{L:[light_queue.len - (lq_idex - 1)]|C:[corner_queue.len - (cq_idex - 1)]|O:[overlay_queue.len - (oq_idex - 1)]}\n", - "\tL:{L:[processed_lights]|C:[processed_corners]|O:[processed_overlays]}\n" - ) - msg = out.Join() - return ..() - -#ifdef USE_INTELLIGENT_LIGHTING_UPDATES - -/datum/controller/subsystem/lighting/ExplosionStart() - force_queued = TRUE - can_fire = FALSE - -/datum/controller/subsystem/lighting/ExplosionEnd() - can_fire = TRUE - if (!force_override) - force_queued = FALSE - - -/datum/controller/subsystem/lighting/proc/handle_roundstart() - force_queued = FALSE - total_ss_updates = 0 - total_instant_updates = 0 - -#endif + var/static/list/mask_queue = list() //! List of hybrid lighting sources queued for update. /datum/controller/subsystem/lighting/Initialize(timeofday) - var/overlaycount = 0 - var/starttime = REALTIMEOFDAY - // Generate overlays. - var/turf/T - var/thing - for (var/zlevel = 1 to world.maxz) - for (thing in Z_TURFS(zlevel)) - T = thing - if(GLOB.config.starlight) - var/turf/space/S = T - if(istype(S) && S.use_starlight) - S.update_starlight() - - if (!T.dynamic_lighting) - continue - - var/area/A = T.loc - if (!A.dynamic_lighting) - continue - - T.lighting_build_overlay() - overlaycount++ - - CHECK_TICK - - GLOB.lighting_overlays_initialized = TRUE - - admin_notice(SPAN_DANGER("Created [overlaycount] lighting overlays in [(REALTIMEOFDAY - starttime)/10] seconds."), R_DEBUG) - - starttime = REALTIMEOFDAY - // Tick once to clear most lights. + started = TRUE + if(!initialized) + //Handle static lightnig + create_all_lighting_objects() fire(FALSE, TRUE) - - admin_notice(SPAN_DANGER("Processed [processed_lights] light sources."), R_DEBUG) - admin_notice(SPAN_DANGER("Processed [processed_corners] light corners."), R_DEBUG) - admin_notice(SPAN_DANGER("Processed [processed_overlays] light overlays."), R_DEBUG) - admin_notice(SPAN_DANGER("Lighting pre-bake completed in [(REALTIMEOFDAY - starttime)/10] seconds."), R_DEBUG) - - log_subsystem("lighting", "NOv:[overlaycount] L:[processed_lights] C:[processed_corners] O:[processed_overlays]") - -#ifdef USE_INTELLIGENT_LIGHTING_UPDATES - SSticker.OnRoundstart(CALLBACK(src, PROC_REF(handle_roundstart))) -#endif - return SS_INIT_SUCCESS -/datum/controller/subsystem/lighting/fire(resumed = FALSE, no_mc_tick = FALSE) - if (!resumed) - processed_lights = 0 - processed_corners = 0 - processed_overlays = 0 +/datum/controller/subsystem/lighting/stat_entry() + . = ..("ShCalcs:[total_shadow_calculations]|SourcQ:[length(static_sources_queue)]|CcornQ:[length(corners_queue)]|ObjQ:[length(objects_queue)]|HybrQ:[length(mask_queue)]") +/datum/controller/subsystem/lighting/fire(resumed, init_tick_checks) MC_SPLIT_TICK_INIT(3) - if (!no_mc_tick) + if(!init_tick_checks) MC_SPLIT_TICK + var/updators_num = 0 + while(updators_num < length(static_sources_queue)) + updators_num += 1 - var/list/curr_lights = light_queue - var/list/curr_corners = corner_queue - var/list/curr_overlays = overlay_queue - - while (lq_idex <= curr_lights.len) - var/datum/light_source/L = curr_lights[lq_idex++] - if(QDELETED(L)) - continue - - if (L.needs_update != LIGHTING_NO_UPDATE) - total_ss_updates += 1 - L.update_corners() + var/datum/static_light_source/L = static_sources_queue[updators_num] + L.update_corners() + if(!QDELETED(L)) L.needs_update = LIGHTING_NO_UPDATE - - processed_lights++ - - if (no_mc_tick) - CHECK_TICK + else + updators_num -= 1 + if(init_tick_checks) + if(!TICK_CHECK) + continue + static_sources_queue.Cut(1, updators_num + 1) + updators_num = 0 + stoplag() else if (MC_TICK_CHECK) break + if(updators_num) + static_sources_queue.Cut(1, updators_num + 1) + updators_num = 0 - if (lq_idex > 1) - curr_lights.Cut(1, lq_idex) - lq_idex = 1 - - if (!no_mc_tick) + if(!init_tick_checks) MC_SPLIT_TICK - while (cq_idex <= curr_corners.len) - var/datum/lighting_corner/C = curr_corners[cq_idex++] - if(QDELETED(C)) + while(updators_num < length(corners_queue)) + updators_num += 1 + + var/datum/static_lighting_corner/C = corners_queue[updators_num] + C.needs_update = FALSE //update_objects() can call qdel if the corner is storing no data + C.update_objects() + + if(init_tick_checks) + if(!TICK_CHECK) + continue + corners_queue.Cut(1, updators_num + 1) + updators_num = 0 + stoplag() + else if (MC_TICK_CHECK) + break + if(updators_num) + corners_queue.Cut(1, updators_num + 1) + updators_num = 0 + if(!init_tick_checks) + MC_SPLIT_TICK + + while(updators_num < length(objects_queue)) + updators_num += 1 + + var/datum/static_lighting_object/O = objects_queue[updators_num] + if (QDELETED(O)) continue + O.update() + O.needs_update = FALSE - if (C.needs_update) - C.update_overlays() - - C.needs_update = FALSE - - processed_corners++ - - if (no_mc_tick) - CHECK_TICK + if(init_tick_checks) + if(!TICK_CHECK) + continue + objects_queue.Cut(1, updators_num + 1) + updators_num = 0 else if (MC_TICK_CHECK) break - - if (cq_idex > 1) - curr_corners.Cut(1, cq_idex) - cq_idex = 1 - - if (!no_mc_tick) + if(updators_num) + objects_queue.Cut(1, updators_num + 1) + updators_num = 0 + if(!init_tick_checks) MC_SPLIT_TICK - while (oq_idex <= curr_overlays.len) - var/atom/movable/lighting_overlay/O = curr_overlays[oq_idex++] + while(updators_num > length(mask_queue)) + updators_num += 1 - if (!QDELETED(O) && O.needs_update) - O.update_overlay() - O.needs_update = FALSE + var/atom/movable/lighting_mask/mask_to_update = mask_queue[updators_num] + mask_to_update.calculate_lighting_shadows() - processed_overlays++ - - if (no_mc_tick) - CHECK_TICK + if(init_tick_checks) + if(!TICK_CHECK) + continue + mask_queue.Cut(1, updators_num + 1) + updators_num = 0 + stoplag() else if (MC_TICK_CHECK) break - - if (oq_idex > 1) - curr_overlays.Cut(1, oq_idex) - oq_idex = 1 + if(updators_num) + mask_queue.Cut(1, updators_num + 1) /datum/controller/subsystem/lighting/Recover() - lighting_corners = SSlighting.lighting_corners - total_lighting_overlays = SSlighting.total_lighting_overlays - total_lighting_sources = SSlighting.total_lighting_sources - - light_queue = SSlighting.light_queue - corner_queue = SSlighting.corner_queue - overlay_queue = SSlighting.overlay_queue - - lq_idex = SSlighting.lq_idex - cq_idex = SSlighting.cq_idex - oq_idex = SSlighting.oq_idex - - if (lq_idex > 1) - light_queue.Cut(1, lq_idex) - lq_idex = 1 - - if (cq_idex > 1) - corner_queue.Cut(1, cq_idex) - cq_idex = 1 - - if (oq_idex > 1) - overlay_queue.Cut(1, oq_idex) - oq_idex = 1 + initialized = SSlighting.initialized + return ..() diff --git a/code/controllers/subsystems/mob.dm b/code/controllers/subsystems/mob.dm index c7dc399f0b9..a289b1e272a 100644 --- a/code/controllers/subsystems/mob.dm +++ b/code/controllers/subsystems/mob.dm @@ -16,9 +16,6 @@ SUBSYSTEM_DEF(mobs) var/list/greatworms = list() var/list/greatasses = list() - var/list/ghost_darkness_images = list() //this is a list of images for things ghosts should still be able to see when they toggle darkness - var/list/ghost_sightless_images = list() //this is a list of images for things ghosts should still be able to see even without ghost sight - // Devour types (these are typecaches). Only simple_animals check these, other types are handled specially. var/list/mtl_synthetic = list( /mob/living/simple_animal/hostile/hivebot diff --git a/code/controllers/subsystems/sunlight.dm b/code/controllers/subsystems/sunlight.dm index 34036aa5544..ff29c383b94 100644 --- a/code/controllers/subsystems/sunlight.dm +++ b/code/controllers/subsystems/sunlight.dm @@ -53,7 +53,6 @@ SUBSYSTEM_DEF(sunlight) /atom/movable/sunobj name = "sunlight emitter" desc = DESC_PARENT - light_novis = TRUE light_range = 16 simulated = FALSE mouse_opacity = FALSE diff --git a/code/controllers/subsystems/ticker.dm b/code/controllers/subsystems/ticker.dm index 4e0d85f69ae..ef51776ec84 100644 --- a/code/controllers/subsystems/ticker.dm +++ b/code/controllers/subsystems/ticker.dm @@ -7,9 +7,7 @@ ///The time at which the next automatic transfer vote will be called GLOBAL_VAR_INIT(next_transfer_time, null) -var/datum/controller/subsystem/ticker/SSticker - -/datum/controller/subsystem/ticker +SUBSYSTEM_DEF(ticker) // -- Subsystem stuff -- name = "Ticker" @@ -73,9 +71,6 @@ var/datum/controller/subsystem/ticker/SSticker var/total_players_ready = 0 var/list/ready_player_jobs -/datum/controller/subsystem/ticker/New() - NEW_SS_GLOBAL(SSticker) - /datum/controller/subsystem/ticker/Initialize(timeofday) pregame() restart_timeout = GLOB.config.restart_timeout diff --git a/code/controllers/subsystems/zcopy.dm b/code/controllers/subsystems/zcopy.dm index dc600b5cfa7..11cc4d57328 100644 --- a/code/controllers/subsystems/zcopy.dm +++ b/code/controllers/subsystems/zcopy.dm @@ -250,8 +250,6 @@ SUBSYSTEM_DEF(zcopy) TO.plane = t_target TO.mouse_opacity = initial(TO.mouse_opacity) - T.queue_ao(T.ao_neighbors_mimic == null) // If ao_neighbors hasn't been set yet, we need to do a rebuild - // Explicitly copy turf delegates so they show up properly on below levels. // I think it's possible to get this to work without discrete delegate copy objects, but I'd rather this just work. if ((T.below.z_flags & (ZM_MIMIC_BELOW|ZM_MIMIC_OVERWRITE)) == ZM_MIMIC_BELOW) @@ -275,11 +273,6 @@ SUBSYSTEM_DEF(zcopy) // Don't queue deleted stuff, stuff that's not visible, blacklisted stuff, or stuff that's centered on another tile but intersects ours. continue - // Special case: these are merged into the shadower to reduce memory usage. - if (object.type == /atom/movable/lighting_overlay) - //T.shadower.copy_lighting(object) - continue - if (!object.bound_overlay) // Generate a new overlay if the atom doesn't already have one. object.bound_overlay = new(T) object.bound_overlay.associated_atom = object @@ -393,13 +386,6 @@ SUBSYSTEM_DEF(zcopy) if (OO.bound_overlay) // If we have a bound overlay, queue it too. OO.update_above() - // If an atom has explicit plane sets on its overlays/underlays, we need to replace the appearance so they can be mangled to work with our planing. - if (OO.z_flags & ZMM_MANGLE_PLANES) - var/new_appearance = fixup_appearance_planes(OO.appearance) - if (new_appearance) - OO.appearance = new_appearance - OO.have_performed_fixup = TRUE - if (no_mc_tick) CHECK_TICK else if (MC_TICK_CHECK) @@ -439,93 +425,6 @@ SUBSYSTEM_DEF(zcopy) if (TO.plane == 0 && target_plane) TO.plane = target_plane -/// Generate a new appearance from `appearance` with planes mangled to work with Z-Mimic. Do not pass a depth. -/datum/controller/subsystem/zcopy/proc/fixup_appearance_planes(appearance, depth = 0) - - // Adding this to guard against a reported runtime - supposed to be impossible, so cause is unclear. - if(!appearance) - return null - - if (fixup_known_good[appearance]) - fixup_hit += 1 - return null - if (fixup_cache[appearance]) - fixup_hit += 1 - return fixup_cache[appearance] - - // If you have more than 4 layers of overlays within overlays, I dunno what to say. - if (depth > 4) - var/icon_name = "[appearance:icon]" - WARNING("Fixup of appearance with icon [icon_name || ""] exceeded maximum recursion limit, bailing") - return null - - var/plane_needs_fix = FALSE - - // Don't fixup the root object's plane. - if (depth > 0) - switch (appearance:plane) - if (GAME_PLANE, FLOAT_PLANE) - plane_needs_fix = FALSE //For lint - else - plane_needs_fix = TRUE - - // Scan & fix overlays - var/list/fixed_overlays - if (appearance:overlays:len) - var/mutated = FALSE - var/fixed_appearance - for (var/i in 1 to appearance:overlays:len) - if ((fixed_appearance = .(appearance:overlays[i], depth + 1))) - mutated = TRUE - if (!fixed_overlays) - fixed_overlays = new( length(appearance:overlays)) - fixed_overlays[i] = fixed_appearance - - if (mutated) - for (var/i in 1 to length(fixed_overlays)) - if (fixed_overlays[i] == null) - fixed_overlays[i] = appearance:overlays[i] - - // Scan & fix underlays - var/list/fixed_underlays - if (appearance:underlays:len) - var/mutated = FALSE - var/fixed_appearance - for (var/i in 1 to appearance:underlays:len) - if ((fixed_appearance = .(appearance:underlays[i], depth + 1))) - mutated = TRUE - if (!fixed_underlays) - fixed_underlays = new( length(appearance:underlays)) - fixed_underlays[i] = fixed_appearance - - if (mutated) - for (var/i in 1 to length(fixed_overlays)) - if (fixed_underlays[i] == null) - fixed_underlays[i] = appearance:underlays[i] - - // If we did nothing (no violations), don't bother creating a new appearance - if (!plane_needs_fix && !fixed_overlays && !fixed_underlays) - fixup_noop += 1 - fixup_known_good[appearance] = TRUE - return null - - fixup_miss += 1 - - var/mutable_appearance/MA = new(appearance) - if (plane_needs_fix) - MA.plane = depth == 0 ? GAME_PLANE : FLOAT_PLANE - MA.layer = FLY_LAYER // probably fine - - if (fixed_overlays) - MA.overlays = fixed_overlays - - if (fixed_underlays) - MA.underlays = fixed_underlays - - fixup_cache[appearance] = MA.appearance - - return MA - #define FMT_DEPTH(X) (X == null ? "(null)" : X) // This is a dummy object used so overlays can be shown in the analyzer. diff --git a/code/datums/components/overlay_lighting.dm b/code/datums/components/overlay_lighting.dm new file mode 100644 index 00000000000..665b7f3d055 --- /dev/null +++ b/code/datums/components/overlay_lighting.dm @@ -0,0 +1,524 @@ +///For switchable lights, is it on and currently emitting light? +#define LIGHTING_ON (1<<0) +///Is the parent attached to something else, its loc? Then we need to keep an eye of this. +#define LIGHTING_ATTACHED (1<<1) + +#define GET_PARENT (parent_attached_to || parent) + +#define SHORT_CAST 2 + + +/** + * Movable atom overlay-based lighting component. + * + * * Component works by applying a visual object to the parent target. + * + * * The component tracks the parent's loc to determine the current_holder. + * * The current_holder is either the parent or its loc, whichever is on a turf. If none, then the current_holder is null and the light is not visible. + * + * * Lighting works at its base by applying a dark overlay and "cutting" said darkness with light, adding (possibly colored) transparency. + * * This component uses the visible_mask visual object to apply said light mask on the darkness. + * + * * The main limitation of this system is that it uses a limited number of pre-baked geometrical shapes, but for most uses it does the job. + * + * * Another limitation is for big lights: you only see the light if you see the object emiting it. + * * For small objects this is good (you can't see them behind a wall), but for big ones this quickly becomes prety clumsy. +*/ +/datum/component/overlay_lighting + ///How far the light reaches, float. + var/range = 1 + ///Ceiling of range, integer without decimal entries. + var/lumcount_range = 0 + ///How much this light affects the dynamic_lumcount of turfs. + var/lum_power = 0.5 + ///Transparency value. + var/set_alpha = 0 + ///For light sources that can be turned on and off. + var/overlay_lighting_flags = NONE + + ///Cache of the possible light overlays, according to size. + var/static/list/light_overlays = list( + "32" = 'icons/effects/light_overlays/light_32.dmi', + "64" = 'icons/effects/light_overlays/light_64.dmi', + "96" = 'icons/effects/light_overlays/light_96.dmi', + "128" = 'icons/effects/light_overlays/light_128.dmi', + "160" = 'icons/effects/light_overlays/light_160.dmi', + "192" = 'icons/effects/light_overlays/light_192.dmi', + "224" = 'icons/effects/light_overlays/light_224.dmi', + "256" = 'icons/effects/light_overlays/light_256.dmi', + "288" = 'icons/effects/light_overlays/light_288.dmi', + "320" = 'icons/effects/light_overlays/light_320.dmi', + "352" = 'icons/effects/light_overlays/light_352.dmi', + "384" = 'icons/effects/light_overlays/light_384.dmi', + "416" = 'icons/effects/light_overlays/light_416.dmi', + ) + + ///Overlay effect to cut into the darkness and provide light. + var/image/visible_mask + ///Lazy list to track the turfs being affected by our light, to determine their visibility. + var/list/turf/affected_turfs + ///Movable atom currently holding the light. Parent might be a flashlight, for example, but that might be held by a mob or something else. + var/atom/movable/current_holder + ///Movable atom the parent is attached to. For example, a flashlight into a helmet or gun. We'll need to track the thing the parent is attached to as if it were the parent itself. + var/atom/movable/parent_attached_to + ///Whether we're a directional light + var/directional = FALSE + ///A cone overlay for directional light, it's alpha and color are dependant on the light + var/image/cone + ///Current tracked direction for the directional cast behaviour + var/current_direction + ///Tracks current directional x offset so we dont update unecessarily + var/directional_offset_x + ///Tracks current directional y offset so we dont update unecessarily + var/directional_offset_y + ///Cast range for the directional cast (how far away the atom is moved) + var/cast_range = 2 + + +/datum/component/overlay_lighting/Initialize(_range, _power, _color, starts_on, is_directional) + if(!ismovable(parent)) + return COMPONENT_INCOMPATIBLE + + var/atom/movable/movable_parent = parent + if(movable_parent.light_system != MOVABLE_LIGHT && movable_parent.light_system != DIRECTIONAL_LIGHT) + stack_trace("[type] added to [parent], with [movable_parent.light_system] value for the light_system var. Use [MOVABLE_LIGHT]/[DIRECTIONAL_LIGHT] instead.") + return COMPONENT_INCOMPATIBLE + + . = ..() + + visible_mask = image('icons/effects/light_overlays/light_32.dmi', icon_state = "light") + visible_mask.plane = O_LIGHTING_VISUAL_PLANE + visible_mask.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + visible_mask.alpha = 0 + if(is_directional) + directional = TRUE + cone = image('icons/effects/light_overlays/light_cone.dmi', icon_state = "light") + cone.plane = O_LIGHTING_VISUAL_PLANE + cone.appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM + cone.alpha = 110 + cone.transform = cone.transform.Translate(-32, -32) + set_direction(movable_parent.dir) + if(!isnull(_range)) + movable_parent.set_light_range(_range) + set_range(parent, movable_parent.light_range) + if(!isnull(_power)) + movable_parent.set_light_power(_power) + set_power(parent, movable_parent.light_power) + if(!isnull(_color)) + movable_parent.set_light_color(_color) + set_color(parent, movable_parent.light_color) + if(!isnull(starts_on)) + movable_parent.set_light_on(starts_on) + +/datum/component/overlay_lighting/RegisterWithParent() + . = ..() + if(directional) + RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, PROC_REF(on_parent_dir_change)) + RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_parent_moved)) + RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(check_holder)) + RegisterSignal(parent, COMSIG_ATOM_SET_LIGHT_RANGE, PROC_REF(set_range)) + RegisterSignal(parent, COMSIG_ATOM_SET_LIGHT_POWER, PROC_REF(set_power)) + RegisterSignal(parent, COMSIG_ATOM_SET_LIGHT_COLOR, PROC_REF(set_color)) + RegisterSignal(parent, COMSIG_ATOM_SET_LIGHT_ON, PROC_REF(on_toggle)) + RegisterSignal(parent, COMSIG_ATOM_SET_LIGHT_FLAGS, PROC_REF(on_light_flags_change)) + var/atom/movable/movable_parent = parent + if(movable_parent.light_flags & LIGHT_ATTACHED) + overlay_lighting_flags |= LIGHTING_ATTACHED + set_parent_attached_to(ismovable(movable_parent.loc) ? movable_parent.loc : null) + check_holder() + if(movable_parent.light_on) + turn_on() + + + +/datum/component/overlay_lighting/UnregisterFromParent() + overlay_lighting_flags &= ~LIGHTING_ATTACHED + set_parent_attached_to(null) + set_holder(null) + clean_old_turfs() + UnregisterSignal(parent, list( + COMSIG_MOVABLE_MOVED, + COMSIG_ATOM_SET_LIGHT_RANGE, + COMSIG_ATOM_SET_LIGHT_POWER, + COMSIG_ATOM_SET_LIGHT_COLOR, + COMSIG_ATOM_SET_LIGHT_ON, + COMSIG_ATOM_SET_LIGHT_FLAGS, + )) + if(directional) + UnregisterSignal(parent, COMSIG_ATOM_DIR_CHANGE) + if(overlay_lighting_flags & LIGHTING_ON) + turn_off() + return ..() + + +/datum/component/overlay_lighting/Destroy() + set_parent_attached_to(null) + set_holder(null) + clean_old_turfs() + visible_mask = null + cone = null + parent_attached_to = null + return ..() + + +///Clears the affected_turfs lazylist, removing from its contents the effects of being near the light. +/datum/component/overlay_lighting/proc/clean_old_turfs() + for(var/turf/lit_turf as anything in affected_turfs) + lit_turf.dynamic_lumcount -= lum_power + affected_turfs = null + + +///Populates the affected_turfs lazylist, adding to its contents the effects of being near the light. +/datum/component/overlay_lighting/proc/get_new_turfs() + if(!current_holder) + return + LAZYINITLIST(affected_turfs) + if(range <= 2) + //Range here is 1 because actual range of lighting mask is 1 tile even if it says that range is 2 + for(var/turf/lit_turf as anything in RANGE_TURFS(1, current_holder.loc)) + lit_turf.dynamic_lumcount += lum_power + affected_turfs += lit_turf + else + for(var/turf/lit_turf in view(lumcount_range, get_turf(current_holder))) + lit_turf.dynamic_lumcount += lum_power + affected_turfs += lit_turf + + +///Clears the old affected turfs and populates the new ones. +/datum/component/overlay_lighting/proc/make_luminosity_update() + clean_old_turfs() + if(!isturf(current_holder?.loc)) + return + if(directional) + cast_directional_light() + get_new_turfs() + + +///Adds the luminosity and source for the affected movable atoms to keep track of their visibility. +/datum/component/overlay_lighting/proc/add_dynamic_lumi() + LAZYSET(current_holder.affected_movable_lights, src, lumcount_range + 1) + current_holder.underlays += visible_mask + current_holder.update_dynamic_luminosity() + if(directional) + current_holder.underlays += cone + +///Removes the luminosity and source for the affected movable atoms to keep track of their visibility. +/datum/component/overlay_lighting/proc/remove_dynamic_lumi() + LAZYREMOVE(current_holder.affected_movable_lights, src) + current_holder.underlays -= visible_mask + current_holder.update_dynamic_luminosity() + if(directional) + current_holder.underlays -= cone + +///Called to change the value of parent_attached_to. +/datum/component/overlay_lighting/proc/set_parent_attached_to(atom/movable/new_parent_attached_to) + if(new_parent_attached_to == parent_attached_to) + return + + . = parent_attached_to + parent_attached_to = new_parent_attached_to + if(.) + var/atom/movable/old_parent_attached_to = . + UnregisterSignal(old_parent_attached_to, list(COMSIG_QDELETING, COMSIG_MOVABLE_MOVED)) + if(old_parent_attached_to == current_holder) + RegisterSignal(old_parent_attached_to, COMSIG_QDELETING, PROC_REF(on_holder_qdel)) + RegisterSignal(old_parent_attached_to, COMSIG_MOVABLE_MOVED, PROC_REF(on_holder_moved)) + if(parent_attached_to) + if(parent_attached_to == current_holder) + UnregisterSignal(current_holder, list(COMSIG_QDELETING, COMSIG_MOVABLE_MOVED)) + RegisterSignal(parent_attached_to, COMSIG_QDELETING, PROC_REF(on_parent_attached_to_qdel)) + RegisterSignal(parent_attached_to, COMSIG_MOVABLE_MOVED, PROC_REF(on_parent_attached_to_moved)) + check_holder() + + +///Called to change the value of current_holder. +/datum/component/overlay_lighting/proc/set_holder(atom/movable/new_holder) + if(new_holder == current_holder) + return + if(current_holder) + if(current_holder != parent && current_holder != parent_attached_to) + UnregisterSignal(current_holder, list(COMSIG_QDELETING, COMSIG_MOVABLE_MOVED)) + if(directional) + UnregisterSignal(current_holder, COMSIG_ATOM_DIR_CHANGE) + if(overlay_lighting_flags & LIGHTING_ON) + remove_dynamic_lumi() + current_holder = new_holder + if(new_holder == null) + clean_old_turfs() + return + if(new_holder != parent && new_holder != parent_attached_to) + RegisterSignal(new_holder, COMSIG_QDELETING, PROC_REF(on_holder_qdel)) + if(overlay_lighting_flags & LIGHTING_ON) + RegisterSignal(new_holder, COMSIG_MOVABLE_MOVED, PROC_REF(on_holder_moved)) + if(directional) + RegisterSignal(new_holder, COMSIG_ATOM_DIR_CHANGE, PROC_REF(on_holder_dir_change)) + if(directional && current_direction != new_holder.dir) + current_direction = new_holder.dir + if(overlay_lighting_flags & LIGHTING_ON) + add_dynamic_lumi() + make_luminosity_update() + + +///Used to determine the new valid current_holder from the parent's loc. +/datum/component/overlay_lighting/proc/check_holder() + var/atom/movable/movable_parent = GET_PARENT + if(QDELETED(movable_parent)) + set_holder(null) + return + if(isturf(movable_parent.loc)) + set_holder(movable_parent) + return + var/atom/inside = movable_parent.loc //Parent's loc + if(isnull(inside)) + set_holder(null) + return + if(isturf(inside.loc)) + // storage items block light, also don't be moving into a qdeleted item + if(QDELETED(inside) || istype(inside, /obj/item/storage)) + set_holder(null) + else + set_holder(inside) + return + set_holder(null) + + +///Called when the current_holder is qdeleted, to remove the light effect. +/datum/component/overlay_lighting/proc/on_holder_qdel(atom/movable/source, force) + SIGNAL_HANDLER + if(QDELETED(current_holder)) + set_holder(null) + return + UnregisterSignal(current_holder, list(COMSIG_QDELETING, COMSIG_MOVABLE_MOVED)) + if(directional) + UnregisterSignal(current_holder, COMSIG_ATOM_DIR_CHANGE) + set_holder(null) + + +///Called when current_holder changes loc. +/datum/component/overlay_lighting/proc/on_holder_moved(atom/movable/source, OldLoc, Dir, Forced) + SIGNAL_HANDLER + if(!(overlay_lighting_flags & LIGHTING_ON)) + return + make_luminosity_update() + +///Called when the current_holder is qdeleted, to remove the light effect. +/datum/component/overlay_lighting/proc/on_parent_attached_to_qdel(atom/movable/source, force) + SIGNAL_HANDLER + UnregisterSignal(parent_attached_to, list(COMSIG_QDELETING, COMSIG_MOVABLE_MOVED)) + if(directional) + UnregisterSignal(parent_attached_to, COMSIG_ATOM_DIR_CHANGE) + if(parent_attached_to == current_holder) + set_holder(null) + set_parent_attached_to(null) + +///Called when parent_attached_to changes loc. +/datum/component/overlay_lighting/proc/on_parent_attached_to_moved(atom/movable/source, OldLoc, Dir, Forced) + SIGNAL_HANDLER + check_holder() + if(!(overlay_lighting_flags & LIGHTING_ON) || !current_holder) + return + make_luminosity_update() + +///Called when parent changes loc. +/datum/component/overlay_lighting/proc/on_parent_moved(atom/movable/source, OldLoc, Dir, Forced) + SIGNAL_HANDLER + var/atom/movable/movable_parent = parent + if(overlay_lighting_flags & LIGHTING_ATTACHED) + set_parent_attached_to(ismovable(movable_parent.loc) ? movable_parent.loc : null) + check_holder() + if(!(overlay_lighting_flags & LIGHTING_ON) || !current_holder) + return + make_luminosity_update() + + +///Changes the range which the light reaches. 0 means no light, 7 is the maximum value. +/datum/component/overlay_lighting/proc/set_range(atom/source, new_range) + SIGNAL_HANDLER + if(range == new_range) + return + if(range == 0) + turn_off() + range = clamp(CEILING(new_range, 0.5), 1, 7) + var/pixel_bounds = ((range - 1) * 64) + 32 + lumcount_range = ceil(range) + if(current_holder && overlay_lighting_flags & LIGHTING_ON) + current_holder.underlays -= visible_mask + visible_mask.icon = light_overlays["[pixel_bounds]"] + if(pixel_bounds == 32) + visible_mask.transform = null + return + var/offset = (pixel_bounds - 32) * 0.5 + var/matrix/transform = new + transform.Translate(-offset, -offset) + visible_mask.transform = transform + directional_offset_x = 0 + directional_offset_y = 0 + if(current_holder && overlay_lighting_flags & LIGHTING_ON) + current_holder.underlays += visible_mask + if(directional) + cast_range = clamp(floor(new_range * 0.5), 1, 3) + if(overlay_lighting_flags & LIGHTING_ON) + make_luminosity_update() + + +///Changes the intensity/brightness of the light by altering the visual object's alpha. +/datum/component/overlay_lighting/proc/set_power(atom/source, new_power) + SIGNAL_HANDLER + set_lum_power(new_power >= 0 ? 0.5 : -0.5) + set_alpha = min(230, (abs(new_power) * 120) + 30) + if(current_holder && overlay_lighting_flags & LIGHTING_ON) + current_holder.underlays -= visible_mask + visible_mask.alpha = set_alpha + if(current_holder && overlay_lighting_flags & LIGHTING_ON) + current_holder.underlays += visible_mask + + if(!directional) + return + + if(current_holder && overlay_lighting_flags & LIGHTING_ON) + current_holder.underlays -= cone + cone.alpha = min(200, (abs(new_power) * 90)+20) + if(current_holder && overlay_lighting_flags & LIGHTING_ON) + current_holder.underlays += cone + + +///Changes the light's color, pretty straightforward. +/datum/component/overlay_lighting/proc/set_color(atom/source, new_color) + SIGNAL_HANDLER + if(current_holder && overlay_lighting_flags & LIGHTING_ON) + current_holder.underlays -= visible_mask + visible_mask.color = new_color + if(current_holder && overlay_lighting_flags & LIGHTING_ON) + current_holder.underlays += visible_mask + + if(!directional) + return + + if(current_holder && overlay_lighting_flags & LIGHTING_ON) + current_holder.underlays -= cone + cone.color = new_color + if(current_holder && overlay_lighting_flags & LIGHTING_ON) + current_holder.underlays += cone + + +///Toggles the light on and off. +/datum/component/overlay_lighting/proc/on_toggle(atom/source, new_value) + SIGNAL_HANDLER + if(new_value) //Truthy value input, turn on. + turn_on() + return + turn_off() //Falsey value, turn off. + +///Triggered right after the parent light flags change. +/datum/component/overlay_lighting/proc/on_light_flags_change(atom/source, new_flags) + SIGNAL_HANDLER + var/atom/movable/movable_parent = parent + + if(new_flags & LIGHT_ATTACHED) // Gained the [LIGHT_ATTACHED] property + overlay_lighting_flags |= LIGHTING_ATTACHED + if(ismovable(movable_parent.loc)) + set_parent_attached_to(movable_parent.loc) + else // Lost the [LIGHT_ATTACHED] property + overlay_lighting_flags &= ~LIGHTING_ATTACHED + set_parent_attached_to(null) + +///Toggles the light on. +/datum/component/overlay_lighting/proc/turn_on() + if(overlay_lighting_flags & LIGHTING_ON) + return + overlay_lighting_flags |= LIGHTING_ON + if(current_holder) + add_dynamic_lumi(current_holder) + if(directional) + cast_directional_light() + if(current_holder && current_holder != parent && current_holder != parent_attached_to) + RegisterSignal(current_holder, COMSIG_MOVABLE_MOVED, PROC_REF(on_holder_moved)) + get_new_turfs() + + +///Toggles the light off. +/datum/component/overlay_lighting/proc/turn_off() + if(!(overlay_lighting_flags & LIGHTING_ON)) + return + if(current_holder) + remove_dynamic_lumi() + overlay_lighting_flags &= ~LIGHTING_ON + if(current_holder && current_holder != parent && current_holder != parent_attached_to) + UnregisterSignal(current_holder, COMSIG_MOVABLE_MOVED) + clean_old_turfs() + + +///Here we append the behavior associated to changing lum_power. +/datum/component/overlay_lighting/proc/set_lum_power(new_lum_power) + if(lum_power == new_lum_power) + return + . = lum_power + lum_power = new_lum_power + var/difference = . - lum_power + for(var/turf/lit_turf as anything in affected_turfs) + lit_turf.dynamic_lumcount -= difference + +///Here we append the behavior associated to changing lum_power. +/datum/component/overlay_lighting/proc/cast_directional_light() + var/final_distance = cast_range + //Lower the distance by 1 if we're not looking at a cardinal direction, and we're not a short cast + if(final_distance > SHORT_CAST && !(ALL_CARDINALS & current_direction)) + final_distance -= 1 + var/turf/scanning = get_turf(current_holder) + for(var/i in 1 to final_distance) + var/turf/next_turf = get_step(scanning, current_direction) + if(isnull(next_turf) || IS_OPAQUE_TURF(next_turf)) + final_distance = i + break + scanning = next_turf + + current_holder.underlays -= visible_mask + + var/translate_x = -((range - 1) * 32) + var/translate_y = translate_x + switch(current_direction) + if(NORTH) + translate_y += 32 * final_distance + if(SOUTH) + translate_y += -32 * final_distance + if(EAST) + translate_x += 32 * final_distance + if(WEST) + translate_x += -32 * final_distance + if((directional_offset_x != translate_x) || (directional_offset_y != translate_y)) + directional_offset_x = translate_x + directional_offset_y = translate_y + var/matrix/transform = matrix() + transform.Translate(translate_x, translate_y) + visible_mask.transform = transform + if(overlay_lighting_flags & LIGHTING_ON) + current_holder.underlays += visible_mask + +///Called when current_holder changes loc. +/datum/component/overlay_lighting/proc/on_holder_dir_change(atom/movable/source, olddir, newdir) + SIGNAL_HANDLER + set_direction(newdir) + +///Called when parent changes loc. +/datum/component/overlay_lighting/proc/on_parent_dir_change(atom/movable/source, olddir, newdir) + SIGNAL_HANDLER + + if(current_holder?.dir != newdir) + return + + set_direction(newdir) + +///Sets a new direction for the directional cast, then updates luminosity +/datum/component/overlay_lighting/proc/set_direction(newdir) + if(!newdir) + return + if(current_direction == newdir) + return + current_direction = newdir + if(overlay_lighting_flags & LIGHTING_ON) + make_luminosity_update() + +#undef LIGHTING_ON +#undef LIGHTING_ATTACHED +#undef GET_PARENT +#undef SHORT_CAST diff --git a/code/datums/elements/light_blocking.dm b/code/datums/elements/light_blocking.dm new file mode 100644 index 00000000000..08e7ea35436 --- /dev/null +++ b/code/datums/elements/light_blocking.dm @@ -0,0 +1,43 @@ +/** + * Attached to movable atoms with opacity. Listens to them move and updates their old and new turf loc's opacity accordingly. + */ +/datum/element/light_blocking + element_flags = ELEMENT_DETACH_ON_HOST_DESTROY + + +/datum/element/light_blocking/Attach(datum/target) + . = ..() + if(!ismovable(target)) + return ELEMENT_INCOMPATIBLE + RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(on_target_move)) + var/atom/movable/movable_target = target + if(!isturf(movable_target.loc)) + return + for(var/turf/turf_loc as anything in movable_target.locs) + turf_loc.add_opacity_source(target) + + +/datum/element/light_blocking/Detach(datum/target) + . = ..() + UnregisterSignal(target, list(COMSIG_MOVABLE_MOVED)) + var/atom/movable/movable_target = target + if(!isturf(movable_target.loc)) + return + for(var/turf/turf_loc as anything in movable_target.locs) + turf_loc.remove_opacity_source(target) + + +///Updates old and new turf loc opacities. +///Updates old and new turf loc opacities. +/datum/element/light_blocking/proc/on_target_move(atom/movable/source, atom/old_loc, dir, forced, list/old_locs) + SIGNAL_HANDLER + if(isturf(old_loc)) + if(old_locs) + for(var/turf/old_turf as anything in old_locs) + old_turf.remove_opacity_source(source) + else + var/turf/old_turf = old_loc + old_turf.remove_opacity_source(source) + if(isturf(source.loc)) + for(var/turf/new_turf as anything in source.locs) + new_turf.add_opacity_source(source) diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 38439f300df..554fdcbf432 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -29,9 +29,9 @@ GLOBAL_LIST_INIT(area_blurb_stated_to, list()) icon = 'icons/turf/areas.dmi' icon_state = "unknown" layer = AREA_LAYER - luminosity = 0 mouse_opacity = MOUSE_OPACITY_TRANSPARENT invisibility = INVISIBILITY_LIGHTING + plane = BLACKNESS_PLANE var/obj/machinery/power/apc/apc = null /// The base turf type of the area, which can be used to override the z-level's base turf. @@ -139,11 +139,6 @@ GLOBAL_LIST_INIT(area_blurb_stated_to, list()) power_equip = 0 power_environ = 0 - if(dynamic_lighting) - luminosity = 0 - else - luminosity = 1 - if(centcomm_area) GLOB.centcom_areas[src] = TRUE alwaysgravity = 1 @@ -161,8 +156,7 @@ GLOBAL_LIST_INIT(area_blurb_stated_to, list()) . = ..() - if(dynamic_lighting) - luminosity = FALSE + update_base_lighting() if (mapload && turf_initializer) for(var/turf/T in src) diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm index d2cc218e2f3..7d222ab3698 100644 --- a/code/game/atom/_atom.dm +++ b/code/game/atom/_atom.dm @@ -56,6 +56,36 @@ var/gfi_layer_rotation = GFI_ROTATION_DEFAULT + //light stuff + + ///Light systems, only one of the three should be active at the same time. + var/light_system = STATIC_LIGHT + ///Range of the light in tiles. Zero means no light. + var/light_range = 0 + ///Intensity of the light. The stronger, the less shadows you will see on the lit area. + var/light_power = 1 + ///Hexadecimal RGB string representing the colour of the light. White by default. + var/light_color = COLOR_WHITE + ///Boolean variable for toggleable lights. Has no effect without the proper light_system, light_range and light_power values. + var/light_on = FALSE + ///Bitflags to determine lighting-related atom properties. + var/light_flags = NONE + ///Our light source. Don't fuck with this directly unless you have a good reason! + var/tmp/datum/dynamic_light_source/light + ///Any light sources that are "inside" of us, for example, if src here was a mob that's carrying a flashlight, that flashlight's light source would be part of this list. + var/tmp/list/hybrid_light_sources + + //Values should avoid being close to -16, 16, -48, 48 etc. + //Best keep them within 10 units of a multiple of 32, as when the light is closer to a wall, the probability + //that a shadow extends to opposite corners of the light mask square is increased, resulting in more shadow + //overlays. + ///x offset for dynamic lights on this atom + var/light_pixel_x + ///y offset for dynamic lights on this atom + var/light_pixel_y + ///typepath for the lighting maskfor dynamic light sources + var/light_mask_type = null + /* * EXTRA DESCRIPTIONS * Adds additional information of different types about a given object. @@ -122,9 +152,6 @@ if(light) QDEL_NULL(light) - if(length(light_sources)) - light_sources.Cut() - if(smoothing_flags & SMOOTH_QUEUED) SSicon_smooth.remove_from_queues(src) diff --git a/code/game/atom/atoms_initializing_EXPENSIVE.dm b/code/game/atom/atoms_initializing_EXPENSIVE.dm index 6e93664a28e..cee45a2cda8 100644 --- a/code/game/atom/atoms_initializing_EXPENSIVE.dm +++ b/code/game/atom/atoms_initializing_EXPENSIVE.dm @@ -129,20 +129,15 @@ reagents.maximum_volume += max(LAZYACCESS(reagents_to_add, v) - REAGENTS_FREE_SPACE(reagents), 0) reagents.add_reagent(v, LAZYACCESS(reagents_to_add, v), LAZYACCESS(reagent_data, v)) - if(light_power && light_range) + if(light_system != MOVABLE_LIGHT && light_system != DIRECTIONAL_LIGHT && light_power && light_range) update_light() if(loc) SEND_SIGNAL(loc, COMSIG_ATOM_INITIALIZED_ON, src) // used for large_object_transparency component if(isturf(loc) && opacity) - var/turf/T = loc - T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guaranteed to be on afterwards anyways. - - #ifdef AO_USE_LIGHTING_OPACITY - if(!mapload) - T.regenerate_ao() - #endif + var/turf/opaque_turf = loc + opaque_turf.directional_opacity = ALL_CARDINALS // No need to recalculate it in this case, it's guaranteed to be on afterwards anyways. if(update_icon_on_init) SSicon_update.add_to_queue(src) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index de1193ec7fb..13fcc2b8e92 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -239,14 +239,9 @@ var/old_dir = dir dir = new_dir - // Lighting. + SEND_SIGNAL(src, COMSIG_ATOM_DIR_CHANGE, dir, new_dir) if (.) - var/datum/light_source/L - for (var/thing in light_sources) - L = thing - if (L.light_angle) - L.source_atom.update_light() - GLOB.dir_set_event.raise_event(src, old_dir, dir) + GLOB.dir_set_event.raise_event(src, old_dir, dir) //todomat: probaly get ird of this shit /atom/proc/melt() return diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 37e603e4f57..44d23df9354 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -76,24 +76,33 @@ ///Internal holder for emissive blocker object, DO NOT USE DIRECTLY. Use blocks_emissive var/mutable_appearance/em_block + ///Lazylist to keep track on the sources of illumination. + var/list/affected_movable_lights + ///Highest-intensity light affecting us, which determines our visibility. + var/affecting_dynamic_lumi = 0 + + /// Holds a reference to the emissive blocker overlay + var/emissive_overlay + /// Whether this atom should have its dir automatically changed when it moves. Setting this to FALSE allows for things such as directional windows to retain dir on moving without snowflake code all of the place. var/set_dir_on_move = TRUE /atom/movable/Initialize(mapload, ...) . = ..() update_emissive_blocker() - if (em_block) - AddOverlays(em_block) + + if(opacity) + AddElement(/datum/element/light_blocking) + if(light_system == MOVABLE_LIGHT) + AddComponent(/datum/component/overlay_lighting) + if(light_system == DIRECTIONAL_LIGHT) + AddComponent(/datum/component/overlay_lighting, is_directional = TRUE) /atom/movable/Destroy(force) if(orbiting) stop_orbit() - //Recalculate opacity - var/turf/T = loc - if(opacity && istype(T)) - T.recalc_atom_opacity() - T.reconsider_lights() + QDEL_NULL(emissive_overlay) if(move_packet) if(!QDELETED(move_packet)) @@ -139,6 +148,9 @@ if(em_block) QDEL_NULL(em_block) + QDEL_NULL(light) + QDEL_NULL(static_light) + /atom/movable/proc/moveToNullspace() . = TRUE @@ -370,19 +382,23 @@ src.throw_at(pick(turfs), maxrange, speed) /atom/movable/proc/update_emissive_blocker() - switch (blocks_emissive) - if (EMISSIVE_BLOCK_GENERIC) + if(emissive_overlay) + CutOverlays(emissive_overlay) + + switch(blocks_emissive) + if(EMISSIVE_BLOCK_GENERIC) var/mutable_appearance/gen_emissive_blocker = mutable_appearance(icon, icon_state, plane = EMISSIVE_PLANE, alpha = src.alpha) gen_emissive_blocker.color = GLOB.em_block_color gen_emissive_blocker.dir = dir gen_emissive_blocker.appearance_flags |= appearance_flags - em_block = gen_emissive_blocker + emissive_overlay = gen_emissive_blocker + AddOverlays(emissive_overlay) - if (EMISSIVE_BLOCK_UNIQUE) + if(EMISSIVE_BLOCK_UNIQUE) render_target = REF(src) em_block = new(src, render_target) - - return em_block + emissive_overlay = em_block + AddOverlays(emissive_overlay) /atom/movable/update_icon() ..() @@ -522,13 +538,6 @@ if(opacity) updateVisibility(src) - //Lighting recalculation - var/datum/light_source/L - var/thing - for (thing in light_sources) - L = thing - L.source_atom.update_light() - RESOLVE_ACTIVE_MOVEMENT return TRUE @@ -567,6 +576,13 @@ SSspatial_grid.enter_cell(src, new_turf) /* END Spatial grid stuffs */ + for(var/datum/dynamic_light_source/light as anything in hybrid_light_sources) + light.source_atom.update_light() + if(!isturf(loc)) + light.find_containing_atom() + for(var/datum/static_light_source/L as anything in static_light_sources) // Cycle through the light sources on this atom and tell them to update. + L.source_atom.static_update_light() + /atom/movable/Exited(atom/movable/gone, direction) . = ..() @@ -926,14 +942,6 @@ if(oldarea != newarea) newarea.Entered(src, oldarea) - // Lighting. - if(light_sources) - var/datum/light_source/L - var/thing - for(thing in light_sources) - L = thing - L.source_atom.update_light() - // Openturf. if(bound_overlay) // The overlay will handle cleaning itself up on non-openspace turfs. @@ -1035,3 +1043,30 @@ /atom/movable/proc/add_point_filter() add_filter("pointglow", 1, list(type = "drop_shadow", x = 0, y = -1, offset = 1, size = 1, color = "#F00")) addtimer(CALLBACK(src, PROC_REF(remove_filter), "pointglow"), 2 SECONDS) + +///Keeps track of the sources of dynamic luminosity and updates our visibility with the highest. +/atom/movable/proc/update_dynamic_luminosity() + var/highest = 0 + for(var/i in affected_movable_lights) + if(affected_movable_lights[i] <= highest) + continue + highest = affected_movable_lights[i] + if(highest == affecting_dynamic_lumi) + return + luminosity -= affecting_dynamic_lumi + affecting_dynamic_lumi = highest + luminosity += affecting_dynamic_lumi + + +///Helper to change several lighting overlay settings. +/atom/movable/proc/set_light_range_power_color(range, power, color) + set_light_range(range) + set_light_power(power) + set_light_color(color) + +/** + * Called when a movable is moved by a shuttle. Eventually, God willing, replace this with the TG shuttle version. + */ +/atom/movable/proc/afterShuttleMove(obj/effect/shuttle_landmark/destination) + if(light) + update_light() diff --git a/code/game/gamemodes/cult/hell_universe.dm b/code/game/gamemodes/cult/hell_universe.dm index a30f247df44..d5814ded795 100644 --- a/code/game/gamemodes/cult/hell_universe.dm +++ b/code/game/gamemodes/cult/hell_universe.dm @@ -61,24 +61,14 @@ In short: /datum/universal_state/hell/OverlayAndAmbientSet() set waitfor = FALSE for(var/turf/T in world) // Expensive, but CHECK_TICK should prevent lag. - if(istype(T, /turf/space)) - T.AddOverlays("hell01") - else - var/static/image/I = image('icons/turf/space.dmi', "hell01") - T.underlays += I + var/static/image/I = image('icons/turf/space.dmi', "hell01") + T.underlays += I if (istype(T, /turf/simulated/floor) && !T.holy && prob(1)) new /obj/effect/gateway/active/cult(T) CHECK_TICK - for(var/datum/lighting_corner/C in SSlighting.lighting_corners) - if (!C.active) - continue - - C.update_lumcount(0.5, 0, 0) - CHECK_TICK - /datum/universal_state/hell/proc/MiscSet() for (var/obj/machinery/firealarm/alm in SSmachinery.processing) if (!(alm.stat & BROKEN)) diff --git a/code/game/gamemodes/cult/structures/pylon.dm b/code/game/gamemodes/cult/structures/pylon.dm index a85ea35e2fe..68ab4594026 100644 --- a/code/game/gamemodes/cult/structures/pylon.dm +++ b/code/game/gamemodes/cult/structures/pylon.dm @@ -6,9 +6,11 @@ name = "pylon" desc = "A floating crystal that hums with an unearthly energy." icon_state = "pylonbase" - var/isbroken = FALSE + light_system = MOVABLE_LIGHT light_range = 5 light_color = "#3e0000" + anchored = FALSE + var/isbroken = FALSE var/pylonmode = PYLON_IDLE var/damagetaken = 0 @@ -42,7 +44,6 @@ var/process_interval = 1 var/ticks - anchored = FALSE /obj/structure/cult/pylon/condition_hints(mob/user, distance, is_adjacent) . = list() @@ -512,12 +513,14 @@ anchored = TRUE if(empowered) AddOverlays("crystal_overcharge") - set_light(7, 3, l_color = "#a160bf") + set_light_range_power_color(4, 1.5, "#a160bf") else - set_light(6, 3, l_color = "#3e0000") + set_light_range_power_color(3, 1.5, "#3e0000") AddOverlays("crystal_turret") + set_light_on(TRUE) else if(!isbroken) - set_light(5, 2, l_color = "#3e0000") + set_light_range_power_color(2, 1, "#3e0000") + set_light_on(TRUE) AddOverlays("crystal_idle") if(pylonmode == PYLON_AWAITING_SACRIFICE) anchored = TRUE @@ -525,7 +528,7 @@ anchored = FALSE else anchored = FALSE - set_light(0) + set_light_on(FALSE) #undef PYLON_IDLE #undef PYLON_AWAITING_SACRIFICE diff --git a/code/game/gamemodes/endgame/supermatter_cascade/blob.dm b/code/game/gamemodes/endgame/supermatter_cascade/blob.dm index 1ae268a6e9d..2b9189c6bb4 100644 --- a/code/game/gamemodes/endgame/supermatter_cascade/blob.dm +++ b/code/game/gamemodes/endgame/supermatter_cascade/blob.dm @@ -49,7 +49,6 @@ STOP_PROCESSING(SScalamity, src) /turf/unsimulated/wall/supermatter/proc/after_tick(turf/T) - T.lighting_clear_overlay() for(var/atom/movable/A in T) if (A && A.simulated) // No eating lighting overlays. if(istype(A, /mob/living)) diff --git a/code/game/gamemodes/endgame/supermatter_cascade/universe.dm b/code/game/gamemodes/endgame/supermatter_cascade/universe.dm index 2c4ef0f095a..57113a482c2 100644 --- a/code/game/gamemodes/endgame/supermatter_cascade/universe.dm +++ b/code/game/gamemodes/endgame/supermatter_cascade/universe.dm @@ -107,14 +107,6 @@ The access requirements on the Asteroid Shuttles' consoles have now been revoked T.underlays += "end01" CHECK_TICK - for(var/datum/lighting_corner/C in SSlighting.lighting_corners) - if (!C.active) - continue - - if (isNotAdminLevel(C.z)) - C.update_lumcount(0.15, 0.15, 0.5) - CHECK_TICK - /datum/universal_state/supermatter_cascade/proc/MiscSet() for (var/obj/machinery/firealarm/alm in SSmachinery.processing) if (!(alm.stat & BROKEN)) diff --git a/code/game/gamemodes/technomancer/devices/shield_armor.dm b/code/game/gamemodes/technomancer/devices/shield_armor.dm index e4991504f78..4477cd4a66a 100644 --- a/code/game/gamemodes/technomancer/devices/shield_armor.dm +++ b/code/game/gamemodes/technomancer/devices/shield_armor.dm @@ -86,8 +86,9 @@ icon_state = "shield_armor_[active]" item_state = "shield_armor_[active]" if(active) - set_light(2, 1, l_color = "#006AFF") + set_light_range_power_color(2, 1, "#006AFF") + set_light_on(TRUE) else - set_light(0, 0, l_color = "#000000") + set_light_on(FALSE) ..() return diff --git a/code/game/gamemodes/technomancer/devices/tesla_armor.dm b/code/game/gamemodes/technomancer/devices/tesla_armor.dm index a8af9c013d6..b08d16e2e03 100644 --- a/code/game/gamemodes/technomancer/devices/tesla_armor.dm +++ b/code/game/gamemodes/technomancer/devices/tesla_armor.dm @@ -73,11 +73,12 @@ if(active && ready) icon_state = ready_icon_state item_state = ready_icon_state - set_light(2, 1, l_color = "#006AFF") + set_light_range_power_color(2, 1, "#006AFF") + set_light_on(TRUE) else icon_state = normal_icon_state item_state = normal_icon_state - set_light(0, 0, l_color = "#000000") + set_light_on(FALSE) if(ishuman(loc)) var/mob/living/carbon/human/H = loc diff --git a/code/game/gamemodes/technomancer/spell_objs.dm b/code/game/gamemodes/technomancer/spell_objs.dm index ca5a800aeb0..f49c84dd63c 100644 --- a/code/game/gamemodes/technomancer/spell_objs.dm +++ b/code/game/gamemodes/technomancer/spell_objs.dm @@ -34,6 +34,7 @@ throwforce = 0 force = 0 item_flags = ITEM_FLAG_NO_BLUDGEON + light_system = MOVABLE_LIGHT var/mob/living/carbon/human/owner var/obj/item/technomancer_core/core var/cast_methods = null // Controls how the spell is casted. diff --git a/code/game/gamemodes/technomancer/spells/aura/aura.dm b/code/game/gamemodes/technomancer/spells/aura/aura.dm index 5a9df276ff5..ba58e61609e 100644 --- a/code/game/gamemodes/technomancer/spells/aura/aura.dm +++ b/code/game/gamemodes/technomancer/spells/aura/aura.dm @@ -8,7 +8,8 @@ /obj/item/spell/aura/Initialize() . = ..() - set_light(calculate_spell_power(7), calculate_spell_power(4), l_color = glow_color) + set_light_range_power_color(calculate_spell_power(7), calculate_spell_power(4), glow_color) + set_light_on(TRUE) START_PROCESSING(SSprocessing, src) log_and_message_admins("has started casting [src].") diff --git a/code/game/gamemodes/technomancer/spells/chroma.dm b/code/game/gamemodes/technomancer/spells/chroma.dm index 1e43aaf33b8..6bf8961cb7b 100644 --- a/code/game/gamemodes/technomancer/spells/chroma.dm +++ b/code/game/gamemodes/technomancer/spells/chroma.dm @@ -17,7 +17,8 @@ /obj/item/spell/chroma/Initialize() . = ..() - set_light(6, 5, l_color = color_to_use) + set_light_range_power_color(6, 5, color_to_use) + set_light_on(TRUE) /obj/effect/temporary_effect/chroma name = "chroma" @@ -27,7 +28,8 @@ /obj/effect/temporary_effect/chroma/Initialize(var/mapload, var/new_color = "#FFFFFF") . = ..() - set_light(6, 5, l_color = new_color) + set_light_range_power_color(6, 5, new_color) + set_light_on(TRUE) /obj/item/spell/chroma/on_ranged_cast(atom/hit_atom, mob/user) . = ..() @@ -42,4 +44,4 @@ var/new_color = input(user, "Choose the color you want your light to be.", "Color selection") as null|color if(new_color) color_to_use = new_color - set_light(6, 5, l_color = new_color) + set_light_range_power_color(6, 5, new_color) diff --git a/code/game/gamemodes/technomancer/spells/flame_tongue.dm b/code/game/gamemodes/technomancer/spells/flame_tongue.dm index ec316d5ff6f..f82fb4943cf 100644 --- a/code/game/gamemodes/technomancer/spells/flame_tongue.dm +++ b/code/game/gamemodes/technomancer/spells/flame_tongue.dm @@ -16,7 +16,8 @@ /obj/item/spell/flame_tongue/Initialize() . = ..() - set_light(3, 2, l_color = "#FF6A00") + set_light_range_power_color(6, 5, "#FF6A00") + set_light_on(TRUE) visible_message(SPAN_WARNING("\The [loc]'s hand begins to emit a flame.")) welder = new /obj/item/weldingtool/spell(src) welder.setWelding(1) diff --git a/code/game/gamemodes/technomancer/spells/insert/insert.dm b/code/game/gamemodes/technomancer/spells/insert/insert.dm index ea92498923b..187c7d71477 100644 --- a/code/game/gamemodes/technomancer/spells/insert/insert.dm +++ b/code/game/gamemodes/technomancer/spells/insert/insert.dm @@ -13,7 +13,8 @@ /obj/item/spell/insert/New() ..() - set_light(spell_light_range, spell_light_intensity, l_color = light_color) + set_light_range_power_color(spell_light_range, spell_light_intensity, light_color) + set_light_on(TRUE) /obj/item/inserted_spell var/mob/living/carbon/human/origin = null @@ -24,8 +25,8 @@ ..(newloc) host = newloc origin = user - if(light_color) - set_light(inserter.spell_light_range, inserter.spell_light_intensity, inserter.spell_color) + if(light_color && inserter) + set_light_range_power_color(inserter.spell_light_range, inserter.spell_light_intensity, inserter.spell_color) on_insert() /obj/item/inserted_spell/proc/on_insert() diff --git a/code/game/gamemodes/technomancer/spells/instability_tap.dm b/code/game/gamemodes/technomancer/spells/instability_tap.dm index e68fdb8e6d1..b206f71feb3 100644 --- a/code/game/gamemodes/technomancer/spells/instability_tap.dm +++ b/code/game/gamemodes/technomancer/spells/instability_tap.dm @@ -16,7 +16,8 @@ /obj/item/spell/instability_tap/New() ..() - set_light(3, 2, l_color = "#FA58F4") + set_light_range_power_color(3, 2, "#FA58F4") + set_light_on(TRUE) /obj/item/spell/instability_tap/on_use_cast(mob/user) . = ..() diff --git a/code/game/gamemodes/technomancer/spells/mark_recall.dm b/code/game/gamemodes/technomancer/spells/mark_recall.dm index 89bead3c48e..0f7552122e5 100644 --- a/code/game/gamemodes/technomancer/spells/mark_recall.dm +++ b/code/game/gamemodes/technomancer/spells/mark_recall.dm @@ -78,13 +78,14 @@ GLOBAL_DATUM(mark_spell_ref, /obj/effect/mark_spell) var/time_left = 3 if(check_for_scepter()) time_left = 2 + set_light_on(TRUE) while(time_left) if(user.incapacitated()) visible_message(SPAN_NOTICE("\The [user]'s glow fades.")) to_chat(user, SPAN_DANGER("You cannot Recall while incapacitated!")) return 0 light_intensity++ - set_light(light_intensity, light_intensity, l_color = "#006AFF") + set_light_range_power_color(light_intensity, light_intensity, "#006AFF") time_left-- sleep(1 SECOND) diff --git a/code/game/gamemodes/technomancer/spells/modifier/modifier.dm b/code/game/gamemodes/technomancer/spells/modifier/modifier.dm index 5f7c621f63c..731379240f3 100644 --- a/code/game/gamemodes/technomancer/spells/modifier/modifier.dm +++ b/code/game/gamemodes/technomancer/spells/modifier/modifier.dm @@ -11,7 +11,8 @@ /obj/item/spell/modifier/Initialize() . = ..() - set_light(spell_light_range, spell_light_intensity, l_color = light_color) + set_light_range_power_color(spell_light_range, spell_light_intensity, light_color) + set_light_on(TRUE) /obj/item/spell/modifier/on_melee_cast(atom/hit_atom, mob/user) . = ..() diff --git a/code/game/gamemodes/technomancer/spells/phase_shift.dm b/code/game/gamemodes/technomancer/spells/phase_shift.dm index 7c1111cfe94..abd90986f29 100644 --- a/code/game/gamemodes/technomancer/spells/phase_shift.dm +++ b/code/game/gamemodes/technomancer/spells/phase_shift.dm @@ -17,7 +17,8 @@ /obj/item/spell/phase_shift/Initialize() . = ..() - set_light(3, 2, l_color = "#FA58F4") + set_light_range_power_color(3, 2, "#FA58F4") + set_light_on(TRUE) /obj/effect/phase_shift name = "rift" @@ -30,7 +31,8 @@ /obj/effect/phase_shift/Initialize(mapload, ...) . = ..() - set_light(3, 5, l_color = "#FA58F4") + set_light_range_power_color(3, 5, "#FA58F4") + set_light_on(TRUE) START_PROCESSING(SSprocessing, src) /obj/effect/phase_shift/Destroy() diff --git a/code/game/gamemodes/technomancer/spells/radiance.dm b/code/game/gamemodes/technomancer/spells/radiance.dm index 59b84fd0dde..63c97f548f2 100644 --- a/code/game/gamemodes/technomancer/spells/radiance.dm +++ b/code/game/gamemodes/technomancer/spells/radiance.dm @@ -17,9 +17,10 @@ var/power = 250 toggled = 1 -/obj/item/spell/radiance/New() - ..() - set_light(7, 4, l_color = "#D9D900") +/obj/item/spell/radiance/Initialize() + . = ..() + set_light_range_power_color(7, 4, "#D9D900") + set_light_on(TRUE) START_PROCESSING(SSprocessing, src) log_and_message_admins("has casted [src].") diff --git a/code/game/gamemodes/technomancer/spells/reflect.dm b/code/game/gamemodes/technomancer/spells/reflect.dm index 626fa079a6d..c5814ba1729 100644 --- a/code/game/gamemodes/technomancer/spells/reflect.dm +++ b/code/game/gamemodes/technomancer/spells/reflect.dm @@ -17,7 +17,8 @@ /obj/item/spell/reflect/Initialize() . = ..() - set_light(3, 2, l_color = "#006AFF") + set_light_range_power_color(3, 2, "#006AFF") + set_light_on(TRUE) to_chat(owner, SPAN_NOTICE("Your shield will expire in 5 seconds!")) QDEL_IN(src, 5 SECONDS) diff --git a/code/game/gamemodes/technomancer/spells/shield.dm b/code/game/gamemodes/technomancer/spells/shield.dm index 54835aeefdd..2135877ddea 100644 --- a/code/game/gamemodes/technomancer/spells/shield.dm +++ b/code/game/gamemodes/technomancer/spells/shield.dm @@ -19,7 +19,8 @@ /obj/item/spell/shield/Initialize() . = ..() - set_light(3, 2, l_color = "#006AFF") + set_light_range_power_color(3, 2, "#006AFF") + set_light_on(TRUE) /obj/item/spell/shield/update_icon() var/mob/living/carbon/human/H = owner diff --git a/code/game/gamemodes/technomancer/spells/spawner/darkness.dm b/code/game/gamemodes/technomancer/spells/spawner/darkness.dm index 07b4a4bfd3c..4037ff4a045 100644 --- a/code/game/gamemodes/technomancer/spells/spawner/darkness.dm +++ b/code/game/gamemodes/technomancer/spells/spawner/darkness.dm @@ -21,7 +21,8 @@ /obj/item/spell/spawner/darkness/New() ..() - set_light(6, -20, l_color = "#FFFFFF") + set_light_range_power_color(6, -20, "#FFFFFF") + set_light_on(TRUE) /obj/effect/temporary_effect/darkness name = "darkness" diff --git a/code/game/gamemodes/technomancer/spells/spawner/destablize.dm b/code/game/gamemodes/technomancer/spells/spawner/destablize.dm index c44aa5e25aa..480bfbc7929 100644 --- a/code/game/gamemodes/technomancer/spells/spawner/destablize.dm +++ b/code/game/gamemodes/technomancer/spells/spawner/destablize.dm @@ -17,7 +17,8 @@ /obj/item/spell/spawner/destabilize/New() ..() - set_light(3, 2, l_color = "#C26DDE") + set_light_range_power_color(3, 2, "#C26DDE") + set_light_on(TRUE) /obj/item/spell/spawner/destabilize/on_ranged_cast(atom/hit_atom, mob/user) if(within_range(hit_atom) && pay_energy(2000)) diff --git a/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm b/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm index b2c428e420e..82f8fa3f584 100644 --- a/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm +++ b/code/game/gamemodes/technomancer/spells/spawner/pulsar.dm @@ -16,7 +16,8 @@ /obj/item/spell/spawner/pulsar/New() ..() - set_light(3, 2, l_color = "#2ECCFA") + set_light_range_power_color(3, 2, "#2ECCFA") + set_light_on(TRUE) /obj/item/spell/spawner/pulsar/on_ranged_cast(atom/hit_atom, mob/user) if(within_range(hit_atom) && pay_energy(4000)) diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index bb7616d38b5..3fc517cbe24 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -115,7 +115,6 @@ pixel_x = 10; clicksound = /singleton/sound_category/button_sound clickvol = 30 obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - z_flags = ZMM_MANGLE_PLANES var/alarm_id = null var/frequency = 1439 @@ -583,7 +582,7 @@ pixel_x = 10; alarm_overlay = image(icon, "alarm[icon_level]") AddOverlays(alarm_overlay) - var/emissive_overlay = emissive_appearance(icon, "alarm[icon_level]") + emissive_overlay = emissive_appearance(icon, "alarm[icon_level]") AddOverlays(emissive_overlay) var/new_color = null @@ -595,7 +594,8 @@ pixel_x = 10; if (2) new_color = COLOR_RED_LIGHT - set_light(l_range = L_WALLMOUNT_RANGE, l_power = L_WALLMOUNT_POWER, l_color = new_color) + if(light_color != new_color) + set_light(L_WALLMOUNT_RANGE, L_WALLMOUNT_POWER, new_color) if(regulating_temperature) AddOverlays("alarm_fan_on") diff --git a/code/game/machinery/atmoalter/canister.dm b/code/game/machinery/atmoalter/canister.dm index 75973b7e3eb..302f4817b49 100644 --- a/code/game/machinery/atmoalter/canister.dm +++ b/code/game/machinery/atmoalter/canister.dm @@ -3,7 +3,8 @@ desc = "Holds gas. Has a built-in valve to allow for filling portable tanks." icon = 'icons/obj/atmos.dmi' icon_state = "yellow" - density = 1 + density = TRUE + light_system = MOVABLE_LIGHT var/health = 100.0 obj_flags = OBJ_FLAG_SIGNALER | OBJ_FLAG_CONDUCTABLE w_class = WEIGHT_CLASS_HUGE @@ -301,7 +302,7 @@ update_flag if (src.destroyed) ClearOverlays() - set_light(FALSE) + set_light_on(FALSE) src.icon_state = "[src.canister_color]-1" return @@ -312,7 +313,6 @@ update_flag return ClearOverlays() - set_light(FALSE) if(signaler) AddOverlays("signaler") @@ -324,19 +324,23 @@ update_flag if(update_flag & 4) var/mutable_appearance/indicator_overlay = mutable_appearance(icon, "can-o0", plane = ABOVE_LIGHTING_PLANE) AddOverlays(indicator_overlay) - set_light(1.4, 1, COLOR_RED_LIGHT) + set_light_range_power_color(0.5, 0.5, COLOR_RED_LIGHT) + set_light_on(TRUE) if(update_flag & 8) var/mutable_appearance/indicator_overlay = mutable_appearance(icon, "can-o1", plane = ABOVE_LIGHTING_PLANE) AddOverlays(indicator_overlay) - set_light(1.4, 1, COLOR_RED_LIGHT) + set_light_range_power_color(0.5, 0.5, COLOR_RED_LIGHT) + set_light_on(TRUE) else if(update_flag & 16) var/mutable_appearance/indicator_overlay = mutable_appearance(icon, "can-o2", plane = ABOVE_LIGHTING_PLANE) AddOverlays(indicator_overlay) - set_light(1.4, 1, COLOR_YELLOW) + set_light_range_power_color(0.5, 0.5, COLOR_YELLOW) + set_light_on(TRUE) else if(update_flag & 32) var/mutable_appearance/indicator_overlay = mutable_appearance(icon, "can-o3", plane = ABOVE_LIGHTING_PLANE) AddOverlays(indicator_overlay) - set_light(1.4, 1, COLOR_BRIGHT_GREEN) + set_light_range_power_color(0.5, 0.5, COLOR_BRIGHT_GREEN) + set_light_on(TRUE) /obj/machinery/portable_atmospherics/canister/fire_act(exposed_temperature, exposed_volume) . = ..() diff --git a/code/game/machinery/body_scanner.dm b/code/game/machinery/body_scanner.dm index a3e9b40ce19..8207fc84a39 100644 --- a/code/game/machinery/body_scanner.dm +++ b/code/game/machinery/body_scanner.dm @@ -261,7 +261,6 @@ var/has_external_injuries = FALSE density = FALSE anchored = TRUE - z_flags = ZMM_MANGLE_PLANES component_types = list( /obj/item/circuitboard/bodyscannerconsole, /obj/item/stock_parts/scanning_module = 2, diff --git a/code/game/machinery/bots/bots.dm b/code/game/machinery/bots/bots.dm index 6eba6b53b97..c1537172578 100644 --- a/code/game/machinery/bots/bots.dm +++ b/code/game/machinery/bots/bots.dm @@ -5,6 +5,7 @@ layer = MOB_LAYER light_range = 3 use_power = POWER_USE_OFF + light_system = MOVABLE_LIGHT var/obj/item/card/id/botcard // the ID card that the bot "holds" var/on = 1 var/health = 0 //do not forget to set health for your bot! @@ -33,14 +34,14 @@ return ..() /obj/machinery/bot/proc/turn_on() - if(stat) return 0 + if(stat) + return 0 on = 1 - set_light(initial(light_range)) - return 1 + set_light_on(on) /obj/machinery/bot/proc/turn_off() on = 0 - set_light(0) + set_light_on(on) /obj/machinery/bot/proc/explode() qdel(src) diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index 9de9b2de0cc..3bb652e0087 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -8,7 +8,6 @@ idle_power_usage = 300 active_power_usage = 300 clicksound = /singleton/sound_category/keyboard_sound - z_flags = ZMM_MANGLE_PLANES var/circuit = null //The path to the circuit board type. If circuit==null, the computer can't be disassembled. var/processing = 0 diff --git a/code/game/machinery/crusher_piston.dm b/code/game/machinery/crusher_piston.dm index 65481df4431..64d6a60fa25 100644 --- a/code/game/machinery/crusher_piston.dm +++ b/code/game/machinery/crusher_piston.dm @@ -11,7 +11,6 @@ opacity = 1 //Just 300 Watts here. Power is drawn by the piston when it moves idle_power_usage = 300 - z_flags = ZMM_MANGLE_PLANES var/obj/machinery/crusher_piston/pstn //Piston @@ -158,7 +157,6 @@ icon_state = asmtype var/image_overlay - var/emissive_overlay if(powered(AREA_USAGE_EQUIP)) if(blocked == 1) image_overlay = image(icon, "[asmtype]-overlay-red") diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index 345f365cb9f..1bbc2e5ddbd 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -9,7 +9,6 @@ anchored = TRUE layer = ABOVE_HUMAN_LAYER interact_offline = TRUE - z_flags = ZMM_MANGLE_PLANES var/on = 0 idle_power_usage = 20 diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index f39f9d72762..a49f183b863 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -79,7 +79,7 @@ var/area/A = get_area(src) if(A.fire) AddOverlays("fire1") - set_light(l_range = L_WALLMOUNT_HI_RANGE, l_power = L_WALLMOUNT_HI_POWER, l_color = COLOR_RED) + set_light(L_WALLMOUNT_HI_RANGE, L_WALLMOUNT_HI_POWER, COLOR_RED) else AddOverlays("fire0") set_light(0) diff --git a/code/game/machinery/floodlight.dm b/code/game/machinery/floodlight.dm index e4157be33e2..59f9384a61c 100644 --- a/code/game/machinery/floodlight.dm +++ b/code/game/machinery/floodlight.dm @@ -6,14 +6,15 @@ icon_state = "flood00" density = TRUE obj_flags = OBJ_FLAG_ROTATABLE + light_system = MOVABLE_LIGHT + light_range = 6 + light_color = LIGHT_COLOR_TUNGSTEN + var/on = FALSE var/obj/item/cell/cell = null var/use = 200 // 200W light var/unlocked = FALSE var/open = FALSE - var/brightness_on = 12 //can't remember what the maxed out value is - light_color = LIGHT_COLOR_TUNGSTEN - light_wedge = LIGHT_WIDE /obj/machinery/floodlight/feedback_hints(mob/user, distance, is_adjacent) . += ..() @@ -42,14 +43,14 @@ // If the cell is almost empty rarely "flicker" the light. Aesthetic only. if((cell.percent() < 10) && prob(5)) - set_light(brightness_on/3, 0.5) + set_light_range_power_color(light_range/3, 0.5, light_color) addtimer(CALLBACK(src, PROC_REF(stop_flicker)), 5, TIMER_UNIQUE) cell.use(use*CELLRATE) /obj/machinery/floodlight/proc/stop_flicker() if(on) - set_light(brightness_on, 1) + set_light_range_power_color(light_range, 1, light_color) // Returns 0 on failure and 1 on success /obj/machinery/floodlight/proc/turn_on(var/loud = FALSE) @@ -59,7 +60,7 @@ return FALSE on = TRUE - set_light(brightness_on, 1) + set_light_on(on) update_icon() if(loud) visible_message(SPAN_NOTICE("\The [src] turns on.")) @@ -67,7 +68,7 @@ /obj/machinery/floodlight/proc/turn_off(var/loud = FALSE) on = FALSE - set_light(0) + set_light_on(on) update_icon() if(loud) visible_message(SPAN_NOTICE("\The [src] shuts down.")) diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index a879bfe0774..96b8abb4ac2 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -12,8 +12,6 @@ var/area/area = null var/otherarea = null power_channel = AREA_USAGE_LIGHT - z_flags = ZMM_MANGLE_PLANES - // luminosity = 1 /obj/machinery/light_switch/feedback_hints(mob/user, distance, is_adjacent) . += ..() @@ -39,7 +37,7 @@ ClearOverlays() if(!(stat & NOPOWER)) var/switch_overlay = image(icon, "light[on]-overlay") - var/emissive_overlay = emissive_appearance(icon, "light[on]-overlay") + emissive_overlay = emissive_appearance(icon, "light[on]-overlay") AddOverlays(switch_overlay) AddOverlays(emissive_overlay) if (!light_range || light_color != on ? "#82ff4c" : "#f86060") diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index dce87018ba8..f9cc8e29de2 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -29,7 +29,6 @@ GLOBAL_LIST_INIT_TYPED(allCasters, /obj/machinery/newscaster, list()) anchored = TRUE appearance_flags = TILE_BOUND // prevents people from viewing the overlay through a wall obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - z_flags = ZMM_MANGLE_PLANES ///If the newscaster is broken, boolean var/isbroken = FALSE @@ -169,7 +168,7 @@ GLOBAL_LIST_INIT_TYPED(allCasters, /obj/machinery/newscaster, list()) screen_hologram.blend_mode = BLEND_MULTIPLY screen.blend_mode = BLEND_ADD AddOverlays(list(screen_hologram, screen, screen_emis)) - set_light(1.4, 1.3, COLOR_CYAN) + set_light(L_WALLMOUNT_RANGE, L_WALLMOUNT_POWER, COLOR_CYAN) if(!alert || !SSnews.wanted_issue) var/mutable_appearance/screen_title = overlay_image(icon, "newscaster-title") diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index ca1a5609899..8f775b048ba 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -201,6 +201,7 @@ spark_system = null if(fast_processing) STOP_PROCESSING(SSfast_process, src) + QDEL_NULL(installation) clear_from_target_grid() diff --git a/code/game/machinery/requests_console.dm b/code/game/machinery/requests_console.dm index c67031a4e2f..f521f51b099 100644 --- a/code/game/machinery/requests_console.dm +++ b/code/game/machinery/requests_console.dm @@ -63,7 +63,6 @@ GLOBAL_LIST_INIT_TYPED(allConsoles, /obj/machinery/requests_console, list()) ) anchored = TRUE appearance_flags = TILE_BOUND // prevents people from viewing the overlay through a wall - z_flags = ZMM_MANGLE_PLANES ///The list of all departments on the station (Determined from this variable on each unit) Set this to the same thing if you want several consoles in one department var/department = "Unknown" @@ -162,16 +161,16 @@ GLOBAL_LIST_INIT_TYPED(allConsoles, /obj/machinery/requests_console, list()) switch(newmessagepriority) if(0) screen = overlay_image(icon, "req_comp-idle") - set_light(1.4, 1.3, COLOR_CYAN) + set_light(L_WALLMOUNT_RANGE, L_WALLMOUNT_POWER, COLOR_CYAN) if(1) screen = overlay_image(icon, "req_comp-alert") - set_light(1.4, 1.3, COLOR_CYAN) + set_light(L_WALLMOUNT_RANGE, L_WALLMOUNT_POWER, COLOR_CYAN) if(2) screen = overlay_image(icon, "req_comp-redalert") - set_light(1.4, 1.3, COLOR_ORANGE) + set_light(L_WALLMOUNT_RANGE,L_WALLMOUNT_POWER, COLOR_ORANGE) if(3) screen = overlay_image(icon, "req_comp-yellowalert") - set_light(1.4, 1.3, COLOR_ORANGE) + set_light(L_WALLMOUNT_RANGE, L_WALLMOUNT_POWER, COLOR_ORANGE) AddOverlays(screen_hologram) AddOverlays(screen) AddOverlays(screen_emis) diff --git a/code/game/machinery/ringer.dm b/code/game/machinery/ringer.dm index a72f8e1143e..35b05ce2052 100644 --- a/code/game/machinery/ringer.dm +++ b/code/game/machinery/ringer.dm @@ -21,7 +21,6 @@ pixel_x = 8; icon_state = "bell" anchored = TRUE appearance_flags = TILE_BOUND // prevents people from viewing the overlay through a wall - z_flags = ZMM_MANGLE_PLANES req_access = list() //what access it needs to link your pda @@ -100,15 +99,15 @@ pixel_x = 8; return if(rings_pdas || rings_pdas.len) screen = overlay_image(icon, "bell-active") - set_light(1.4, 1, COLOR_CYAN) + set_light(L_WALLMOUNT_POWER, L_WALLMOUNT_RANGE, COLOR_CYAN) if(pinged) screen = overlay_image(icon, "bell-alert") - set_light(1.4, 1, COLOR_CYAN) + set_light(L_WALLMOUNT_POWER, L_WALLMOUNT_RANGE, COLOR_CYAN) if(on) AddOverlays("bell-scanline") else screen = overlay_image(icon, "bell-standby") - set_light(1.4, 1, COLOR_CYAN) + set_light(L_WALLMOUNT_POWER, L_WALLMOUNT_RANGE, COLOR_CYAN) AddOverlays(screen_hologram) AddOverlays(screen) AddOverlays(screen_emis) diff --git a/code/game/machinery/rotating_alarm.dm b/code/game/machinery/rotating_alarm.dm index 1941597242e..c8ce3cb7e5f 100644 --- a/code/game/machinery/rotating_alarm.dm +++ b/code/game/machinery/rotating_alarm.dm @@ -113,5 +113,5 @@ set_light(0) else vis_contents += spin_effect - set_light(2, 0.5, alarm_light_color) + set_light(2, 1, alarm_light_color) on = !on diff --git a/code/game/machinery/status_display.dm b/code/game/machinery/status_display.dm index cbf072804d8..6f74ca24791 100644 --- a/code/game/machinery/status_display.dm +++ b/code/game/machinery/status_display.dm @@ -222,7 +222,7 @@ ) set_light(0) return - set_light(1.5, 0.7, LIGHT_COLOR_FAINT_CYAN) // blue light + set_light(L_WALLMOUNT_RANGE, L_WALLMOUNT_POWER, LIGHT_COLOR_FAINT_CYAN) // blue light /obj/machinery/status_display/proc/get_shuttle_timer() var/timeleft = GLOB.evacuation_controller.get_eta() diff --git a/code/game/machinery/suit_cycler.dm b/code/game/machinery/suit_cycler.dm index df59efe5f7a..06bdbe49bbc 100644 --- a/code/game/machinery/suit_cycler.dm +++ b/code/game/machinery/suit_cycler.dm @@ -35,7 +35,6 @@ icon_state = "base" req_access = list(ACCESS_CAPTAIN, ACCESS_HEADS) - z_flags = ZMM_MANGLE_PLANES /// PLEASE HOLD. var/active = FALSE /// The cycler won't start with a living thing inside it unless safeties are off. diff --git a/code/game/machinery/vending/_vending.dm b/code/game/machinery/vending/_vending.dm index 2091fa3c244..43e6b22e15b 100644 --- a/code/game/machinery/vending/_vending.dm +++ b/code/game/machinery/vending/_vending.dm @@ -63,7 +63,6 @@ density = 1 clicksound = /singleton/sound_category/button_sound manufacturer = "idris" - z_flags = ZMM_MANGLE_PLANES // Every vending machine has one of these. /// `icon_state` when off. Defined on init. diff --git a/code/game/objects/auras/radiant_aura.dm b/code/game/objects/auras/radiant_aura.dm index 39818bfe880..e1eaca1e062 100644 --- a/code/game/objects/auras/radiant_aura.dm +++ b/code/game/objects/auras/radiant_aura.dm @@ -13,7 +13,8 @@ /obj/aura/radiant_aura/added_to(mob/living/user) ..() to_chat(user, SPAN_NOTICE("A bubble of light appears around you, exuding protection and warmth.")) - set_light(6, 6, COLOR_AMBER) + set_light_range_power_color(6, 6, COLOR_AMBER) + set_light_on(TRUE) /obj/aura/radiant_aura/Destroy() to_chat(user, SPAN_WARNING("Your protective aura dissipates, leaving you feeling cold and unsafe.")) diff --git a/code/game/objects/effects/decals/Cleanable/misc.dm b/code/game/objects/effects/decals/Cleanable/misc.dm index 3b2636bc55c..23371daa6c7 100644 --- a/code/game/objects/effects/decals/Cleanable/misc.dm +++ b/code/game/objects/effects/decals/Cleanable/misc.dm @@ -50,7 +50,6 @@ light_range = 2 light_power = 0.5 light_color = LIGHT_COLOR_GREEN - uv_intensity = 0 icon = 'icons/effects/effects.dmi' icon_state = "greenglow" diff --git a/code/game/objects/effects/decals/misc.dm b/code/game/objects/effects/decals/misc.dm index acfad0f687a..2907949596a 100644 --- a/code/game/objects/effects/decals/misc.dm +++ b/code/game/objects/effects/decals/misc.dm @@ -51,7 +51,7 @@ /obj/effect/decal/fake_object/light_source/Initialize() .=..() - set_light() + set_light(light_power, light_range, light_color) /obj/effect/decal/fake_object/light_source/invisible simulated = 0 diff --git a/code/game/objects/effects/effect_system.dm b/code/game/objects/effects/effect_system.dm index 5f2f869b07e..b764bc8b382 100644 --- a/code/game/objects/effects/effect_system.dm +++ b/code/game/objects/effects/effect_system.dm @@ -122,6 +122,11 @@ would spawn and follow the beaker, even if it is carried or thrown. AddElement(/datum/element/connect_loc, loc_connections) +/obj/effect/smoke/Destroy() + if(opacity) + set_opacity(FALSE) + return ..() + /obj/effect/smoke/proc/kill() animate(src, alpha = 0, time = 2 SECONDS, easing = QUAD_EASING) set_opacity(FALSE) @@ -157,7 +162,7 @@ would spawn and follow the beaker, even if it is carried or thrown. icon = 'icons/effects/effects.dmi' icon_state = "sparks" -/obj/effect/smoke/illumination/New(var/newloc, var/brightness=15, var/lifetime=10) +/obj/effect/smoke/illumination/New(var/newloc, var/brightness=15, var/lifetime=5) time_to_live=lifetime ..() set_light(brightness) diff --git a/code/game/objects/effects/shockwave.dm b/code/game/objects/effects/shockwave.dm index d100de1dba0..9f8280b9fb2 100644 --- a/code/game/objects/effects/shockwave.dm +++ b/code/game/objects/effects/shockwave.dm @@ -4,7 +4,7 @@ /obj/effect/shockwave - icon = 'icons/effects/shockwave.dmi' + icon = 'icons/effects/light_overlays/shockwave.dmi' icon_state = "shockwave" mouse_opacity = MOUSE_OPACITY_TRANSPARENT plane = DISPLACEMENT_PLATE_RENDER_LAYER diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 5342f40a722..fad88c059e9 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -2,6 +2,7 @@ name = "item" icon = 'icons/obj/items.dmi' w_class = WEIGHT_CLASS_NORMAL + light_system = MOVABLE_LIGHT blocks_emissive = EMISSIVE_BLOCK_GENERIC /// This saves our blood splatter overlay, which will be processed not to go over the edges of the sprite @@ -491,9 +492,6 @@ SEND_SIGNAL(src, COMSIG_ITEM_DROPPED, user) in_inventory = FALSE - if(user && (z_flags & ZMM_MANGLE_PLANES)) - addtimer(CALLBACK(user, /mob/proc/check_emissive_equipment), 0, TIMER_UNIQUE) - user?.update_equipment_speed_mods() try_make_persistent_trash() @@ -629,9 +627,6 @@ //Äšent for observable SEND_SIGNAL(src, COMSIG_ITEM_REMOVE, src) - if(user && (z_flags & ZMM_MANGLE_PLANES)) - addtimer(CALLBACK(user, /mob/proc/check_emissive_equipment), 0, TIMER_UNIQUE) - user.update_equipment_speed_mods() if(persistency_considered_trash || persistence_track_active) // The moment trash like items get picked up they are no longer persistent diff --git a/code/game/objects/items/devices/lighting/flare.dm b/code/game/objects/items/devices/lighting/flare.dm index 3116061917a..fe31d2f4dd7 100644 --- a/code/game/objects/items/devices/lighting/flare.dm +++ b/code/game/objects/items/devices/lighting/flare.dm @@ -2,17 +2,15 @@ name = "flare" desc = "A red standard-issue flare. There are instructions on the side reading 'twist cap off, make light'." w_class = WEIGHT_CLASS_TINY - brightness_on = 5 // Pretty bright. + light_range = 5 // Pretty bright. light_power = 6 light_color = LIGHT_COLOR_FLARE //"#E58775" icon_state = "flare" item_state = "flare" action_button_name = null //just pull it manually, neckbeard. var/fuel = 0 - uv_intensity = 100 var/on_damage = 7 var/produce_heat = 1500 - light_wedge = LIGHT_OMNI power_use = FALSE activation_sound = 'sound/items/flare.ogg' toggle_sound = null @@ -77,6 +75,7 @@ SPAN_NOTICE("\The [src] sputters out.") ) update_icon() + set_light_on(on) /obj/item/device/flashlight/flare/proc/update_damage() if(on) @@ -90,12 +89,11 @@ name = "torch" desc = "A rustic source of light." w_class = WEIGHT_CLASS_BULKY - brightness_on = 2 + light_range = 2 light_power = 3 light_color = LIGHT_COLOR_FIRE icon_state = "torch" item_state = "torch" - uv_intensity = 40 produce_heat = 1000 on_damage = 10 @@ -121,12 +119,12 @@ H.update_inv_l_hand() H.update_inv_r_hand() - /obj/item/device/flashlight/flare/torch/proc/light(mob/user) user.visible_message(SPAN_NOTICE("\The [user] lights \the [src]."), SPAN_NOTICE("You light \the [src].")) force = on_damage damtype = "fire" on = TRUE + set_light_on(on) START_PROCESSING(SSprocessing, src) update_icon() @@ -177,7 +175,7 @@ /obj/item/device/flashlight/flare/torch/stick name = "flaming stick" desc = "How exciting!" - brightness_on = 1.5 + light_range = 1.5 light_power = 1 produce_heat = 400 diff --git a/code/game/objects/items/devices/lighting/flashlight.dm b/code/game/objects/items/devices/lighting/flashlight.dm index 3f3f444672e..a9a908542ed 100644 --- a/code/game/objects/items/devices/lighting/flashlight.dm +++ b/code/game/objects/items/devices/lighting/flashlight.dm @@ -8,16 +8,14 @@ obj_flags = OBJ_FLAG_CONDUCTABLE slot_flags = SLOT_BELT light_color = LIGHT_COLOR_HALOGEN - uv_intensity = 50 - light_wedge = LIGHT_WIDE + light_system = DIRECTIONAL_LIGHT + light_range = 4 matter = list(MATERIAL_PLASTIC = 50, MATERIAL_GLASS = 20) action_button_name = "Toggle Flashlight" /// Is the light currently on or off? var/on = FALSE - /// Luminosity when on - var/brightness_on = 4 // Lighting power when on var/flashlight_power = 0.8 /// Sound the light makes when it's switched @@ -55,36 +53,29 @@ . += "\The [src] is set to [brightness_level]." if(cell) . += "\The [src] has \a [cell] attached. It has [round(cell.percent())]% charge remaining." - if(light_wedge && isturf(loc)) - . += SPAN_NOTICE("\The [src] is facing [dir2text(dir)].") /obj/item/device/flashlight/Initialize() if(power_use && cell_type) if(starts_with_cell) cell = new cell_type(src) - brightness_levels = list("low" = 1/32, "medium" = 1/16, "high" = 1/8) // ~26 minutes at high power with a device cell. - power_usage = (brightness_levels[brightness_level] / efficiency_modifier) + brightness_levels = list("low" = 2, "medium" = 3, "high" = 4) + power_usage = ((brightness_levels[brightness_level]/ 10 ) / efficiency_modifier) else verbs -= /obj/item/device/flashlight/verb/toggle_brightness if (on) if(brightness_level == "low") - light_range = brightness_on * 0.5 + light_range = light_range * 0.5 else if(brightness_level == "high") - light_range = brightness_on * 1.5 + light_range = light_range * 1.5 else - light_range = brightness_on + light_range = light_range update_icon() + set_light_on(on) . = ..() - if(light_wedge) - set_dir(pick(NORTH, SOUTH, EAST, WEST)) - if(spawn_dir) - set_dir(spawn_dir) - update_light() - /obj/item/device/flashlight/Destroy() STOP_PROCESSING(SSprocessing, src) QDEL_NULL(cell) @@ -96,7 +87,7 @@ /obj/item/device/flashlight/proc/set_brightness(mob/user) var/choice = tgui_input_list(user, "Choose a brightness level.", "Flashlight", brightness_levels) if(choice) - brightness_level = choice + set_light_range(brightness_levels[choice]) power_usage = brightness_levels[choice] to_chat(user, SPAN_NOTICE("You set the brightness level on \the [src] to [brightness_level].")) update_icon() @@ -120,15 +111,8 @@ if(on) icon_state = "[initial(icon_state)]-on" - if(brightness_level == "low") - set_light(brightness_on * 0.5, flashlight_power * 0.75, light_color) - else if(brightness_level == "high") - set_light(brightness_on * 1.5, flashlight_power * 1.1, light_color) - else - set_light(brightness_on, flashlight_power, light_color) else icon_state = "[initial(icon_state)]" - set_light(0) if (ismob(src.loc)) //for reasons, this makes headlights work. var/mob/M = src.loc M.update_inv_l_ear() @@ -198,24 +182,12 @@ START_PROCESSING(SSprocessing, src) else if (power_use) STOP_PROCESSING(SSprocessing, src) + set_light_on(on) update_icon() /obj/item/device/flashlight/vendor_action(var/obj/machinery/vending/V) toggle() -/obj/item/device/flashlight/dropped(mob/user) - . = ..() - if(light_wedge) - set_dir(user.dir) - update_light() - -/obj/item/device/flashlight/throw_at(atom/target, range, speed, thrower, do_throw_animation) - . = ..() - if(light_wedge) - var/new_dir = pick(NORTH, SOUTH, EAST, WEST) - set_dir(new_dir) - update_light() - /obj/item/device/flashlight/emp_act(severity) . = ..() @@ -229,7 +201,7 @@ if(((user.is_clumsy()) || (user.mutations & DUMB)) && prob(50)) //too dumb to use flashlight properly return ..() //just hit them in the head - if(brightness_on < 2) + if(light_range < 2) to_chat(user, SPAN_WARNING("This light is too dim to see anything with!")) return @@ -253,7 +225,7 @@ inspect_vision(vision, user) user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) //can be used offensively - if (!(brightness_on < 2)) + if (!(light_range < 2)) H.flash_act(length = 1 SECOND) else return ..() @@ -312,9 +284,8 @@ pickup_sound = 'sound/items/pickup/accessory.ogg' obj_flags = OBJ_FLAG_CONDUCTABLE slot_flags = SLOT_EARS - brightness_on = 2 + light_range = 2 w_class = WEIGHT_CLASS_TINY - light_wedge = LIGHT_OMNI /obj/item/device/flashlight/drone name = "low-power flashlight" @@ -322,7 +293,7 @@ icon_state = "penlight" item_state = "" obj_flags = OBJ_FLAG_CONDUCTABLE - brightness_on = 2 + light_range = 2 efficiency_modifier = 2 w_class = WEIGHT_CLASS_TINY @@ -331,11 +302,9 @@ desc = "A high-luminosity flashlight, for specialist duties." icon_state = "heavyflashlight" item_state = "heavyflashlight" - brightness_on = 4 + light_range = 4 w_class = WEIGHT_CLASS_NORMAL - uv_intensity = 60 matter = list(MATERIAL_PLASTIC = 100, MATERIAL_GLASS = 70) - light_wedge = LIGHT_SEMI /obj/item/device/flashlight/heavy/on on = TRUE @@ -346,14 +315,12 @@ icon_state = "maglight" item_state = "maglight" force = 9 - brightness_on = 5 + light_range = 5 efficiency_modifier = 0.8 w_class = WEIGHT_CLASS_NORMAL - uv_intensity = 70 attack_verb = list("slammed", "whacked", "bashed", "thunked", "battered", "bludgeoned", "thrashed") matter = list(MATERIAL_ALUMINIUM = 200, MATERIAL_GLASS = 100) hitsound = 'sound/weapons/smash.ogg' - light_wedge = LIGHT_NARROW /obj/item/device/flashlight/maglight/update_icon() ..() @@ -373,13 +340,12 @@ icon_state = "yellow slime extract" item_state = "flashlight" w_class = WEIGHT_CLASS_TINY - brightness_on = 6 - uv_intensity = 200 + light_range = 6 on = TRUE //Bio-luminesence has one setting, on. always_on = TRUE power_usage = FALSE light_color = LIGHT_COLOR_SLIME_LAMP - light_wedge = LIGHT_OMNI + light_system = MOVABLE_LIGHT /obj/item/device/flashlight/headlights name = "headlights" @@ -388,9 +354,8 @@ item_state = "headlights" obj_flags = OBJ_FLAG_CONDUCTABLE slot_flags = SLOT_HEAD | SLOT_EARS - brightness_on = 2 + light_range = 2 w_class = WEIGHT_CLASS_TINY - light_wedge = LIGHT_WIDE body_parts_covered = 0 /******************************Lantern*******************************/ @@ -403,11 +368,11 @@ attack_verb = list("bludgeoned, bashed, whacked") matter = list(MATERIAL_STEEL = 200,MATERIAL_GLASS = 100) flashlight_power = 1 - brightness_on = 4 + light_range = 4 cell_type = /obj/item/cell accepts_large_cells = TRUE - light_wedge = LIGHT_OMNI light_color = LIGHT_COLOR_FIRE + light_system = MOVABLE_LIGHT /obj/item/device/flashlight/lantern/update_icon() ..() diff --git a/code/game/objects/items/devices/lighting/glowstick.dm b/code/game/objects/items/devices/lighting/glowstick.dm index 5c2eba0aec4..2d721010c46 100644 --- a/code/game/objects/items/devices/lighting/glowstick.dm +++ b/code/game/objects/items/devices/lighting/glowstick.dm @@ -2,21 +2,20 @@ name = "green glowstick" desc = "A green military-grade glowstick." w_class = WEIGHT_CLASS_SMALL - brightness_on = 1.2 + light_system = MOVABLE_LIGHT + light_range = 1.2 flashlight_power = 2 light_color = "#49F37C" icon_state = "glowstick" item_state = "glowstick" produce_heat = 0 - uv_intensity = 255 - light_wedge = LIGHT_OMNI activation_sound = 'sound/items/glowstick.ogg' toggle_sound = null /obj/item/device/flashlight/flare/glowstick/Initialize() . = ..() fuel = rand(9 MINUTES, 12 MINUTES) - light_color = color + set_light_color(color) /obj/item/device/flashlight/flare/glowstick/process() fuel = max(fuel - 1, 0) @@ -30,14 +29,15 @@ overlays.Cut() if(!fuel) icon_state = "[initial(icon_state)]-empty" - set_light(0) + set_light_on(0) else if(on) var/image/I = overlay_image(icon, "glowstick-overlay", color) I.blend_mode = BLEND_ADD AddOverlays(I) icon_state = "[initial(icon_state)]-on" item_state = "[initial(icon_state)]-on" - set_light(brightness_on, flashlight_power, light_color) + set_light_range_power_color(light_range, flashlight_power, light_color) + set_light_on(on) else icon_state = initial(icon_state) update_held_icon() diff --git a/code/game/objects/items/devices/lighting/lamp.dm b/code/game/objects/items/devices/lighting/lamp.dm index c07a0d31ddf..85967abc7d8 100644 --- a/code/game/objects/items/devices/lighting/lamp.dm +++ b/code/game/objects/items/devices/lighting/lamp.dm @@ -4,17 +4,16 @@ icon_state = "lamp" item_state = "lamp" center_of_mass = list("x" = 13,"y" = 11) - brightness_on = 4 - flashlight_power = 1.0 w_class = WEIGHT_CLASS_HUGE obj_flags = OBJ_FLAG_CONDUCTABLE - uv_intensity = 100 power_use = FALSE on = TRUE slot_flags = 0 //No wearing desklamps - light_wedge = LIGHT_OMNI toggle_sound = /singleton/sound_category/switch_sound activation_sound = 'sound/effects/lighton.ogg' + light_system = MOVABLE_LIGHT + light_range = 3 + flashlight_power = 1.0 /obj/item/device/flashlight/lamp/mechanics_hints(mob/user, distance, is_adjacent) . += ..() @@ -32,7 +31,7 @@ desc = "A classic green-shaded desk lamp." icon_state = "lampgreen" item_state = "lampgreen" - brightness_on = 5 + light_range = 4 light_color = "#FFC58F" toggle_sound = 'sound/machines/switch_chain.ogg' @@ -49,15 +48,16 @@ name = "data encryption lamp" desc = "Random oil globules within were parsed in photos for your protection. Enjoy this kitschy memorabilia by sticking it on your desk." icon_state = "lavalamp" - brightness_on = 3 + light_range = 3 flashlight_power = 0.5 matter = list(DEFAULT_WALL_MATERIAL = 250, MATERIAL_GLASS = 200) /obj/item/device/flashlight/lamp/lava/update_icon() if(on) - set_light(brightness_on, flashlight_power, light_color) + set_light_range_power_color(light_range, flashlight_power, light_color) else set_light(0) + set_light_on(on) ClearOverlays() var/image/I = image(icon = icon, icon_state = "lavalamp-[on ? "on" : "off"]") I.color = light_color @@ -97,7 +97,7 @@ name = "holographic lighting orb" desc = "A floating orb that comes in a variety of colors. Optional holodeck lighting." anchored = 1 - brightness_on = 12 + light_range = 12 light_color = "#ffcb9b" icon = 'icons/effects/props/holodeck/holodeck_tools.dmi' icon_state = "orb" @@ -108,7 +108,7 @@ /obj/item/device/flashlight/lamp/box name = "box lamp" desc = "A box-shaped traditional flame lamp. Less safe, more pretty." - brightness_on = 5 + light_range = 5 light_color = "#ffcb9b" icon = 'icons/effects/props/holodeck/konyang/32x32.dmi' icon_state = "boxlamp" diff --git a/code/game/objects/items/devices/lighting/marshalling_wand.dm b/code/game/objects/items/devices/lighting/marshalling_wand.dm index 6b06aa788c2..b36cc2e2bca 100644 --- a/code/game/objects/items/devices/lighting/marshalling_wand.dm +++ b/code/game/objects/items/devices/lighting/marshalling_wand.dm @@ -5,8 +5,7 @@ item_state = "marshallingwand" w_class = WEIGHT_CLASS_SMALL light_color = LIGHT_COLOR_RED - light_wedge = LIGHT_OMNI - brightness_on = 2 + light_range = 2 action_button_name = "Toggle Marshalling Wands" /obj/item/device/flashlight/marshallingwand/AltClick(mob/user) diff --git a/code/game/objects/items/devices/lighting/survival.dm b/code/game/objects/items/devices/lighting/survival.dm index 355effc8089..fbe42929d95 100644 --- a/code/game/objects/items/devices/lighting/survival.dm +++ b/code/game/objects/items/devices/lighting/survival.dm @@ -3,10 +3,7 @@ desc = "A hand-held emergency light. This one has been modified with a larger, more efficient bulb pointing inwards." icon_state = "survival_flashlight" item_state = "survival_flashlight" - light_wedge = null - - uv_intensity = 255 light_power = 2 - brightness_on = 2 + light_range = 2 light_color = LIGHT_COLOR_GREEN efficiency_modifier = 1.2 // 120% more efficient compared to other flashlights diff --git a/code/game/objects/items/devices/lightmeter.dm b/code/game/objects/items/devices/lightmeter.dm index c5acc8eee86..f32eede9c4e 100644 --- a/code/game/objects/items/devices/lightmeter.dm +++ b/code/game/objects/items/devices/lightmeter.dm @@ -24,11 +24,9 @@ return var/visible_reading = T.get_lumcount(low, high) - var/uv_reading = T.get_uv_lumcount(low, high) var/reading = "Light analysis for \the [T].
" reading += "Visible light: [visible_reading] lx
" - reading += "Ultraviolet light: [uv_reading] lx ([uv_reading * 5.5 - 1.5] adlx)" to_chat(usr, SPAN_NOTICE(reading)) diff --git a/code/game/objects/items/devices/oxycandle.dm b/code/game/objects/items/devices/oxycandle.dm index 31082c805de..705ee1b2973 100644 --- a/code/game/objects/items/devices/oxycandle.dm +++ b/code/game/objects/items/devices/oxycandle.dm @@ -11,15 +11,14 @@ var/on = FALSE var/activation_sound = 'sound/items/flare.ogg' light_color = LIGHT_COLOR_FLARE - uv_intensity = 50 - var/brightness_on = 2 // Moderate bright. + light_range = 2 // Moderate bright. light_power = 2 action_button_name = null /obj/item/device/oxycandle/attack_self(mob/user) if(!on) to_chat(user, SPAN_NOTICE("You pull the cord and [src] ignites.")) - light_range = brightness_on + light_range = light_range on = TRUE update_icon() playsound(src.loc, activation_sound, 75, 1) @@ -65,7 +64,7 @@ if(on) icon_state = "oxycandle_on" item_state = icon_state - set_light(brightness_on) + set_light(light_range) else icon_state = "oxycandle" item_state = icon_state diff --git a/code/game/objects/items/devices/powersink.dm b/code/game/objects/items/devices/powersink.dm index 2b3a209f87d..e8545dac9f8 100644 --- a/code/game/objects/items/devices/powersink.dm +++ b/code/game/objects/items/devices/powersink.dm @@ -121,7 +121,6 @@ if(!PN) return 1 - set_light(12) PN.trigger_warning() // found a powernet, so drain up to max power from it drained = PN.draw_power(drain_rate * seconds_per_tick) diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index bbf7a76dab5..a72283e1d28 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -29,7 +29,6 @@ pixel_x = 8; canhear_range = 2 atom_flags = ATOM_FLAG_NO_BLOOD obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED | OBJ_FLAG_CONDUCTABLE - z_flags = ZMM_MANGLE_PLANES var/number = 0 var/obj/machinery/abstract/intercom_listener/power_interface var/radio_sound = null diff --git a/code/game/objects/items/recharger_backpack.dm b/code/game/objects/items/recharger_backpack.dm index b1e707d3d8d..471a8e50d4b 100644 --- a/code/game/objects/items/recharger_backpack.dm +++ b/code/game/objects/items/recharger_backpack.dm @@ -64,7 +64,7 @@ if(!powersupply) icon_state = "recharger_backpack" item_state = "recharger_backpack" - set_light(0) + set_light_on(FALSE) else var/current_charge = powersupply.percent() @@ -72,19 +72,22 @@ if(70 to INFINITY) icon_state = "recharger_backpack_full" item_state = "recharger_backpack_full" - set_light(2, 0.75, LIGHT_COLOR_GREEN) + set_light_range_power_color(2, 0.75, LIGHT_COLOR_GREEN) + set_light_on(TRUE) if(35 to 70) icon_state = "recharger_backpack_med" item_state = "recharger_backpack_med" - set_light(2, 0.75, LIGHT_COLOR_FIRE) + set_light_range_power_color(2, 0.75, LIGHT_COLOR_FIRE) + set_light_on(TRUE) if(1 to 35) icon_state = "recharger_backpack_low" item_state = "recharger_backpack_low" - set_light(2, 0.75, LIGHT_COLOR_RED) + set_light_range_power_color(2, 0.75, LIGHT_COLOR_RED) + set_light_on(TRUE) if(-INFINITY to 1) icon_state = "recharger_backpack" item_state = "recharger_backpack" - set_light(0) + set_light_on(FALSE) /obj/item/recharger_backpack/get_cell() if(powersupply) diff --git a/code/game/objects/items/skrell.dm b/code/game/objects/items/skrell.dm index 05132115faa..f494a5a11d0 100644 --- a/code/game/objects/items/skrell.dm +++ b/code/game/objects/items/skrell.dm @@ -54,7 +54,6 @@ light_power = 1 light_range = 1 light_color = LIGHT_COLOR_HALOGEN - z_flags = ZMM_MANGLE_PLANES var/global/image/glow_state /obj/effect/temp_visual/constellation/Initialize() diff --git a/code/game/objects/items/weapons/candle.dm b/code/game/objects/items/weapons/candle.dm index 9a1f79ddf7f..ba444b968e4 100644 --- a/code/game/objects/items/weapons/candle.dm +++ b/code/game/objects/items/weapons/candle.dm @@ -8,6 +8,8 @@ pickup_sound = 'sound/items/pickup/gloves.ogg' w_class = WEIGHT_CLASS_TINY light_color = "#E09D37" + light_range = 2 + light_power = CANDLE_LUM var/wax = 3200 var/start_lit = FALSE @@ -47,8 +49,7 @@ if(!src.lit) src.lit = 1 playsound(src.loc, 'sound/items/cigs_lighters/cig_light.ogg', 50, 1) - //src.damtype = "fire" - set_light(CANDLE_LUM) + set_light_on(TRUE) update_icon() START_PROCESSING(SSprocessing, src) @@ -76,4 +77,4 @@ to_chat(user, SPAN_NOTICE("You snuff out the flame.")) playsound(src.loc, 'sound/items/cigs_lighters/cig_snuff.ogg', 50, 1) update_icon() - set_light(0) + set_light_on(FALSE) diff --git a/code/game/objects/items/weapons/cards_ids.dm b/code/game/objects/items/weapons/cards_ids.dm index 9e3c9b67b3a..fe34283e21e 100644 --- a/code/game/objects/items/weapons/cards_ids.dm +++ b/code/game/objects/items/weapons/cards_ids.dm @@ -770,7 +770,8 @@ var/list/pilot_access = list() for(var/mob/pilot as anything in exosuit.pilots) var/obj/item/ID = pilot.GetIdCard() - pilot_access |= ID.GetAccess() + if(ID) + pilot_access |= ID.GetAccess() return pilot_access #undef ID_CARD_UNSET diff --git a/code/game/objects/items/weapons/chaplain_items.dm b/code/game/objects/items/weapons/chaplain_items.dm index 6975da04d41..492a4013059 100644 --- a/code/game/objects/items/weapons/chaplain_items.dm +++ b/code/game/objects/items/weapons/chaplain_items.dm @@ -126,6 +126,9 @@ icon_state = "azubarre_torch" item_state = "azubarre_torch" contained_sprite = TRUE + light_range = 3 + light_power = 1 + light_color = LIGHT_COLOR_FIRE var/lit = FALSE /obj/item/nullrod/azubarre/attack_self(mob/user) @@ -142,10 +145,10 @@ /obj/item/nullrod/azubarre/update_icon() if(lit) icon_state = "azubarre_torch-on" - set_light(3, 1, LIGHT_COLOR_FIRE) + set_light_on(TRUE) else icon_state = "azubarre_torch-empty" - set_light(0) + set_light_on(FALSE) item_state = icon_state /obj/item/nullrod/azubarre/isFlameSource() diff --git a/code/game/objects/items/weapons/cigs_lighters.dm b/code/game/objects/items/weapons/cigs_lighters.dm index 648712b015b..7dc64eb5eef 100644 --- a/code/game/objects/items/weapons/cigs_lighters.dm +++ b/code/game/objects/items/weapons/cigs_lighters.dm @@ -40,6 +40,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM attack_verb = list("burnt", "singed") drop_sound = 'sound/items/drop/food.ogg' pickup_sound = 'sound/items/pickup/food.ogg' + light_system = MOVABLE_LIGHT /obj/item/trash/match name = "burnt match" @@ -113,7 +114,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM M.update_inv_wear_mask(0) M.update_inv_l_hand(0) M.update_inv_r_hand(1) - set_light(2, 0.25, "#E38F46") + set_light_range_power_color(2, 0.25, "#E38F46") + set_light_on(TRUE) START_PROCESSING(SSprocessing, src) /obj/item/flame/match/proc/die(var/nomessage = FALSE) @@ -135,7 +137,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM M.update_inv_l_hand(0) M.update_inv_r_hand(1) M.put_in_hands(burnt) - set_light(0) + set_light_on(FALSE) STOP_PROCESSING(SSprocessing, src) qdel(src) @@ -227,12 +229,13 @@ ABSTRACT_TYPE(/obj/item/clothing/mask/smokable) M.update_inv_r_hand(1) var/turf/T = get_turf(src) T.visible_message(flavor_text) - set_light(2, 0.25, "#E38F46") + set_light_range_power_color(2, 0.25, "#E38F46") + set_light_on(TRUE) START_PROCESSING(SSprocessing, src) /obj/item/clothing/mask/smokable/proc/die(var/no_message = FALSE, var/intentionally = FALSE) var/turf/T = get_turf(src) - set_light(0) + set_light_on(FALSE) playsound(src.loc, 'sound/items/cigs_lighters/cig_snuff.ogg', 50, 1) if(type_butt) var/obj/item/butt = new type_butt(src.loc) @@ -965,7 +968,7 @@ ABSTRACT_TYPE(/obj/item/clothing/mask/smokable) else user.visible_message(SPAN_NOTICE("[user] quietly shuts off \the [src]."), range = 3) - set_light(0) + set_light_on(FALSE) STOP_PROCESSING(SSprocessing, src) else return ..() @@ -975,7 +978,8 @@ ABSTRACT_TYPE(/obj/item/clothing/mask/smokable) lit = TRUE update_icon() playsound(src.loc, pick(activation_sound), 75, 1) - set_light(flame_light_power, flame_light_range, l_color = flame_light_color) + set_light_range_power_color(flame_light_range, flame_light_power, flame_light_color) + set_light_on(TRUE) START_PROCESSING(SSprocessing, src) /obj/item/flame/lighter/vendor_action(var/obj/machinery/vending/V) @@ -1032,7 +1036,7 @@ ABSTRACT_TYPE(/obj/item/clothing/mask/smokable) lit = 0 icon_state = "[base_state]" item_state = "[base_state]" - set_light(0) + set_light_on(FALSE) STOP_PROCESSING(SSprocessing, src) return diff --git a/code/game/objects/items/weapons/tools.dm b/code/game/objects/items/weapons/tools.dm index 8a675b8aa38..d6dbe61c16d 100644 --- a/code/game/objects/items/weapons/tools.dm +++ b/code/game/objects/items/weapons/tools.dm @@ -237,6 +237,10 @@ attack_verb = list("hit", "bludgeoned", "whacked") + light_system = MOVABLE_LIGHT + light_range = 1 + light_color = LIGHT_COLOR_LAVA + //Amount of OUCH when it's thrown force = 3 throwforce = 5 @@ -299,6 +303,7 @@ max_fuel = 40 matter = list(DEFAULT_WALL_MATERIAL = 100, MATERIAL_GLASS = 120) origin_tech = list(TECH_ENGINEERING = 4, TECH_BIO = 4) + light_color = LIGHT_COLOR_BLUE var/last_gen = 0 var/fuelgen_delay = 400 //The time, in deciseconds, required to regenerate one unit of fuel @@ -333,11 +338,14 @@ item_state = "[initial(item_state)]" if(welding == 2) - set_light(0.7, 2, l_color = LIGHT_COLOR_CYAN) + set_light_range_power_color(light_range * 1.5, light_power * 1.5, light_color) + set_light_on(TRUE) else if (welding == 1) - set_light(0.6, 1.5, l_color = LIGHT_COLOR_LAVA) + set_light_range_power_color(light_range, light_power, light_color) + set_light_on(TRUE) else - set_light(0) + set_light_range_power_color(light_range, light_power, light_color) + set_light_on(FALSE) /obj/item/weldingtool/update_icon() ClearOverlays() diff --git a/code/game/objects/structures/light_pole.dm b/code/game/objects/structures/light_pole.dm index 33618c73166..0f3982821ca 100644 --- a/code/game/objects/structures/light_pole.dm +++ b/code/game/objects/structures/light_pole.dm @@ -5,7 +5,6 @@ icon_state = "rustlamp_l" anchored = TRUE density = TRUE - light_wedge = LIGHT_OMNI light_color = LIGHT_COLOR_HALOGEN light_range = 8 light_power = 8 @@ -29,7 +28,6 @@ anchored = TRUE density = FALSE light_color = "#FA644B" - light_wedge = LIGHT_OMNI light_range = 6 light_power = 1 @@ -66,7 +64,6 @@ /obj/structure/utility_pole/street/on desc = "A tall light source. This one shines brightly." - light_wedge = LIGHT_OMNI light_color = "#e8ffeb" light_range = 8 light_power = 1.9 @@ -82,7 +79,6 @@ /obj/structure/utility_pole/street/classic/on desc = "A tall light source. This one shines brightly." - light_wedge = LIGHT_OMNI light_color = LIGHT_COLOR_TUNGSTEN light_range = 8 light_power = 1.9 diff --git a/code/game/objects/structures/urban.dm b/code/game/objects/structures/urban.dm index 0e6441534e5..b97ea7f6a7f 100644 --- a/code/game/objects/structures/urban.dm +++ b/code/game/objects/structures/urban.dm @@ -241,7 +241,7 @@ ABSTRACT_TYPE(/obj/structure/stairs/urban) icon = 'icons/obj/structure/urban/ledges.dmi' icon_state = "stairs-single" layer = 2.01 - opacity = 1 + opacity = TRUE /obj/structure/stairs/urban/right dir = EAST @@ -821,6 +821,10 @@ ABSTRACT_TYPE(/obj/structure/stairs/urban/road_ramp) if(storage_type) storage_compartment = new storage_type(src) +/obj/structure/cash_register/Destroy() + QDEL_NULL(storage_compartment) + return ..() + /obj/item/storage/toolbox/cash_register_storage name = "cash compartment" @@ -960,7 +964,7 @@ ABSTRACT_TYPE(/obj/structure/stairs/urban/road_ramp) autoclose = TRUE support_ids = TRUE glass = TRUE - opacity = 0 //otherwise it is opaque until opened/closed for the first time. + opacity = FALSE //otherwise it is opaque until opened/closed for the first time. /obj/machinery/door/urban/glass_sliding/double //use north state for left side and south state for right side icon_state = "double_glass_sliding_closed" diff --git a/code/game/turfs/simulated/shuttle_turfs.dm b/code/game/turfs/simulated/shuttle_turfs.dm index 478f8e554de..a1c5dfcb3df 100644 --- a/code/game/turfs/simulated/shuttle_turfs.dm +++ b/code/game/turfs/simulated/shuttle_turfs.dm @@ -4,7 +4,6 @@ /turf/simulated/wall/shuttle icon = 'icons/turf/smooth/shuttle_wall_dark.dmi' icon_state = "map-shuttle" - permit_ao = 0 smoothing_flags = SMOOTH_MORE canSmoothWith = list( /turf/unsimulated/wall/steel, // Centcomm wall. @@ -197,6 +196,12 @@ atmos_canpass = CANPASS_DENSITY obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED|OBJ_FLAG_NOFALL +/obj/structure/shuttle_part/afterShuttleMove(obj/effect/shuttle_landmark/destination) + . = ..() + if(outside_part) + var/turf/target_turf = get_turf(src) + target_turf.ChangeTurf(destination.base_turf) + /obj/structure/window/shuttle/unique name = "shuttle window" desc = "It looks extremely strong. Might take many good hits to crack it." @@ -210,6 +215,12 @@ can_be_unanchored = FALSE var/outside_window = FALSE +/obj/structure/window/shuttle/unique/afterShuttleMove(obj/effect/shuttle_landmark/destination) + . = ..() + if(outside_window) + var/turf/target_turf = get_turf(src) + target_turf.ChangeTurf(destination.base_turf) + //merchant shuttle /turf/simulated/wall/shuttle/unique/merchant @@ -516,7 +527,6 @@ name = "shuttle floor" icon = 'icons/turf/shuttle.dmi' icon_state = "floor" - permit_ao = 0 initial_flooring = /singleton/flooring/shuttle footstep_sound = /singleton/sound_category/plating_footstep @@ -593,7 +603,6 @@ smooth_underlays = TRUE initial_gas = null roof_type = null - permit_ao = 0 canSmoothWith = list( /turf/simulated/shuttle_roof ) diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 7bc01e7ab66..55875705a03 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -3,7 +3,6 @@ name = "\proper space" desc = "The final frontier." icon_state = "0" - dynamic_lighting = 0 footstep_sound = null //Override to make sure because yeah tracks_footprint = FALSE @@ -14,7 +13,6 @@ // heat_capacity = 700000 No. is_hole = TRUE - permit_ao = FALSE z_eventually_space = TRUE turf_flags = TURF_FLAG_BACKGROUND explosion_resistance = 3 @@ -22,7 +20,7 @@ var/use_space_appearance = TRUE /turf/space/dynamic //For use in edge cases where you want the turf to not be completely lit, like in places where you have placed lattice. - dynamic_lighting = 1 + //todomatt: this is useless now // Copypaste of parent for performance. /turf/space/Initialize() @@ -34,7 +32,8 @@ if(use_space_appearance) appearance = SSskybox.space_appearance_cache[(((x + y) ^ ~(x * y) + z) % 25) + 1] - if(GLOB.config.starlight && GLOB.lighting_overlays_initialized) + + if(GLOB.config.starlight) update_starlight() for(var/atom/movable/AM as mob|obj in src) @@ -43,11 +42,6 @@ // if (is_station_level(z)) // GLOB.station_turfs += src - if(dynamic_lighting) - luminosity = 0 - else - luminosity = 1 - return INITIALIZE_HINT_NORMAL // Handles starlight logic unique to space turfs. diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index b7ad7658d02..d3bf65fb14f 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -3,6 +3,7 @@ level = 1 layer = TURF_LAYER + vis_flags = VIS_INHERIT_PLANE var/holy = 0 @@ -62,6 +63,18 @@ var/base_icon_state = "plating" var/base_color = null + ///Lumcount added by sources other than lighting datum objects, such as the overlay lighting component. + var/dynamic_lumcount = 0 + + ///List of light sources affecting this turf. + ///Which directions does this turf block the vision of, taking into account both the turf's opacity and the movable opacity_sources. + var/directional_opacity = NONE + ///Lazylist of movable atoms providing opacity sources. + var/list/atom/movable/opacity_sources + + ///hybrid lights affecting this turf + var/tmp/list/atom/movable/lighting_mask/hybrid_lights_affecting + ///for clean log spam. var/last_clean @@ -112,20 +125,9 @@ if (is_station_level(z)) GLOB.station_turfs += src - if(dynamic_lighting) - luminosity = 0 - else - luminosity = 1 - if (smoothing_flags) QUEUE_SMOOTH(src) - if (opacity) - has_opaque_atom = TRUE - - if (mapload && permit_ao) - queue_ao() - var/area/A = loc if(A.base_turf) @@ -136,6 +138,14 @@ if (light_range && light_power) update_light() + //Get area light + var/area/current_area = loc + if(current_area?.lighting_effect) + overlays += current_area.lighting_effect + + if(opacity) + directional_opacity = ALL_CARDINALS + else if(!baseturf) // Hard-coding this for performance reasons. baseturf = SSatlas.current_map.base_turf_by_z["[z]"] || /turf/space @@ -149,6 +159,11 @@ return INITIALIZE_HINT_NORMAL /turf/Destroy() + if(hybrid_lights_affecting) + for(var/atom/movable/lighting_mask/mask as anything in hybrid_lights_affecting) + LAZYREMOVE(mask.affecting_turfs, src) + hybrid_lights_affecting.Cut() + if (!changing_turf) crash_with("Improper turf qdeletion.") @@ -160,10 +175,6 @@ remove_cleanables() cleanup_roof() - if (ao_queued) - SSao.queue -= src - ao_queued = 0 - if (z_flags & ZM_MIMIC_BELOW) cleanup_zmimic() @@ -198,7 +209,7 @@ // We do this prior to the unique space logic so this also covers space turfs within a needs_starlight area. var/area/A = get_area(src) if(A.needs_starlight) - set_light(SSatlas.current_sector.starlight_range, SSatlas.current_sector.starlight_power, l_color = SSskybox.background_color) + set_light(SSatlas.current_sector.starlight_range, SSatlas.current_sector.starlight_power, SSskybox.background_color) return TRUE else // If we aren't assigning starlight lighting, set the lighting to default so it's possible to undo starlight lighting if an area changes. set_default_lighting() @@ -463,15 +474,6 @@ if (oAM.simulated && (oAM.movable_flags & MOVABLE_FLAG_PROXMOVE)) arrived.proximity_callback(oAM) - if (arrived && arrived.opacity && !has_opaque_atom) - has_opaque_atom = TRUE // Make sure to do this before reconsider_lights(), incase we're on instant updates. Guaranteed to be on in this case. - reconsider_lights() - -#ifdef AO_USE_LIGHTING_OPACITY - // Hook for AO. - regenerate_ao() -#endif - if(!(arrived.bound_overlay || (arrived.z_flags & ZMM_IGNORE) || !TURF_IS_MIMICING(above))) above.update_mimic() diff --git a/code/game/turfs/turf_changing.dm b/code/game/turfs/turf_changing.dm index 15e6e087cea..ed7a7f40f12 100644 --- a/code/game/turfs/turf_changing.dm +++ b/code/game/turfs/turf_changing.dm @@ -49,11 +49,6 @@ var/obj/fire/old_fire = fire var/old_baseturf = baseturf var/old_above = above - var/old_opacity = opacity - var/old_dynamic_lighting = dynamic_lighting - var/list/old_affecting_lights = affecting_lights - var/old_lighting_overlay = lighting_overlay - var/list/old_corners = corners var/list/old_blueprints = blueprints var/list/old_decals = decals var/old_outside = is_outside @@ -61,6 +56,17 @@ var/list/old_resources = resources ? resources.Copy() : null SEND_SIGNAL(src, COMSIG_TURF_CHANGE, path) + + //static lighting + var/old_lighting_object = static_lighting_object + var/old_lighting_corner_NE = lighting_corner_NE + var/old_lighting_corner_SE = lighting_corner_SE + var/old_lighting_corner_SW = lighting_corner_SW + var/old_lighting_corner_NW = lighting_corner_NW + //hybrid lighting + var/list/old_hybrid_lights_affecting = hybrid_lights_affecting?.Copy() + var/old_directional_opacity = directional_opacity + changing_turf = TRUE if(connections) @@ -87,34 +93,38 @@ if(old_signal_procs) LAZYOR(new_turf._signal_procs, old_signal_procs) -#ifndef AO_USE_LIGHTING_OPACITY - // If we're using opacity-based AO, this is done in recalc_atom_opacity(). - if (permit_ao) - regenerate_ao() -#endif + new_turf.hybrid_lights_affecting = old_hybrid_lights_affecting + new_turf.dynamic_lumcount = dynamic_lumcount - if(GLOB.lighting_overlays_initialized) - recalc_atom_opacity() - lighting_overlay = old_lighting_overlay - if (lighting_overlay && lighting_overlay.loc != src) - // This is a hack, but I can't figure out why the fuck they're not on the correct turf in the first place. - lighting_overlay.forceMove(src, harderforce = TRUE) + lighting_corner_NE = old_lighting_corner_NE + lighting_corner_SE = old_lighting_corner_SE + lighting_corner_SW = old_lighting_corner_SW + lighting_corner_NW = old_lighting_corner_NW - affecting_lights = old_affecting_lights - corners = old_corners + //static Update + if(SSlighting.initialized) + recalculate_directional_opacity() - if ((old_opacity != opacity) || (dynamic_lighting != old_dynamic_lighting) || force_lighting_update) - reconsider_lights() + new_turf.static_lighting_object = old_lighting_object - if (dynamic_lighting != old_dynamic_lighting) - if (dynamic_lighting) - lighting_build_overlay() - else - lighting_clear_overlay() + if(static_lighting_object && !static_lighting_object.needs_update) + static_lighting_object.update() - if (GLOB.config.starlight) - for (var/turf/space/S in RANGE_TURFS(1, src)) - S.update_starlight() + //Since the old turf was removed from hybrid_lights_affecting, readd the new turf here + if(new_turf.hybrid_lights_affecting) + for(var/atom/movable/lighting_mask/mask as anything in new_turf.hybrid_lights_affecting) + LAZYADD(mask.affecting_turfs, new_turf) + + if(new_turf.directional_opacity != old_directional_opacity) + new_turf.reconsider_lights() + + var/area/thisarea = get_area(new_turf) + if(thisarea.lighting_effect) + new_turf.AddOverlays(thisarea.lighting_effect) + + if(GLOB.config.starlight) + for(var/turf/space/S in RANGE_TURFS(1, src)) + S.update_starlight() new_turf.above = old_above @@ -167,7 +177,6 @@ src.icon_state = other.icon_state src.icon = other.icon src.overlays = other.overlays.Copy() - src.underlays = other.underlays.Copy() if(other.decals) src.decals = other.decals.Copy() other.decals.Cut() @@ -200,7 +209,6 @@ other.icon = icon other.icon_state = icon_state - other.underlays = underlays.Copy() other.name = name other.layer = layer other.decals = decals diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 26c827ab4f9..66654ac2ab0 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -224,7 +224,6 @@ GLOBAL_LIST_INIT(admin_verbs_debug, list( /client/proc/toggle_recursive_explosions, /client/proc/restart_sql, /client/proc/fix_player_list, - /client/proc/lighting_show_verbs, /client/proc/restart_controller, /client/proc/cmd_display_del_log, /client/proc/cmd_display_harddel_log, @@ -236,7 +235,6 @@ GLOBAL_LIST_INIT(admin_verbs_debug, list( /datum/admins/proc/map_template_load, /datum/admins/proc/map_template_load_new_z, /datum/admins/proc/map_template_upload, - /client/proc/global_ao_regenerate, /client/proc/add_client_color, /client/proc/connect_ntsl, /client/proc/disconnect_ntsl, @@ -342,7 +340,6 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( /client/proc/end_round, /datum/admins/proc/immreboot, /client/proc/cmd_dev_bst, - /client/proc/global_ao_regenerate, /client/proc/everyone_random, /datum/admins/proc/toggleAI, /client/proc/cmd_admin_delete, @@ -420,7 +417,6 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list( /datum/admins/proc/capture_map, /turf/proc/view_chunk, /turf/proc/update_chunk, - /client/proc/lighting_show_verbs, /client/proc/callproc, /client/proc/callproc_target, /client/proc/debug_controller, @@ -498,7 +494,6 @@ GLOBAL_LIST_INIT(admin_verbs_dev, list( //will need to be altered - Ryan784 /client/proc/toggledebuglogs, /client/proc/ZASSettings, /client/proc/cmd_dev_bst, - /client/proc/lighting_show_verbs, /client/proc/cmd_display_del_log, /client/proc/cmd_display_harddel_log, /client/proc/cmd_display_init_log, diff --git a/code/modules/admin/verbs/bluespacetech.dm b/code/modules/admin/verbs/bluespacetech.dm index a3412513899..4ef1a60e5d5 100644 --- a/code/modules/admin/verbs/bluespacetech.dm +++ b/code/modules/admin/verbs/bluespacetech.dm @@ -419,7 +419,7 @@ name = "bluespace technician's glasses" desc = "A pair of modified sunglasses. The word 'BST' is stamped on the side." vision_flags = (SEE_TURFS|SEE_OBJS|SEE_MOBS) - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE canremove = 0 flash_protection = FLASH_PROTECTION_MAJOR @@ -431,17 +431,17 @@ switch (mode) if ("X-Ray without Lighting") - vision_flags = SEE_TURFS|SEE_OBJS|SEE_MOBS|SEE_BLACKNESS|SEE_SELF - see_invisible = SEE_INVISIBLE_NOLIGHTING + vision_flags = SEE_TURFS|SEE_OBJS|SEE_MOBS|SEE_SELF + lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE if ("X-Ray with Lighting") - vision_flags = SEE_TURFS|SEE_OBJS|SEE_MOBS|SEE_BLACKNESS|SEE_SELF - see_invisible = -1 + vision_flags = SEE_TURFS|SEE_OBJS|SEE_MOBS|SEE_SELF + lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE if ("Darkvision") - vision_flags = SEE_BLACKNESS|SEE_SELF - see_invisible = SEE_INVISIBLE_NOLIGHTING + vision_flags = SEE_SELF + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE if ("Normal vision") vision_flags = 0 - see_invisible = -1 + lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE to_chat(usr, SPAN_NOTICE("\The [src]'s vision mode is now [mode].")) diff --git a/code/modules/ambient_occlusion/ao_turf.dm b/code/modules/ambient_occlusion/ao_turf.dm deleted file mode 100644 index 36fca99efb5..00000000000 --- a/code/modules/ambient_occlusion/ao_turf.dm +++ /dev/null @@ -1,116 +0,0 @@ -#ifdef AO_USE_LIGHTING_OPACITY -#define AO_TURF_CHECK(T) (!T.has_opaque_atom || !T.permit_ao) -#define AO_SELF_CHECK(T) (!T.has_opaque_atom) -#else -#define AO_TURF_CHECK(T) (!T.density || !T.opacity || !T.permit_ao) -#define AO_SELF_CHECK(T) (!T.density && !T.opacity) -#endif - -/turf - var/permit_ao = TRUE - var/tmp/list/ao_overlays // Current ambient occlusion overlays. Tracked so we can reverse them without dropping all priority overlays. - var/tmp/ao_neighbors - var/tmp/list/ao_overlays_mimic - var/tmp/ao_neighbors_mimic - var/ao_queued = AO_UPDATE_NONE - -/turf/proc/regenerate_ao() - if (GLOB.config.fastboot) - return - for (var/thing in RANGE_TURFS(1, src)) - var/turf/T = thing - if (T.permit_ao) - T.queue_ao(TRUE) - -/turf/proc/calculate_ao_neighbors() - ao_neighbors = 0 - ao_neighbors_mimic = 0 - if (!permit_ao) - return - - var/turf/T - if (z_flags & ZM_MIMIC_BELOW) - CALCULATE_NEIGHBORS(src, ao_neighbors_mimic, T, (T.z_flags & ZM_MIMIC_BELOW)) - if (AO_SELF_CHECK(src) && !(z_flags & ZM_MIMIC_NO_AO)) - CALCULATE_NEIGHBORS(src, ao_neighbors, T, AO_TURF_CHECK(T)) - -/proc/make_ao_image(corner, i, px = 0, py = 0, pz = 0, pw = 0) - var/list/cache = SSicon_cache.ao_cache - var/cstr = "[corner]" - var/key = "[cstr]-[i]-[px]/[py]/[pz]/[pw]" - - var/image/I = image('icons/turf/flooring/shadows.dmi', cstr, dir = 1 << (i-1)) - I.alpha = WALL_AO_ALPHA - I.blend_mode = BLEND_OVERLAY - I.appearance_flags = RESET_ALPHA|RESET_COLOR|TILE_BOUND - I.layer = AO_LAYER - // If there's an offset, counteract it. - if (px || py || pz || pw) - I.pixel_x = -px - I.pixel_y = -py - I.pixel_z = -pz - I.pixel_w = -pw - - . = cache[key] = I - -/turf/proc/queue_ao(rebuild = TRUE) - if (GLOB.config.fastboot) - return - if (!ao_queued) - SSao.queue += src - - var/new_level = rebuild ? AO_UPDATE_REBUILD : AO_UPDATE_OVERLAY - if (ao_queued < new_level) - ao_queued = new_level - -#define PROCESS_AO_CORNER(AO_LIST, NEIGHBORS, CORNER_INDEX, CDIR) \ - corner = 0; \ - if (NEIGHBORS & (1 << CDIR)) { \ - corner |= 2; \ - } \ - if (NEIGHBORS & (1 << turn(CDIR, 45))) { \ - corner |= 1; \ - } \ - if (NEIGHBORS & (1 << turn(CDIR, -45))) { \ - corner |= 4; \ - } \ - if (corner != 7) { /* 7 is the 'no shadows' state, no reason to add overlays for it. */ \ - var/image/I = cache["[corner]-[CORNER_INDEX]-[pixel_x]/[pixel_y]/[pixel_z]/[pixel_w]"]; \ - if (!I) { \ - I = make_ao_image(corner, CORNER_INDEX, pixel_x, pixel_y, pixel_z, pixel_w) /* this will also add the image to the cache. */ \ - } \ - LAZYADD(AO_LIST, I); \ - } - -#define CUT_AO(TARGET, AO_LIST) \ - if (AO_LIST) { \ - TARGET.CutOverlays(AO_LIST, ATOM_ICON_CACHE_PROTECTED); \ - AO_LIST.Cut(); \ - } - -#define REGEN_AO(TARGET, AO_LIST, NEIGHBORS) \ - if (permit_ao && NEIGHBORS != AO_ALL_NEIGHBORS) { \ - var/corner;\ - PROCESS_AO_CORNER(AO_LIST, NEIGHBORS, 1, NORTHWEST); \ - PROCESS_AO_CORNER(AO_LIST, NEIGHBORS, 2, SOUTHEAST); \ - PROCESS_AO_CORNER(AO_LIST, NEIGHBORS, 3, NORTHEAST); \ - PROCESS_AO_CORNER(AO_LIST, NEIGHBORS, 4, SOUTHWEST); \ - } \ - UNSETEMPTY(AO_LIST); \ - if (AO_LIST) { \ - TARGET.AddOverlays(AO_LIST, ATOM_ICON_CACHE_PROTECTED); \ - } - -/turf/proc/update_ao() - var/list/cache = SSicon_cache.ao_cache - CUT_AO(shadower, ao_overlays_mimic) - CUT_AO(src, ao_overlays) - if (z_flags & ZM_MIMIC_BELOW) - REGEN_AO(shadower, ao_overlays_mimic, ao_neighbors_mimic) - if (!has_opaque_atom && !(z_flags & ZM_MIMIC_NO_AO)) - REGEN_AO(src, ao_overlays, ao_neighbors) - -#undef REGEN_AO -#undef PROCESS_AO_CORNER -#undef AO_TURF_CHECK -#undef AO_SELF_CHECK diff --git a/code/modules/ambient_occlusion/ao_verbs.dm b/code/modules/ambient_occlusion/ao_verbs.dm deleted file mode 100644 index 1a8ac2fba0a..00000000000 --- a/code/modules/ambient_occlusion/ao_verbs.dm +++ /dev/null @@ -1,23 +0,0 @@ -/client/proc/global_ao_regenerate() - set name = "Regenerate AO (Global)" - set desc = "Regenerates AO caches across the map." - set category = "Debug" - - if (!check_rights(R_DEBUG)) return - - log_and_message_admins("has triggered a global ambient occlusion rebuild.") - to_chat(usr, "Beginning global AO rebuild.") - - SSao.can_fire = FALSE - - for (var/turf/T in world) // Yes, in world. - T.ao_neighbors = null // To force a recalc. - T.ao_neighbors_mimic = null - if (T.permit_ao) - T.queue_ao() - - CHECK_TICK - - SSao.can_fire = TRUE - - to_chat(usr, "AO rebuild complete.") diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index f69f77540bc..0b5b6944ce1 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -600,7 +600,6 @@ body_parts_covered = HEAD slot_flags = SLOT_HEAD w_class = WEIGHT_CLASS_SMALL - uv_intensity = 50 //Light emitted by this object or creature has limited interaction with diona species_restricted = list("exclude",BODYTYPE_VAURCA_BREEDER,BODYTYPE_VAURCA_WARFORM,BODYTYPE_TESLA_BODY) drop_sound = 'sound/items/drop/hat.ogg' @@ -608,13 +607,14 @@ valid_accessory_slots = list(ACCESSORY_SLOT_HEAD) + light_system = DIRECTIONAL_LIGHT + /// In case if you want to allow someone to switch the BLOCKHEADHAIR var from the helmet or not var/allow_hair_covering = TRUE var/light_overlay = "helmet_light" var/light_applied - var/brightness_on - var/on = 0 + var/on = FALSE var/protects_against_weather = FALSE /obj/item/clothing/head/Initialize(mapload, material_key) @@ -638,22 +638,22 @@ return on /obj/item/clothing/head/attack_self(mob/user) - if(brightness_on) + if(light_range) if(!isturf(user.loc)) to_chat(user, "You cannot turn the light on while in this [user.loc]") return on = !on - to_chat(user, "You [on ? "enable" : "disable"] the helmet light.") + to_chat(user, SPAN_NOTICE("You [on ? "enable" : "disable"] the helmet light.")) update_flashlight(user) else return ..(user) /obj/item/clothing/head/proc/update_flashlight(var/mob/user = null) if(on && !light_applied) - set_light(brightness_on) + set_light_on(on) light_applied = 1 else if(!on && light_applied) - set_light(0) + set_light_on(on) light_applied = 0 update_icon(user) user.update_action_buttons() diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index 2cde7080e5a..70564936b13 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -19,9 +19,12 @@ BLIND // can't see anything w_class = WEIGHT_CLASS_SMALL slot_flags = SLOT_EYES body_parts_covered = EYES + light_system = MOVABLE_LIGHT var/vision_flags = 0 var/darkness_view = 0//Base human is 2 var/prescription = 0 + /// The amount of nightvision these glasses have. This should be a number between 0 and 1. + var/lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE var/see_invisible = -1 var/toggleable = 0 var/toggle_changes_appearance = TRUE @@ -77,18 +80,18 @@ BLIND // can't see anything /obj/item/clothing/glasses/attack_self(mob/user) if(toggleable) if(active) - active = 0 + active = FALSE if(toggle_changes_appearance) icon_state = off_state item_state = off_state user.update_inv_glasses() flash_protection = FLASH_PROTECTION_NONE tint = TINT_NONE - to_chat(usr, "You deactivate the optical matrix on the [src].") + to_chat(usr, SPAN_NOTICE("You deactivate the optical matrix on the [src].")) if(activated_color) - set_light(0) + set_light_on(active) else - active = 1 + active = TRUE if(toggle_changes_appearance) icon_state = initial(icon_state) item_state = initial(icon_state) @@ -97,9 +100,10 @@ BLIND // can't see anything sound_to(usr, activation_sound) flash_protection = initial(flash_protection) tint = initial(tint) - to_chat(usr, "You activate the optical matrix on the [src].") + to_chat(usr, SPAN_NOTICE("You activate the optical matrix on the [src].")) if(activated_color) - set_light(2, 0.4, activated_color) + set_light_range_power_color(2, 0.4, activated_color) + set_light_on(active) user.update_action_buttons() user.update_inv_l_hand(0) user.update_inv_r_hand(1) @@ -120,7 +124,7 @@ BLIND // can't see anything origin_tech = list(TECH_MAGNET = 2, TECH_ENGINEERING = 2) toggleable = 1 vision_flags = SEE_TURFS - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE item_flags = ITEM_FLAG_AIRTIGHT activated_color = LIGHT_COLOR_GREEN @@ -225,7 +229,7 @@ BLIND // can't see anything origin_tech = list(TECH_MAGNET = 2) darkness_view = 7 toggleable = 1 - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE off_state = "denight" /obj/item/clothing/glasses/night/Initialize() @@ -1048,7 +1052,7 @@ BLIND // can't see anything origin_tech = list(TECH_MAGNET = 3) toggleable = 1 vision_flags = SEE_MOBS - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE flash_protection = FLASH_PROTECTION_REDUCED item_flags = ITEM_FLAG_AIRTIGHT @@ -1165,11 +1169,9 @@ BLIND // can't see anything if(active && slot == slot_glasses) user.AddOverlays(mob_overlay, ATOM_ICON_CACHE_PROTECTED) user.AddOverlays(mob_overlay_emis, TRUE) - user.z_flags |= ZMM_MANGLE_PLANES else user.CutOverlays(mob_overlay, ATOM_ICON_CACHE_PROTECTED) user.AddOverlays(mob_overlay_emis, TRUE) - user.z_flags &= ZMM_MANGLE_PLANES return ..() /obj/item/clothing/glasses/eyepatch/hud/Destroy() @@ -1229,7 +1231,7 @@ BLIND // can't see anything name = "MESpatch" desc = "An optical meson scanner display that connects directly to the optic nerve of the user, giving you cool green vision at the low cost of your only other eye." vision_flags = SEE_TURFS - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE eye_color = COLOR_LIME /obj/item/clothing/glasses/eyepatch/hud/meson/Initialize() @@ -1255,7 +1257,7 @@ BLIND // can't see anything name = "HEATpatch" desc = "A thermal-type heads-up display that connects directly to the optic nerve of the user. Double the tacticool, half the eyes." vision_flags = SEE_MOBS - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE eye_color = COLOR_ORANGE /obj/item/clothing/glasses/eyepatch/hud/thermal/Initialize() @@ -1273,7 +1275,7 @@ BLIND // can't see anything name = "NITEpatch" desc = "A light-amplifying display that connects directly to the optic nerve of the user. Helps you avoid a battery charge from bumping an officer in the dark." darkness_view = 7 - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE eye_color = COLOR_GREEN /obj/item/clothing/glasses/eyepatch/hud/night/Initialize() diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index c96d1257d4a..9602747180f 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -133,7 +133,7 @@ icon_state = "jensenshades" item_state = "jensenshades" vision_flags = SEE_MOBS - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE /obj/item/clothing/glasses/hud/security/process_hud(var/mob/M) process_sec_hud(M, 1) diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm index 96698c7b8d3..01b1732eedd 100644 --- a/code/modules/clothing/head/hardhat.dm +++ b/code/modules/clothing/head/hardhat.dm @@ -7,7 +7,7 @@ light_overlay = "hardhat_light" contained_sprite = TRUE action_button_name = "Toggle Headlamp" - brightness_on = 4 //luminosity when on + light_range = 4 //luminosity when on armor = list( MELEE = ARMOR_MELEE_RESISTANT, BULLET = ARMOR_BALLISTIC_MINOR, @@ -21,7 +21,6 @@ w_class = WEIGHT_CLASS_NORMAL siemens_coefficient = 0.9 max_pressure_protection = FIRESUIT_MAX_PRESSURE - light_wedge = LIGHT_WIDE drop_sound = 'sound/items/drop/helm.ogg' pickup_sound = 'sound/items/pickup/helm.ogg' diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index 9c4af5e6984..2ece6e05a7e 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -469,7 +469,6 @@ action_button_name = "Toggle Helmet Light" light_overlay = "helmet_light_dual" - brightness_on = 6 - light_wedge = LIGHT_WIDE + light_range = 6 camera = /obj/machinery/camera/network/tcfl on = 0 diff --git a/code/modules/clothing/spacesuits/rig/rig_pieces.dm b/code/modules/clothing/spacesuits/rig/rig_pieces.dm index af91868996a..ebc43a992c7 100644 --- a/code/modules/clothing/spacesuits/rig/rig_pieces.dm +++ b/code/modules/clothing/spacesuits/rig/rig_pieces.dm @@ -9,8 +9,7 @@ body_parts_covered = HEAD|FACE|EYES heat_protection = HEAD|FACE|EYES cold_protection = HEAD|FACE|EYES - brightness_on = 4 - light_wedge = LIGHT_WIDE + light_range = 4 icon = 'icons/obj/clothing/hats.dmi' contained_sprite = FALSE diff --git a/code/modules/clothing/spacesuits/rig/suits/station.dm b/code/modules/clothing/spacesuits/rig/suits/station.dm index d3229631457..47c048b3980 100644 --- a/code/modules/clothing/spacesuits/rig/suits/station.dm +++ b/code/modules/clothing/spacesuits/rig/suits/station.dm @@ -2,7 +2,7 @@ camera = /obj/machinery/camera/network/mining light_overlay = "helmet_light_dual" light_color = "#ffcf2f" - brightness_on = 6 + light_range = 6 /obj/item/clothing/head/helmet/space/rig/industrial/himeo light_overlay = "helmet_light_himeo" diff --git a/code/modules/clothing/spacesuits/spacesuits.dm b/code/modules/clothing/spacesuits/spacesuits.dm index b7f3e79a4ac..f67bccec010 100644 --- a/code/modules/clothing/spacesuits/spacesuits.dm +++ b/code/modules/clothing/spacesuits/spacesuits.dm @@ -30,8 +30,7 @@ action_button_name = "Toggle Helmet Light" light_overlay = "helmet_light" - brightness_on = 4 - light_wedge = LIGHT_WIDE + light_range = 4 on = 0 /obj/item/clothing/head/helmet/space/Initialize() diff --git a/code/modules/clothing/spacesuits/syndi.dm b/code/modules/clothing/spacesuits/syndi.dm index 1e1c1cb7c00..9cdf8806a1f 100644 --- a/code/modules/clothing/spacesuits/syndi.dm +++ b/code/modules/clothing/spacesuits/syndi.dm @@ -15,7 +15,7 @@ RAD = ARMOR_RAD_MINOR ) siemens_coefficient = 0.5 - brightness_on = 6 + light_range = 6 contained_sprite = FALSE /obj/item/clothing/suit/space/syndicate diff --git a/code/modules/clothing/spacesuits/void/alien/unathi.dm b/code/modules/clothing/spacesuits/void/alien/unathi.dm index f4dd11852b6..9b8b2cd23bf 100644 --- a/code/modules/clothing/spacesuits/void/alien/unathi.dm +++ b/code/modules/clothing/spacesuits/void/alien/unathi.dm @@ -82,7 +82,7 @@ RAD = ARMOR_RAD_SMALL ) light_overlay = "helmet_light_dual_low" - brightness_on = 6 + light_range = 6 species_restricted = list(BODYTYPE_UNATHI) refittable = FALSE @@ -156,7 +156,7 @@ RAD = ARMOR_RAD_SHIELDED ) light_overlay = "helmet_light_dual_low" - brightness_on = 6 + light_range = 6 species_restricted = list(BODYTYPE_UNATHI) refittable = FALSE diff --git a/code/modules/clothing/spacesuits/void/merc.dm b/code/modules/clothing/spacesuits/void/merc.dm index 8be192e783b..f83d394b597 100644 --- a/code/modules/clothing/spacesuits/void/merc.dm +++ b/code/modules/clothing/spacesuits/void/merc.dm @@ -21,7 +21,7 @@ species_restricted = list(BODYTYPE_HUMAN) light_overlay = "merc_voidsuit_lights" camera = /obj/machinery/camera/network/mercenary - brightness_on = 6 + light_range = 6 light_color = "#ffffff" /obj/item/clothing/suit/space/void/merc diff --git a/code/modules/clothing/spacesuits/void/misc.dm b/code/modules/clothing/spacesuits/void/misc.dm index b9b7bebf5de..fbafae3da81 100644 --- a/code/modules/clothing/spacesuits/void/misc.dm +++ b/code/modules/clothing/spacesuits/void/misc.dm @@ -17,7 +17,7 @@ siemens_coefficient = 0.35 species_restricted = list(BODYTYPE_HUMAN) - brightness_on = 6 + light_range = 6 refittable = FALSE /obj/item/clothing/suit/space/void/sol @@ -65,7 +65,7 @@ refittable_species = list(BODYTYPE_HUMAN, BODYTYPE_TAJARA, BODYTYPE_IPC, BODYTYPE_SKRELL) - brightness_on = 6 + light_range = 6 /obj/item/clothing/suit/space/void/coalition name = "coalition vulture voidsuit" @@ -101,7 +101,7 @@ species_restricted = list(BODYTYPE_HUMAN) light_overlay = "helmet_light_xanu_voidsuit" - brightness_on = 6 + light_range = 6 /obj/item/clothing/suit/space/void/coalition/xanu name = "\improper Xanan eagle voidsuit" @@ -139,7 +139,7 @@ refittable_species = list(BODYTYPE_HUMAN, BODYTYPE_TAJARA, BODYTYPE_IPC) icon_supported_species_tags = list("taj") - brightness_on = 6 + light_range = 6 light_color = "#ffce01" /obj/item/clothing/head/helmet/space/void/coalition/galatea @@ -184,7 +184,7 @@ siemens_coefficient = 0.35 species_restricted = list(BODYTYPE_HUMAN) w_class = WEIGHT_CLASS_NORMAL - brightness_on = 6 + light_range = 6 refittable = FALSE /obj/item/clothing/suit/space/void/cruiser @@ -228,7 +228,7 @@ siemens_coefficient = 0.35 species_restricted = list(BODYTYPE_HUMAN) max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE + 10000 - brightness_on = 6 + light_range = 6 icon_supported_species_tags = list("ipc") refittable_species = list(BODYTYPE_HUMAN, BODYTYPE_IPC) @@ -330,7 +330,7 @@ siemens_coefficient = 0.35 species_restricted = list(BODYTYPE_HUMAN) light_overlay = "helmet_light_banshee" - brightness_on = 6 + light_range = 6 light_color = "#7ffbf7" desc_extended = "An easily recognized Einstein Engines-made PMC voidsuit piece. It is a telltale mark of corporate espionage and more often than not ends up buried with its user." icon_supported_species_tags = list("skr", "ipc") @@ -382,7 +382,7 @@ siemens_coefficient = 0.35 species_restricted = list(BODYTYPE_HUMAN) light_overlay = "helmet_light_dragon" - brightness_on = 6 + light_range = 6 light_color = "#7ffbf7" desc_extended = "An easily recognized Zeng-Hu Pharmaceuticals biohazard control suit helmet. Its bug-eyed goggle visor design is unique among its class, alongside cutting-edge radiation protection." icon_supported_species_tags = list("skr", "ipc") @@ -434,7 +434,7 @@ siemens_coefficient = 0.35 species_restricted = list(BODYTYPE_HUMAN) light_overlay = "helmet_light_caiman" - brightness_on = 6 + light_range = 6 light_color = "#ffce01" desc_extended = "An easily recognized Hephaestus terraforming suit helmet. Its low, protruding brow and heavy plating is useful in the event you happen to be cutting down things. Mostly trees. Hopefully trees." icon_supported_species_tags = list("una") @@ -486,7 +486,7 @@ siemens_coefficient = 0.35 species_restricted = list(BODYTYPE_HUMAN) light_overlay = "helmet_light_revenant" - brightness_on = 6 + light_range = 6 light_color = "#f65858" desc_extended = "An ominous helmet of Zavodskoi Interstellar make with its past veiled in mystery, used for high-end corporate backstabbing and secret operations." @@ -535,7 +535,7 @@ siemens_coefficient = 0.35 species_restricted = list(BODYTYPE_HUMAN) light_overlay = "freelancer_light" - brightness_on = 6 + light_range = 6 light_color = "#7ffbf7" refittable_species = list(BODYTYPE_HUMAN, BODYTYPE_TAJARA, BODYTYPE_IPC, BODYTYPE_UNATHI, BODYTYPE_SKRELL) @@ -582,7 +582,7 @@ ) siemens_coefficient = 0.35 species_restricted = list(BODYTYPE_HUMAN, BODYTYPE_UNATHI) - brightness_on = 6 + light_range = 6 icon_supported_species_tags = list("una") refittable_species = list(BODYTYPE_HUMAN, BODYTYPE_UNATHI) @@ -648,7 +648,7 @@ ) siemens_coefficient = 0.35 species_restricted = list(BODYTYPE_HUMAN, BODYTYPE_IPC, BODYTYPE_IPC_INDUSTRIAL, BODYTYPE_IPC_ZENGHU, BODYTYPE_IPC_BISHOP) - brightness_on = 6 + light_range = 6 /obj/item/clothing/suit/space/void/golden_deep name = "golden suit" @@ -1022,7 +1022,7 @@ item_state = "gadpathur_vulture_helm" species_restricted = list(BODYTYPE_HUMAN) - brightness_on = 6 + light_range = 6 /obj/item/clothing/suit/space/void/coalition/gadpathur name = "coalition vulture-GP voidsuit" @@ -1095,7 +1095,7 @@ contained_sprite = TRUE icon_supported_species_tags = list("ipc", "skr", "taj", "una", "vau", "vaw") refittable_species = list(BODYTYPE_HUMAN, BODYTYPE_IPC, BODYTYPE_TAJARA, BODYTYPE_UNATHI, BODYTYPE_SKRELL, BODYTYPE_VAURCA) - brightness_on = 6 + light_range = 6 siemens_coefficient = 0.35 /obj/item/clothing/head/helmet/space/void/sci/assunzione diff --git a/code/modules/clothing/spacesuits/void/station.dm b/code/modules/clothing/spacesuits/void/station.dm index 0fbf63a5adc..adc934c1212 100644 --- a/code/modules/clothing/spacesuits/void/station.dm +++ b/code/modules/clothing/spacesuits/void/station.dm @@ -24,7 +24,7 @@ max_heat_protection_temperature = SPACE_SUIT_MAX_HEAT_PROTECTION_TEMPERATURE + 2500 max_pressure_protection = ENG_VOIDSUIT_MAX_PRESSURE light_overlay = "helmet_light_dual_low" - brightness_on = 6 + light_range = 6 /obj/item/clothing/suit/space/void/engineering name = "engineering voidsuit" @@ -74,7 +74,7 @@ RAD = ARMOR_RAD_MINOR ) light_overlay = "merc_voidsuit_lights" - brightness_on = 6 + light_range = 6 /obj/item/clothing/suit/space/void/mining name = "mining voidsuit" @@ -120,7 +120,7 @@ RAD = ARMOR_RAD_SMALL ) light_overlay = "helmet_light_dual_low" - brightness_on = 6 + light_range = 6 refittable_species = list(BODYTYPE_HUMAN, BODYTYPE_TAJARA, BODYTYPE_IPC, BODYTYPE_UNATHI, BODYTYPE_SKRELL) /obj/item/clothing/suit/space/void/medical @@ -167,7 +167,7 @@ RAD = ARMOR_RAD_MINOR ) light_overlay = "helmet_light_dual_low" - brightness_on = 6 + light_range = 6 refittable_species = list(BODYTYPE_HUMAN, BODYTYPE_TAJARA, BODYTYPE_IPC, BODYTYPE_UNATHI, BODYTYPE_SKRELL) /obj/item/clothing/suit/space/void/security @@ -217,7 +217,7 @@ max_heat_protection_temperature = FIRE_HELMET_MAX_HEAT_PROTECTION_TEMPERATURE + 10000 // It is a suit designed for fire, enclosed max_pressure_protection = FIRESUIT_MAX_PRESSURE light_overlay = "helmet_light_dual_low" - brightness_on = 6 + light_range = 6 refittable_species = list(BODYTYPE_HUMAN, BODYTYPE_TAJARA, BODYTYPE_IPC, BODYTYPE_UNATHI, BODYTYPE_SKRELL, BODYTYPE_VAURCA) /obj/item/clothing/suit/space/void/atmos diff --git a/code/modules/clothing/suits/armor.dm b/code/modules/clothing/suits/armor.dm index f0fbfd31754..b817df8296b 100644 --- a/code/modules/clothing/suits/armor.dm +++ b/code/modules/clothing/suits/armor.dm @@ -217,6 +217,10 @@ QDEL_NULL(pockets) //Tactical armor has internal holster instead of pockets, so we null this out ClearOverlays() // Remove the holster's overlay. +/obj/item/clothing/suit/armor/tactical/Destroy() + QDEL_NULL(holster) + return ..() + /obj/item/clothing/suit/armor/tactical/attackby(obj/item/attacking_item, mob/user) ..() holster.attackby(attacking_item, user) diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm index 0cda0fd85d6..5fa0a2ded08 100644 --- a/code/modules/clothing/under/accessories/accessory.dm +++ b/code/modules/clothing/under/accessories/accessory.dm @@ -11,6 +11,8 @@ BODYTYPE_VAURCA_BULWARK = 'icons/mob/species/bulwark/accessories.dmi' ) + light_system = MOVABLE_LIGHT + var/slot = ACCESSORY_SLOT_GENERIC /// Determines how accessories will layer over eachother, with lower being beneath everything, and upper above @@ -120,13 +122,6 @@ /obj/item/clothing/accessory/proc/on_clothing_change(var/mob/user) update_light() -/obj/item/clothing/accessory/get_light_atom() - if(isclothing(loc)) - if(ismob(loc.loc)) - return loc.loc - return loc - return ..() - //default attackby behaviour /obj/item/clothing/accessory/attackby(obj/item/attacking_item, mob/user) ..() @@ -1412,14 +1407,15 @@ /obj/item/clothing/accessory/led_collar/Initialize() . = ..() color = pick("#00FFFF", "#FF0000", "#FF00FF", "#FF6600", "#CC00CC") - set_light(MINIMUM_USEFUL_LIGHT_RANGE, 1.2, color) + set_light_range_power_color(MINIMUM_USEFUL_LIGHT_RANGE, 1.2, color) + set_light_on(TRUE) /obj/item/clothing/accessory/led_collar/attack_self(mob/user) . = ..() var/new_color = input(user, "Select the color of \the [src]", "LED Collar Color Selection", color) as null|color if(new_color) color = new_color - set_light(MINIMUM_USEFUL_LIGHT_RANGE, 1.2, color) + set_light_range_power_color(MINIMUM_USEFUL_LIGHT_RANGE, 1.2, color) /obj/item/clothing/accessory/led_collar/get_accessory_mob_overlay(var/mob/living/carbon/human/H, var/force = FALSE) var/image/I = ..() diff --git a/code/modules/detectivework/tools/uvlight.dm b/code/modules/detectivework/tools/uvlight.dm index 2136bca6355..fa426bb7d39 100644 --- a/code/modules/detectivework/tools/uvlight.dm +++ b/code/modules/detectivework/tools/uvlight.dm @@ -11,7 +11,6 @@ var/list/scanned = list() var/list/stored_alpha = list() var/list/reset_objects = list() - uv_intensity = 255 var/range = 3 var/on = 0 var/step_alpha = 50 diff --git a/code/modules/heavy_vehicle/components/head.dm b/code/modules/heavy_vehicle/components/head.dm index 6b7ac4aa03d..9196023465b 100644 --- a/code/modules/heavy_vehicle/components/head.dm +++ b/code/modules/heavy_vehicle/components/head.dm @@ -6,6 +6,7 @@ gender = NEUTER var/vision_flags = 0 + var/lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE var/see_invisible = 0 var/obj/item/robot_parts/robot_component/radio/radio var/obj/item/robot_parts/robot_component/camera/camera @@ -79,6 +80,12 @@ invisible = see_invisible return invisible +/obj/item/mech_component/sensors/proc/get_lighting_alpha(powered) + var/l_alpha = 0 + if((total_damage <= 0.8 * max_damage) && active_sensors && powered) + l_alpha = lighting_alpha + return l_alpha + /obj/item/mech_component/sensors/ready_to_install() return (radio && camera) diff --git a/code/modules/heavy_vehicle/equipment/utility.dm b/code/modules/heavy_vehicle/equipment/utility.dm index 48399168b9c..9473125aa97 100644 --- a/code/modules/heavy_vehicle/equipment/utility.dm +++ b/code/modules/heavy_vehicle/equipment/utility.dm @@ -221,14 +221,15 @@ mech_layer = MECH_GEAR_LAYER var/on = 0 - var/brightness_on = 12 //can't remember what the maxed out value is + light_range = 8 light_color = LIGHT_COLOR_TUNGSTEN - light_wedge = LIGHT_WIDE origin_tech = list(TECH_MATERIAL = 1, TECH_ENGINEERING = 1) module_hints = list( "Alt Click(Icon): Light up a large area in front of the mech.", ) + light_system = MOVABLE_LIGHT + /obj/item/mecha_equipment/light/attack_self(var/mob/user) . = ..() if(.) @@ -250,10 +251,10 @@ /obj/item/mecha_equipment/light/update_icon() if(on) icon_state = "[initial(icon_state)]-on" - set_light(brightness_on, 1) else icon_state = "[initial(icon_state)]" - set_light(0) + set_light_on(on) + /obj/item/mecha_equipment/light/uninstalled() on = FALSE diff --git a/code/modules/heavy_vehicle/mech_life.dm b/code/modules/heavy_vehicle/mech_life.dm index 7e012dcfffc..9c23c83ed98 100644 --- a/code/modules/heavy_vehicle/mech_life.dm +++ b/code/modules/heavy_vehicle/mech_life.dm @@ -168,6 +168,7 @@ if(head) sight = head.get_sight(powered) see_invisible = head.get_invisible(powered) + lighting_alpha = head.get_lighting_alpha(power_profiled_time) if(!hatch_closed || (body && (body.pilot_coverage < 100 || body.transparent_cabin))) sight &= ~BLIND diff --git a/code/modules/heavy_vehicle/premade/combat.dm b/code/modules/heavy_vehicle/premade/combat.dm index 1cbea5729e6..2e948dc65aa 100644 --- a/code/modules/heavy_vehicle/premade/combat.dm +++ b/code/modules/heavy_vehicle/premade/combat.dm @@ -43,7 +43,7 @@ max_damage = 50 power_use = 50000 vision_flags = SEE_MOBS - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE /obj/item/mech_component/sensors/combat/prebuild() ..() diff --git a/code/modules/heavy_vehicle/premade/light.dm b/code/modules/heavy_vehicle/premade/light.dm index 8c1fd9c619a..ef42515577b 100644 --- a/code/modules/heavy_vehicle/premade/light.dm +++ b/code/modules/heavy_vehicle/premade/light.dm @@ -42,7 +42,7 @@ power_use = 12000 desc = "A series of high resolution optical sensors." vision_flags = SEE_TURFS - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE /obj/item/mech_component/sensors/light/prebuild() ..() diff --git a/code/modules/heavy_vehicle/premade/powerloader.dm b/code/modules/heavy_vehicle/premade/powerloader.dm index 89c46a621f3..bd788417190 100644 --- a/code/modules/heavy_vehicle/premade/powerloader.dm +++ b/code/modules/heavy_vehicle/premade/powerloader.dm @@ -160,7 +160,7 @@ gender = PLURAL power_use = 50000 vision_flags = SEE_MOBS - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE /obj/item/mech_component/sensors/combatripley/prebuild() ..() diff --git a/code/modules/heavy_vehicle/premade/pra.dm b/code/modules/heavy_vehicle/premade/pra.dm index 09758da491c..bffc8271987 100644 --- a/code/modules/heavy_vehicle/premade/pra.dm +++ b/code/modules/heavy_vehicle/premade/pra.dm @@ -42,7 +42,7 @@ max_damage = 50 power_use = 50000 vision_flags = SEE_MOBS - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE /obj/item/mech_component/sensors/pra_egg/prebuild() ..() diff --git a/code/modules/holodeck/HolodeckObjects.dm b/code/modules/holodeck/HolodeckObjects.dm index 72d522aa424..07fa8e31bab 100644 --- a/code/modules/holodeck/HolodeckObjects.dm +++ b/code/modules/holodeck/HolodeckObjects.dm @@ -91,7 +91,6 @@ icon_state = "0" footstep_sound = null plane = SPACE_PLANE - dynamic_lighting = 0 /turf/simulated/floor/holofloor/space/Initialize() . = ..() diff --git a/code/modules/hydroponics/seed.dm b/code/modules/hydroponics/seed.dm index 011a05ea7f0..91e96979c10 100644 --- a/code/modules/hydroponics/seed.dm +++ b/code/modules/hydroponics/seed.dm @@ -338,10 +338,7 @@ // Handle light requirements. if(!light_supplied) - if (TURF_IS_DYNAMICALLY_LIT(current_turf)) - light_supplied = current_turf.get_lumcount(0, 3) * 10 - else - light_supplied = 5 + light_supplied = current_turf.get_lumcount(0, 3) * 10 if(light_supplied) if(check_light_tolerances(light_supplied)) @@ -382,10 +379,7 @@ // Handle light requirements. if(!light_supplied) - if (TURF_IS_DYNAMICALLY_LIT(current_turf)) - light_supplied = current_turf.get_lumcount(0, 3) * 10 - else - light_supplied = 5 + light_supplied = current_turf.get_lumcount(0, 3) * 10 // Are we within the preference zone for temperature? If so, add to the chance of growth. if(check_heat_preferences(environment)) diff --git a/code/modules/hydroponics/trays/tray.dm b/code/modules/hydroponics/trays/tray.dm index 110d1e89ad0..9e00381b3ac 100644 --- a/code/modules/hydroponics/trays/tray.dm +++ b/code/modules/hydroponics/trays/tray.dm @@ -758,10 +758,7 @@ if(closed_system && mechanical) light_available = tray_light else - if(TURF_IS_DYNAMICALLY_LIT(T)) - light_available = T.get_lumcount(0, 3) * 10 - else - light_available = 5 + light_available = T.get_lumcount(0, 3) * 5 // If it's a mechanical tray, provide precise information to the user about the plant's conditions. if(mechanical) diff --git a/code/modules/hydroponics/trays/tray_process.dm b/code/modules/hydroponics/trays/tray_process.dm index 76e9236d09c..bc5c00ecb6b 100644 --- a/code/modules/hydroponics/trays/tray_process.dm +++ b/code/modules/hydroponics/trays/tray_process.dm @@ -104,10 +104,7 @@ // Handle light requirements for upcoming logic. var/light_supplied if(!closed_system) - if (TURF_IS_DYNAMICALLY_LIT(T)) - light_supplied = T.get_lumcount(0, 3) * 10 - else - light_supplied = 5 + light_supplied = T.get_lumcount(0, 3) * 10 else light_supplied = tray_light diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index 903b0ffacbd..74bb3f85275 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -5,6 +5,8 @@ icon = 'icons/obj/assemblies/electronic_setups.dmi' icon_state = "setup_small" item_flags = ITEM_FLAG_NO_BLUDGEON + light_system = MOVABLE_LIGHT + var/max_components = IC_COMPONENTS_BASE var/max_complexity = IC_COMPLEXITY_BASE var/opened = 0 diff --git a/code/modules/integrated_electronics/subtypes/output.dm b/code/modules/integrated_electronics/subtypes/output.dm index 5ec321e5671..ab71ac6fbad 100644 --- a/code/modules/integrated_electronics/subtypes/output.dm +++ b/code/modules/integrated_electronics/subtypes/output.dm @@ -69,7 +69,8 @@ var/light_brightness = 3 var/light_rgb = COLOR_WHITE power_draw_idle = 0 // Adjusted based on brightness. - light_wedge = LIGHT_WIDE + + light_system = MOVABLE_LIGHT /obj/item/integrated_circuit/output/light/do_work() light_toggled = !light_toggled @@ -77,12 +78,13 @@ /obj/item/integrated_circuit/output/light/proc/update_lighting() if(assembly) - var/atom/atom_holder = assembly.get_assembly_holder() - if(light_toggled) - atom_holder.set_light(l_range = light_brightness, l_power = light_brightness, l_color = light_rgb, uv = 0, angle = light_wedge) - else - atom_holder.set_light(0) - power_draw_idle = light_toggled ? light_brightness * 2 : 0 + var/atom/movable/atom_holder = assembly.get_assembly_holder() + if(istype(atom_holder)) + if(light_toggled) + atom_holder.set_light_on(FALSE) //make sure the atom holder has movable_light set + else + atom_holder.set_light_on(TRUE) + power_draw_idle = light_toggled ? light_brightness * 2 : 0 /obj/item/integrated_circuit/output/light/disconnect_all() ..() @@ -98,6 +100,10 @@ light_rgb = new_color light_brightness = brightness + var/atom/movable/atom_holder = assembly.get_assembly_holder() + if(istype(atom_holder)) + atom_holder.set_light_range_power_color(light_brightness, light_brightness, light_rgb) + ..() /obj/item/integrated_circuit/output/light/power_fail() // Turns off the flashlight if there's no power left. diff --git a/code/modules/lighting/_LIGHTING_README.MD b/code/modules/lighting/_LIGHTING_README.MD new file mode 100644 index 00000000000..a7e7166e6b8 --- /dev/null +++ b/code/modules/lighting/_LIGHTING_README.MD @@ -0,0 +1,75 @@ +# The Lighting Systems +## Introduction + +Hello reader, and welcome to the coders guide to lighting. TGMC uses three different lighting systems: Static Lighting, Movable Lighting and Hybrid Lighting +These all have their pros and cons, and are explained later in this file. +For now we will look at the frameworks we have pertaining to lighting. + +```dm +//Our vars: +//The "intensity" of our light to determine how much it actually lights up +var/light_power +// The range of our light, aka how many turfs are actually lit up +var/light_range +//the color of our light +var/light_color +///whether the light is actually on or not, use /atom/proc/turn_on() to set this +var/light_on +``` + +Additionally, we have SSlighting, the lighting subsystem which handles lighting updates for Static and Hybrid lighting. +This subsystems processes enqueued lighting object, corner and source updates, as well as taking enqueued hybrid lighting updates. +You shouldnt really be touching this as it primarily just stops too many updates from happening at once. + +## The Lighting systems +As mentioned previously,lighting is split into three seperate systems who's functionality, benefits and downsides will be discussed below + +Seperate from these systems we also have a system to update the base lighting of an area, we do this using "Base lighting" + +```dm +/area/proc/set_base_lighting(new_base_lighting_color = -1, new_alpha = -1) +``` +Use this to set areas as required to luminosity. This is expensive-ish to apply/update but is very cheap to maintain. It also enables area specific light intensity and color changes. + +### Static Lighting +Static lighting consists of a single, static_lighting_source light source which gets all turfs in view, then tells their /datum/static_lighting_objects to update themselves. These lighting objects manage two things: lighting corners, and an underlay. The lighting corners hold data for the edges of turfs next to darkness to allow a smooth transition from dark to light, and the actual lighting is done using an underlay which is layered over the darkness layer in order to create light. Color is changed using a color matrix. +The advantage of this system, is that it is cheap, as long as it does not need to actively update opacity changes or a moving light target. +This system can also be used for as large lights as you want. +The disadvantage however is that updating this type of light, such as when it moves is relatively expensive, and colors are not always the prettiest. Additionally, lighting corners are known to be a large source of RAM usage and thus you should only load lighting objects in areas hat it is needed using /area/var/static_lighting. +Thus this should be your go to choice for large, frequent, immobile lights. + +To update lights using this system use +```dm +/atom/proc/set_light(l_range, l_power, l_color, mask_type) +``` +Note that the use of mask_type only is applicable to Hybrid lights. + +### Movable lighting +Movable lighting is extremely simple and cheap as it requires no updates. This is done by replacing a large amount of updating objects with one single, large vis_contents overlay, which we apply and manage through a component (/datum/component/overlay_lighting). This means that it will move smoothly when the owner moves and requires no updating, but also means that rendering issues might occur, where the overlay will seemingly "pop in" to existence as it suddenly renders when someone walks around a corner or into the 1/2-tile render buffer around the edges of the viewport. +Thus this should be your go to ideal cheap light for small and mobile lights (NOT turfs or anchored objects!). This light also typically has more saturated colors than static lighting. + +Note that this lighting type utilises special update procs from the other two lighting types, specifically +```dm +//update light variables +/atom/movable/proc/set_light_range_power_color(range, power, color) + set_light_range(range) + set_light_power(power) + set_light_color(color) + +//turn the light on and off without changing any variables +/atom/proc/set_light_on(new_value) +``` + +### Hybrid lighting +Hybrid lighting is, as the name implies, a hybrid of the two above systems. It still needs to update when the owner moves, or something in view changes like static lighting does, but uses overlays to hide areas using shadows. As a result, this has similar if not better performance to Static lighting, but has a higher drain on player GPU and thus you should ideally avoid lagging players that play on terrible computers too much. This means that you should use this lighting in decently sized lights that act as centerpieces for a scene (i.e. a fire, supermatter, etc.) since it combines the best of static and movable lighting at a clientside performance cost. +As a rule of thumb most items will be fine using this except for light fixtures, as lag mostly seems to crop up from multiple large lighting sources. +Using lights for turf based fires and large floodlights is thus fine, but be careful with frquesnt use. +It functions by fetching all nearby blockers, then calculating triangles behind these blocked areas which it then masks with overlays. +These overlays then render as an alpha mask blocking the light from appearing. +This system also supports non-round lights, such as light cones, rotating lights, and shimmering lights through the use of +```dm +var/mask_type +``` +which determines which type of icon we are going to use as the base when drawing this lights (/atom/movable/lighting_mask/flicker for shimmering lights as an example). + +Actual updates however are handled through the same procs as Static lighting, and the mask_type argument on set_light() allows you to change the mask type that is being used on the fly. diff --git a/code/modules/lighting/__lighting_docs.dm b/code/modules/lighting/__lighting_docs.dm deleted file mode 100644 index fcd2e63d51a..00000000000 --- a/code/modules/lighting/__lighting_docs.dm +++ /dev/null @@ -1,56 +0,0 @@ -/* - -- Aurora directional lighting system, based off of /vg/lights. -- - - Documentation is present in most of the code files. - lighting_atom.dm -> procs/vars for tracking/managing lights attached to objects. - lighting_turf.dm -> procs/vars for managing lighting overlays bound to turfs, tracking lights affecting said turf, and getting information about the turf's light level. - lighting_corner.dm -> contains code for tracking per-corner lighting data. - lighting_source.dm -> contains actual light emitter datum & core lighting calculations. Directional lights and Z-lights are implemented here. - lighting_source_novis.dm -> Same as lighting_source.dm, but does not take visibility into account - used for sun objects. - lighting_profiler.dm -> contains code used for the diagnostic lighting profiler (currently disabled). - lighting_area.dm -> contains area vars/procs for managing an area's dynamic lighting state. - lighting_verbs.dm -> contains verbs for debugging lighting. - -*/ - -/* - Useful procs when using lights: - -/atom/proc/set_light(range, power, color, uv_power, angle, no_update) - desc: Sets an atom's light emission. `set_light(FALSE)` will disable the light. - args: - range -> the range of the light. 1.4 is the lowest possible value here. - power -> the power (intensity) of the light. Generally should be 1 or lower. Optional. - color -> The hex string (#FFFFFF) color of the light. Optional. - uv_power -> The UV power of this light. Must be between 0 and 255. Optional. - angle -> The angle of the cone that the light should shine at (directional lighting). Behavior of lights over 180 degrees is undefined. Best to stick to using the LIGHT_ defines for this. Optional. - no_update -> if TRUE, the light will not be updated. Useful for when making several of these calls to the same object. Optional. - -/atom/proc/set_opacity(new_opacity) - desc: Sets an atom's opacity, updating affecting lights' visibility. Returns TRUE if opacity changed, FALSE otherwise. - args: - new_opacity -> the new opacity value. - -/turf/proc/reconsider_lights() - desc: Cause all lights affecting this turf to recalculate visibility. - args: none - -/turf/proc/force_update_lights() - desc: Force all lights affecting this turf to regenerate. Slow, use reconsider_lights instead when possible. - args: none - -/turf/proc/get_avg_color() - desc: Gets the average color of this tile as a hexadecimal color string. Used by cameras. - -/turf/proc/get_lumcount(minlum = 0, maxlum = 1) - desc: Gets the brightness of this tile. If not dynamically lit, always returns 0.5, otherwise returns the average brightness of all 4 corners, scaled between minlum and maxlum. - args: - minlum -> the low-bound of the scalar. - maxlum -> the high-bound of the scalar. - -/turf/proc/get_uv_lumcount(minlum = 0, maxlum = 1) - desc: Same as above, but only considers UV light. - args: - minlum -> the low-bound of the scalar. - maxlum -> the high-bound of the scalar. -*/ diff --git a/code/modules/lighting/_lighting_defs.dm b/code/modules/lighting/_lighting_defs.dm deleted file mode 100644 index c4cb90e3236..00000000000 --- a/code/modules/lighting/_lighting_defs.dm +++ /dev/null @@ -1,58 +0,0 @@ -// This is the define used to calculate falloff. -#define LUM_FALLOFF(Cx,Cy,Tx,Ty,HEIGHT) (1 - CLAMP01(sqrt(((Cx) - (Tx)) ** 2 + ((Cy) - (Ty)) ** 2 + HEIGHT) / max(1, actual_range))) - -// Macro that applies light to a new corner. -// It is a macro in the interest of speed, yet not having to copy paste it. -// If you're wondering what's with the backslashes, the backslashes cause BYOND to not automatically end the line. -// As such this all gets counted as a single line. -// The braces and semicolons are there to be able to do this on a single line. - -#define APPLY_CORNER_SIMPLE(C) \ - . = light_power; \ - var/OLD = effect_str[C]; \ - effect_str[C] = .; \ - C.update_lumcount \ - ( \ - (. * lum_r) - (OLD * applied_lum_r), \ - (. * lum_g) - (OLD * applied_lum_g), \ - (. * lum_b) - (OLD * applied_lum_b), \ - (. * lum_u) - (OLD * applied_lum_u), \ - FALSE \ - ); - -#define APPLY_CORNER(C,now,Tx,Ty,hdiff) \ - . = LUM_FALLOFF(C.x, C.y, Tx, Ty, hdiff) * light_power; \ - var/OLD = effect_str[C]; \ - effect_str[C] = .; \ - C.update_lumcount \ - ( \ - (. * lum_r) - (OLD * applied_lum_r), \ - (. * lum_g) - (OLD * applied_lum_g), \ - (. * lum_b) - (OLD * applied_lum_b), \ - (. * lum_u) - (OLD * applied_lum_u), \ - now \ - ); - -// I don't need to explain what this does, do I? -#define REMOVE_CORNER(C,now) \ - . = -effect_str[C]; \ - C.update_lumcount \ - ( \ - . * applied_lum_r, \ - . * applied_lum_g, \ - . * applied_lum_b, \ - . * applied_lum_u, \ - now \ - ); - -// Converts two Z levels into a height value for LUM_FALLOFF or HEIGHT_FALLOFF. -#define CALCULATE_CORNER_HEIGHT(ZA,ZB) (((max(ZA,ZB) - min(ZA,ZB)) + 1) * LIGHTING_HEIGHT * LIGHTING_Z_FACTOR) - -#define APPLY_CORNER_BY_HEIGHT(now) \ - if (C.z != Sz) { \ - corner_height = CALCULATE_CORNER_HEIGHT(C.z, Sz); \ - } \ - else { \ - corner_height = LIGHTING_HEIGHT; \ - } \ - APPLY_CORNER(C, now, Sx, Sy, corner_height); diff --git a/code/modules/lighting/emissive_blocker.dm b/code/modules/lighting/emissive_blocker.dm new file mode 100644 index 00000000000..218847852cf --- /dev/null +++ b/code/modules/lighting/emissive_blocker.dm @@ -0,0 +1,34 @@ +/** + * Internal atom that copies an appearance on to the blocker plane + * + * Copies an appearance vis render_target and render_source on to the emissive blocking plane. + * This means that the atom in question will block any emissive sprites. + * This should only be used internally. If you are directly creating more of these, you're + * almost guaranteed to be doing something wrong. + */ +/atom/movable/emissive_blocker + name = "emissive blocker" + plane = EMISSIVE_PLANE + layer = FLOAT_LAYER + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + //Why? + //render_targets copy the transform of the target as well, but vis_contents also applies the transform + //to what's in it. Applying RESET_TRANSFORM here makes vis_contents not apply the transform. + //Since only render_target handles transform we don't get any applied transform "stacking" + appearance_flags = EMISSIVE_APPEARANCE_FLAGS + +/atom/movable/emissive_blocker/Initialize(mapload, source) + . = ..() + verbs.Cut() //Cargo culting from lighting object, this maybe affects memory usage? + + render_source = source + color = GLOB.em_block_color + + +/atom/movable/emissive_blocker/ex_act(severity) + return FALSE + +//Prevents people from moving these after creation, because they shouldn't be. +/atom/movable/emissive_blocker/forceMove(atom/destination, no_tp=FALSE, harderforce = FALSE) + if(harderforce) + return ..() diff --git a/code/modules/lighting/lighting_area.dm b/code/modules/lighting/lighting_area.dm index 78328caf474..2b6a1409f38 100644 --- a/code/modules/lighting/lighting_area.dm +++ b/code/modules/lighting/lighting_area.dm @@ -1,23 +1,59 @@ /area - luminosity = TRUE - var/dynamic_lighting = TRUE + luminosity = 1 + ///The mutable appearance we underlay to show light + var/mutable_appearance/lighting_effect = null + ///Whether this area has a currently active base lighting, bool + var/area_has_base_lighting = FALSE + ///alpha 0-255 of lighting_effect and thus baselighting intensity + var/base_lighting_alpha = 0 + ///The colour of the light acting on this area + var/base_lighting_color = COLOR_WHITE -/area/proc/set_dynamic_lighting(var/new_dynamic_lighting = TRUE) - //L_PROF(src, "area_sdl") - - if (new_dynamic_lighting == dynamic_lighting) +/area/proc/set_base_lighting(new_base_lighting_color = -1, new_alpha = -1) + if(base_lighting_alpha == new_alpha && base_lighting_color == new_base_lighting_color) return FALSE - - dynamic_lighting = new_dynamic_lighting - - if (new_dynamic_lighting) - for (var/turf/T in src) - if (T.dynamic_lighting) - T.lighting_build_overlay() - - else - for (var/turf/T in src) - if (T.lighting_overlay) - T.lighting_clear_overlay() - + if(new_alpha != -1) + base_lighting_alpha = new_alpha + if(new_base_lighting_color != -1) + base_lighting_color = new_base_lighting_color + update_base_lighting() return TRUE + +/area/vv_edit_var(var_name, var_value) + switch(var_name) + if("base_lighting_color") + set_base_lighting(new_base_lighting_color = var_value) + return TRUE + if("base_lighting_alpha") + set_base_lighting(new_alpha = var_value) + return TRUE + return ..() + +/area/proc/update_base_lighting() + if(!area_has_base_lighting && (!base_lighting_alpha || !base_lighting_color)) + return + + if(!area_has_base_lighting) + add_base_lighting() + return + remove_base_lighting() + if(base_lighting_alpha && base_lighting_color) + add_base_lighting() + +/area/proc/remove_base_lighting() + for(var/turf/T in src) + T.overlays -= lighting_effect + QDEL_NULL(lighting_effect) + area_has_base_lighting = FALSE + +/area/proc/add_base_lighting() + lighting_effect = mutable_appearance('icons/effects/alphacolors.dmi', "white") + lighting_effect.plane = LIGHTING_PLANE + lighting_effect.layer = LIGHTING_PRIMARY_LAYER + lighting_effect.blend_mode = BLEND_ADD + lighting_effect.alpha = base_lighting_alpha + lighting_effect.color = base_lighting_color + for(var/turf/T in src) + T.overlays += lighting_effect + T.luminosity = 1 + area_has_base_lighting = TRUE diff --git a/code/modules/lighting/lighting_atom.dm b/code/modules/lighting/lighting_atom.dm index 092a2534ad4..a544dd38209 100644 --- a/code/modules/lighting/lighting_atom.dm +++ b/code/modules/lighting/lighting_atom.dm @@ -1,123 +1,185 @@ -/atom - var/light_power = 1 // Intensity of the light. - var/light_range = 0 // Range in tiles of the light. - var/light_color // Hexadecimal RGB string representing the colour of the light. - var/uv_intensity = 255 // How much UV light is being emitted by this object. Valid range: 0-255. - var/light_wedge // The angle that the light's emission should be restricted to. null for omnidirectional. -#ifdef ENABLE_SUNLIGHT - var/light_novis // If TRUE, visibility checks will be skipped when calculating this light. -#endif - - var/tmp/datum/light_source/light // Our light source. Don't fuck with this directly unless you have a good reason! - var/tmp/list/light_sources // Any light sources that are "inside" of us, for example, if src here was a mob that's carrying a flashlight, that flashlight's light source would be part of this list. - -// Nonesensical value for l_color default, so we can detect if it gets set to null. -#define NONSENSICAL_VALUE -99999 // The proc you should always use to set the light of this atom. -/atom/proc/set_light(var/l_range, var/l_power, var/l_color = NONSENSICAL_VALUE, var/uv = NONSENSICAL_VALUE, var/angle = NONSENSICAL_VALUE, var/no_update = FALSE) - //L_PROF(src, "atom_setlight") - . = FALSE // don't update if nothing changed - +// Nonesensical value for l_color default, so we can detect if it gets set to null. +#define NONSENSICAL_VALUE -99999 +/atom/proc/set_light(l_range, l_power, l_color = NONSENSICAL_VALUE, mask_type = null) if(l_range > 0 && l_range < MINIMUM_USEFUL_LIGHT_RANGE) l_range = MINIMUM_USEFUL_LIGHT_RANGE //Brings the range up to 1.4, which is just barely brighter than the soft lighting that surrounds players. - . = TRUE - if (l_power != null && light_power != l_power) + + if(l_power != null && l_power != light_power) light_power = l_power . = TRUE - if (l_range != null && light_range != l_range) + + if(l_range != null && l_range != light_range) light_range = l_range + light_on = (light_range>0) ? TRUE : FALSE . = TRUE - if (l_color != NONSENSICAL_VALUE && light_color != l_color) + if(l_color != NONSENSICAL_VALUE && l_color != light_color) light_color = l_color . = TRUE - if (uv != NONSENSICAL_VALUE && uv_intensity != uv) - set_uv(uv, no_update = TRUE) + if(mask_type != null && mask_type != light_mask_type) + light_mask_type = mask_type . = TRUE - if (angle != NONSENSICAL_VALUE && light_wedge != angle) - light_wedge = angle - . = TRUE - - if(!no_update && .) + if(.) update_light() -#undef NONSENSICAL_VALUE + SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT, l_range, l_power, l_color) -/atom/proc/set_uv(var/intensity, var/no_update) - //L_PROF(src, "atom_setuv") - if (intensity < 0 || intensity > 255) - intensity = min(max(intensity, 255), 0) - uv_intensity = intensity +/atom/proc/fade_light(new_colour, time) + light_color = new_colour + if(light?.our_mask) + animate(light.our_mask, color = new_colour, time = time) - if (no_update) - return - - update_light() - -// Will update the light (duh). -// Creates or destroys it if needed, makes it update values, makes sure it's got the correct source turf... +/// Will update the light (duh).Creates or destroys it if needed, makes it update values, makes sure it's got the correct source turf... /atom/proc/update_light() - SHOULD_NOT_SLEEP(TRUE) + set waitfor = FALSE - if (QDELING(src)) + if(QDELETED(src)) + return + if(light_system == STATIC_LIGHT) + static_update_light() return - //L_PROF(src, "atom_update") - - if (!light_power || !light_range) // We won't emit light anyways, destroy the light source. + if((!light_power || !light_range) && light) // We won't emit light anyways, destroy the light source. QDEL_NULL(light) - else - . = get_light_atom() - -#ifdef ENABLE_SUNLIGHT - if (light) // Update the light or create it if it does not exist. - light.update(.) - else if (light_novis) - light = new/datum/light_source/sunlight(src, .) - else - light = new/datum/light_source(src, .) -#else - if (light) - light.update(.) - else - light = new /datum/light_source(src, .) -#endif - -/atom/proc/get_light_atom() - if (!istype(loc, /atom/movable)) // We choose what atom should be the top atom of the light here. - return src - return loc + return + if(light && light_mask_type && (light_mask_type != light.mask_type)) + QDEL_NULL(light) + if(!light) // Update the light or create it if it does not exist. + light = new /datum/dynamic_light_source(src, light_mask_type) + return + light.set_light(light_range, light_power, light_color) + light.update_position() -// Should always be used to change the opacity of an atom. -// It notifies (potentially) affected light sources so they can update (if needed). -/atom/proc/set_opacity(var/new_opacity) - if (new_opacity == opacity) - return FALSE - - //L_PROF(src, "atom_setopacity") +/** + * Updates the atom's opacity value. + * + * This exists to act as a hook for associated behavior. + * It notifies (potentially) affected light sources so they can update (if needed). + */ +/atom/proc/set_opacity(new_opacity) + if(new_opacity == opacity) + return + SEND_SIGNAL(src, COMSIG_ATOM_SET_OPACITY, new_opacity) + . = opacity opacity = new_opacity - var/turf/T = loc - if (!isturf(T)) - return FALSE - if (new_opacity == TRUE) - T.has_opaque_atom = TRUE - T.reconsider_lights() -#ifdef AO_USE_LIGHTING_OPACITY - T.regenerate_ao() -#endif +/atom/movable/set_opacity(new_opacity) + . = ..() + if(isnull(.) || !isturf(loc)) + return + + if(opacity) + AddElement(/datum/element/light_blocking) else - var/old_has_opaque_atom = T.has_opaque_atom - T.recalc_atom_opacity() - if (old_has_opaque_atom != T.has_opaque_atom) - T.reconsider_lights() + RemoveElement(/datum/element/light_blocking) - updateVisibility(src, FALSE) - return TRUE +/turf/set_opacity(new_opacity) + . = ..() + if(isnull(.)) + return + recalculate_directional_opacity() + +/atom/vv_edit_var(var_name, var_value) + switch(var_name) + if("light_range") + if(light_system != MOVABLE_LIGHT) + set_light(l_range = var_value) + else + set_light_range(var_value) + datum_flags |= DF_VAR_EDITED + return TRUE + + if("light_power") + if(light_system != MOVABLE_LIGHT) + set_light(l_power = var_value) + else + set_light_power(var_value) + datum_flags |= DF_VAR_EDITED + return TRUE + + if("light_color") + if(light_system != MOVABLE_LIGHT) + set_light(l_color = var_value) + else + set_light_color(var_value) + datum_flags |= DF_VAR_EDITED + return TRUE + return ..() + + +/atom/proc/flash_lighting_fx( + _range = FLASH_LIGHT_RANGE, + _power = FLASH_LIGHT_POWER, + _color = COLOR_WHITE, + _duration = FLASH_LIGHT_DURATION, + _reset_lighting = TRUE, + _flash_times = 1) + new /obj/effect/light_flash(get_turf(src), _range, _power, _color, _duration, _flash_times) + + +/obj/effect/light_flash/Initialize(mapload, _range = FLASH_LIGHT_RANGE, _power = FLASH_LIGHT_POWER, _color = COLOR_WHITE, _duration = FLASH_LIGHT_DURATION, _flash_times = 1) + light_range = _range + light_power = _power + light_color = _color + . = ..() + do_flashes(_flash_times, _duration) + +/obj/effect/light_flash/proc/do_flashes(_flash_times, _duration) + set waitfor = FALSE + for(var/i in 1 to _flash_times) + //Something bad happened + if(!(light?.our_mask)) + break + light.our_mask.alpha = 255 + animate(light.our_mask, time = _duration, easing = SINE_EASING, alpha = 0, flags = ANIMATION_END_NOW) + sleep(_duration) //this is extremely short so it's ok to sleep + qdel(src) + +/atom/proc/set_light_range(new_range) + if(new_range == light_range) + return + SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_RANGE, new_range) + . = light_range + light_range = new_range + + +/atom/proc/set_light_power(new_power) + if(new_power == light_power) + return + SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_POWER, new_power) + . = light_power + light_power = new_power + + +/atom/proc/set_light_color(new_color) + if(new_color == light_color) + return + SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_COLOR, new_color) + . = light_color + light_color = new_color + + +/atom/proc/set_light_on(new_value) + if(new_value == light_on) + return + SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_ON, new_value) + . = light_on + light_on = new_value + + +/// Setter for the light flags of this atom. +/atom/proc/set_light_flags(new_value) + if(new_value == light_flags) + return + SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT_FLAGS, new_value) + . = light_flags + light_flags = new_value + diff --git a/code/modules/lighting/lighting_corner.dm b/code/modules/lighting/lighting_corner.dm deleted file mode 100644 index f8fa2082fb5..00000000000 --- a/code/modules/lighting/lighting_corner.dm +++ /dev/null @@ -1,233 +0,0 @@ -/var/datum/lighting_corner/dummy/dummy_lighting_corner = new -// Because we can control each corner of every lighting overlay. -// And corners get shared between multiple turfs (unless you're on the corners of the map, then 1 corner doesn't). -// For the record: these should never ever ever be deleted, even if the turf doesn't have dynamic lighting. - -// This list is what the code that assigns corners listens to, the order in this list is the order in which corners are added to the /turf/corners list. -/var/list/LIGHTING_CORNER_DIAGONAL = list(NORTHEAST, SOUTHEAST, SOUTHWEST, NORTHWEST) - -// This is the reverse of the above - the position in the array is a dir. Update this if the above changes. -var/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0, 2, 1) - -/datum/lighting_corner - var/turf/t1 // These are in no particular order. - var/t1i // Our index in this turf's corners list. - var/turf/t2 - var/t2i - var/turf/t3 - var/t3i - var/turf/t4 - var/t4i - - var/list/datum/light_source/affecting // Light sources affecting us. - var/active = FALSE // TRUE if one of our masters has dynamic lighting. - - var/x = 0 - var/y = 0 - var/z = 0 - - var/lum_r = 0 - var/lum_g = 0 - var/lum_b = 0 - var/lum_u = 0 // UV Radiation, not visible. - - var/needs_update = FALSE - - var/cache_r = LIGHTING_SOFT_THRESHOLD - var/cache_g = LIGHTING_SOFT_THRESHOLD - var/cache_b = LIGHTING_SOFT_THRESHOLD - var/cache_mx = 0 - -/datum/lighting_corner/New(turf/new_turf, diagonal) - SSlighting.lighting_corners += src - - t1 = new_turf - z = new_turf.z - t1i = REVERSE_LIGHTING_CORNER_DIAGONAL[diagonal] - - var/vertical = diagonal & ~(diagonal - 1) // The horizontal directions (4 and 8) are bigger than the vertical ones (1 and 2), so we can reliably say the lsb is the horizontal direction. - var/horizontal = diagonal & ~vertical // Now that we know the horizontal one we can get the vertical one. - - x = new_turf.x + (horizontal == EAST ? 0.5 : -0.5) - y = new_turf.y + (vertical == NORTH ? 0.5 : -0.5) - - // My initial plan was to make this loop through a list of all the dirs (horizontal, vertical, diagonal). - // Issue being that the only way I could think of doing it was very messy, slow and honestly overengineered. - // So we'll have this hardcode instead. - var/turf/T - var/i - - // Diagonal one is easy. - T = get_step(new_turf, diagonal) - if (T) // In case we're on the map's border. - if (!T.corners) - T.corners = list(null, null, null, null) - - t2 = T - i = REVERSE_LIGHTING_CORNER_DIAGONAL[diagonal] - t2i = i - T.corners[i] = src - - // Now the horizontal one. - T = get_step(new_turf, horizontal) - if (T) // Ditto. - if (!T.corners) - T.corners = list(null, null, null, null) - - t3 = T - i = REVERSE_LIGHTING_CORNER_DIAGONAL[((T.x > x) ? EAST : WEST) | ((T.y > y) ? NORTH : SOUTH)] // Get the dir based on coordinates. - t3i = i - T.corners[i] = src - - // And finally the vertical one. - T = get_step(new_turf, vertical) - if (T) - if (!T.corners) - T.corners = list(null, null, null, null) - - t4 = T - i = REVERSE_LIGHTING_CORNER_DIAGONAL[((T.x > x) ? EAST : WEST) | ((T.y > y) ? NORTH : SOUTH)] // Get the dir based on coordinates. - t4i = i - T.corners[i] = src - - update_active() - -#define OVERLAY_PRESENT(T) (T && T.lighting_overlay) - -/datum/lighting_corner/proc/update_active() - active = FALSE - - if (OVERLAY_PRESENT(t1) || OVERLAY_PRESENT(t2) || OVERLAY_PRESENT(t3) || OVERLAY_PRESENT(t4)) - active = TRUE - -#undef OVERLAY_PRESENT - -// God that was a mess, now to do the rest of the corner code! Hooray! -/datum/lighting_corner/proc/update_lumcount(delta_r, delta_g, delta_b, delta_u, now = FALSE) - if (!(delta_r + delta_g + delta_b)) // Don't check u since the overlay doesn't care about it. - return - - lum_r += delta_r - lum_g += delta_g - lum_b += delta_b - lum_u += delta_u - - // This needs to be down here instead of the above if so the lum values are properly updated. - if (needs_update) - return - - if (!now) - needs_update = TRUE - SSlighting.corner_queue += src - else - update_overlays(TRUE) - -#define UPDATE_MASTER(T) \ - if (T && T.lighting_overlay) { \ - if (now) { \ - T.lighting_overlay.update_overlay(); \ - } \ - else if (!T.lighting_overlay.needs_update) { \ - T.lighting_overlay.needs_update = TRUE; \ - SSlighting.overlay_queue += T.lighting_overlay; \ - } \ - } - - -#define AVERAGE_BELOW_CORNER(Tt, Ti) \ - if (TURF_IS_MIMICING(Tt)) { \ - T = GET_TURF_BELOW(Tt); \ - if (T && T.corners && TURF_IS_DYNAMICALLY_LIT_UNSAFE(T)) { \ - C = T.corners[Ti]; \ - if (C) { \ - divisor += 1; \ - lr += C.lum_r; \ - lg += C.lum_g; \ - lb += C.lum_b; \ - } \ - } \ - } - -#define UPDATE_ABOVE_CORNER(Tt, Ti) \ - if (Tt) { \ - T = GET_TURF_ABOVE(Tt); \ - if (TURF_IS_MIMICING(T) && TURF_IS_DYNAMICALLY_LIT_UNSAFE(T)) { \ - if (!T.corners) { \ - T.generate_missing_corners(); \ - } \ - C = T.corners[Ti]; \ - if (C && !C.needs_update) { \ - C.update_overlays(FALSE); \ - } \ - } \ - } - -/datum/lighting_corner/proc/update_overlays(now = FALSE) - var/lr = lum_r - var/lg = lum_g - var/lb = lum_b - -#ifdef USE_CORNER_ZBLEED - - var/divisor = 1 - var/datum/lighting_corner/C - var/turf/T - - AVERAGE_BELOW_CORNER(t1, t1i) - AVERAGE_BELOW_CORNER(t2, t2i) - AVERAGE_BELOW_CORNER(t3, t3i) - AVERAGE_BELOW_CORNER(t4, t4i) - - if (divisor > 1) - lr /= divisor - lg /= divisor - lb /= divisor - -#endif - - // Cache these values a head of time so 4 individual lighting overlays don't all calculate them individually. - var/mx = max(lr, lg, lb) // Scale it so 1 is the strongest lum, if it is above 1. - . = 1 // factor - if (mx > 1) - . = 1 / mx - - else if (mx < LIGHTING_SOFT_THRESHOLD) - . = 0 // 0 means soft lighting. - - if (.) - cache_r = round(lr * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD - cache_g = round(lg * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD - cache_b = round(lb * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD - else - cache_r = cache_g = cache_b = LIGHTING_SOFT_THRESHOLD - - cache_mx = round(mx, LIGHTING_ROUND_VALUE) - - UPDATE_MASTER(t1) - UPDATE_MASTER(t2) - UPDATE_MASTER(t3) - UPDATE_MASTER(t4) - -#ifdef USE_CORNER_ZBLEED - - UPDATE_ABOVE_CORNER(t1, t1i) - UPDATE_ABOVE_CORNER(t2, t2i) - UPDATE_ABOVE_CORNER(t3, t3i) - UPDATE_ABOVE_CORNER(t4, t4i) - -#endif - -#undef UPDATE_MASTER -#undef AVERAGE_BELOW_CORNER -#undef UPDATE_ABOVE_CORNER - -/datum/lighting_corner/Destroy(force = FALSE) - crash_with("Some fuck [force ? "force-" : ""]deleted a lighting corner.") - if (!force) - return QDEL_HINT_LETMELIVE - - SSlighting.lighting_corners -= src - return ..() - -/datum/lighting_corner/dummy/New() - return diff --git a/code/modules/lighting/lighting_mask/dynamic_lighting_source.dm b/code/modules/lighting/lighting_mask/dynamic_lighting_source.dm new file mode 100644 index 00000000000..c0bf02daae4 --- /dev/null +++ b/code/modules/lighting/lighting_mask/dynamic_lighting_source.dm @@ -0,0 +1,103 @@ +// This is where the fun begins. +// These are the main datums that emit light. + +/datum/dynamic_light_source + ///source atom that we belong to + var/atom/source_atom + ///The atom that the source atom is contained inside + var/atom/movable/contained_atom + ///our last loc + var/atom/cached_loc + //the turf where cached loc was + var/turf/source_turf + ///the turf the contained atom appears to be covering + var/turf/pixel_turf + /// Intensity of the emitter light. + var/light_power = 0 + /// The range of the emitted light. + var/light_range = 0 + /// The colour of the light, string, decomposed by PARSE_LIGHT_COLOR() + var/light_color = NONSENSICAL_VALUE + + /// Whether we have applied our light yet or not. + var/applied = FALSE + + ///typepath for the mask type we are using + var/mask_type + ///reference to the mask holder effect + var/obj/effect/lighting_mask_holder/mask_holder + ///reference to the mask contained within the mask_holder objects vis_contents + var/atom/movable/lighting_mask/our_mask + +/datum/dynamic_light_source/New(atom/movable/owner, mask_type = /atom/movable/lighting_mask) + source_atom = owner // Set our new owner. + LAZYADD(source_atom.hybrid_light_sources, src) + + //Find the atom that contains us + find_containing_atom() + + source_turf = get_turf(source_atom) + + src.mask_type = mask_type + mask_holder = new(source_turf) + our_mask = new mask_type + mask_holder.assign_mask(our_mask) + our_mask.attached_atom = owner + + //Set light vars + set_light(owner.light_range, owner.light_power, owner.light_color) + + //Calculate shadows + our_mask.queue_mask_update() + + //Set direction + our_mask.rotate_mask_on_holder_turn(contained_atom.dir) + RegisterSignal(our_mask, COMSIG_ATOM_DIR_CHANGE, TYPE_PROC_REF(/atom/movable/lighting_mask, rotate_mask_on_holder_turn)) + +/datum/dynamic_light_source/Destroy(force) + //Remove references to ourself. + LAZYREMOVE(source_atom?.hybrid_light_sources, src) + LAZYREMOVE(contained_atom?.hybrid_light_sources, src) + QDEL_NULL(mask_holder) + our_mask = null//deletion handled on holder + return ..() + +///Updates containing atom +/datum/dynamic_light_source/proc/find_containing_atom() + //Remove ourselves from the old containing atoms light sources + if(contained_atom && contained_atom != source_atom) + LAZYREMOVE(contained_atom.hybrid_light_sources, src) + //Find our new container + if(isturf(source_atom) || isarea(source_atom)) + contained_atom = source_atom + return + contained_atom = source_atom.loc + for(var/sanity in 1 to 20) + if(!contained_atom) + //Welcome to nullspace my friend. + contained_atom = source_atom + return + if(isturf(contained_atom.loc)) + break + contained_atom = contained_atom.loc + //Add ourselves to their light sources + if(contained_atom != source_atom) + LAZYADD(contained_atom.hybrid_light_sources, src) + +///Update light if changed. +/datum/dynamic_light_source/proc/set_light(l_range, l_power, l_color = NONSENSICAL_VALUE) + if(!our_mask) + return + if(l_range && l_range != light_range) + light_range = l_range + our_mask.set_radius(l_range) + if(l_power && l_power != light_power) + light_power = l_power + our_mask.set_intensity(l_power) + if(l_color != NONSENSICAL_VALUE && l_color != light_color) + light_color = l_color + our_mask.set_color(l_color) + +/datum/dynamic_light_source/proc/update_position() + mask_holder.forceMove(get_turf(source_atom)) + find_containing_atom() diff --git a/code/modules/lighting/lighting_mask/lighting_mask.dm b/code/modules/lighting/lighting_mask/lighting_mask.dm new file mode 100644 index 00000000000..e6d3da36da4 --- /dev/null +++ b/code/modules/lighting/lighting_mask/lighting_mask.dm @@ -0,0 +1,172 @@ +///Lighting mask sprite radius in tiles +#define LIGHTING_MASK_RADIUS 4 +///Lighting mask sprite diameter in pixels +#define LIGHTING_MASK_SPRITE_SIZE LIGHTING_MASK_RADIUS * 64 + +/atom/movable/lighting_mask + name = "" + icon = LIGHTING_ICON_BIG + icon_state = "light_normalized" + + anchored = TRUE + plane = LIGHTING_PLANE + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + layer = LIGHTING_SECONDARY_LAYER + invisibility = INVISIBILITY_LIGHTING + blend_mode = BLEND_ADD + appearance_flags = KEEP_TOGETHER|RESET_TRANSFORM + + ///The current angle the item is pointing at + var/current_angle = 0 + + ///The radius of illumination of the mask + var/radius = 0 + + ///The atom that we are attached to, does not need hard del protection as we are deleted with it + var/atom/attached_atom + + ///Reference to the holder /obj/effect + var/obj/effect/lighting_mask_holder/mask_holder + + ///Prevents us from registering for update twice before SSlighting init + var/awaiting_update = FALSE + ///Set to TRUE if you want the light to rotate with the owner + var/is_directional = FALSE + + ///Turfs that are being affected by this mask, this is for the sake of luminosity + var/list/turf/affecting_turfs + ///list of mutable appearance shadows + var/list/mutable_appearance/shadows + var/times_calculated = 0 + + //Please dont change these + var/calculated_position_x + var/calculated_position_y + +/atom/movable/lighting_mask/Initialize(mapload, ...) + . = ..() + add_filter("pixel_smoother", 3, gauss_blur_filter(2)) + add_filter("shadow_alpha_masking", 4, alpha_mask_filter(render_source = SHADOW_RENDER_TARGET, flags = MASK_INVERSE)) + +/atom/movable/lighting_mask/Destroy() + //Make sure we werent destroyed in init + SSlighting.mask_queue -= src + //Remove from affecting turfs + if(affecting_turfs) + for(var/turf/thing as anything in affecting_turfs) + var/area/A = thing.loc + LAZYREMOVE(thing.hybrid_lights_affecting, src) + if(!A.base_lighting_alpha) + thing.luminosity -= 1 + affecting_turfs = null + //Cut the shadows. Since they are overlays they will be deleted when cut from overlays. + LAZYCLEARLIST(shadows) + mask_holder = null + attached_atom = null + return ..() + +///Sets the radius of the mask, and updates everything that needs to be updated +/atom/movable/lighting_mask/proc/set_radius(new_radius, transform_time = 0) + //Update our matrix + var/matrix/new_size_matrix = get_matrix(new_radius) + apply_matrix(new_size_matrix, transform_time) + radius = new_radius + //then recalculate and redraw + queue_mask_update() + +///if you want the matrix to grow or shrink, you can do that using this proc when applyng it +/atom/movable/lighting_mask/proc/apply_matrix(matrix/to_apply, transform_time = 0) + if(transform_time) + animate(src, transform = to_apply, time = transform_time) + else + transform = to_apply + +///Creates a matrix for the lighting mak to use +/atom/movable/lighting_mask/proc/get_matrix(radius = 1) + var/matrix/new_size_matrix = new() + //Scale + // - Scale to the appropriate radius + new_size_matrix.Scale(radius / LIGHTING_MASK_RADIUS) + //Translate + // - Center the overlay image + // - Ok so apparently translate is affected by the scale we already did huh. + // ^ Future me here, its because it works as translate then scale since its backwards. + // ^ ^ Future future me here, it totally shouldnt since the translation component of a matrix is independent to the scale component. + new_size_matrix.Translate(-128 + 16) + //Adjust for pixel offsets + var/invert_offsets = attached_atom.dir & (NORTH | EAST) + var/left_or_right = attached_atom.dir & (EAST | WEST) + var/offset_x = (left_or_right ? attached_atom.light_pixel_y : attached_atom.light_pixel_x) * (invert_offsets ? -1 : 1) + var/offset_y = (left_or_right ? attached_atom.light_pixel_x : attached_atom.light_pixel_y) * (invert_offsets ? -1 : 1) + new_size_matrix.Translate(offset_x, offset_y) + if(is_directional) + //Rotate + // - Rotate (Directional lights) + new_size_matrix.Turn(current_angle) + return new_size_matrix + +///Rotates the light source to angle degrees. +/atom/movable/lighting_mask/proc/rotate(angle = 0) + //Converting our transform is pretty simple. + var/matrix/rotated_matrix = matrix() + rotated_matrix.Turn(angle - current_angle) + rotated_matrix *= transform + //Overlays cannot be edited while applied, meaning their transform cannot be changed. + //Disconnect the shadows from the overlay, apply the transform and then reapply them as an overlay. + //Oh also since the matrix is really weird standard rotation matrices wont work here. + overlays.Cut() + //Disconnect from parent matrix, become a global position + for(var/mutable_appearance/shadow as anything in shadows) //Mutable appearances are children of icon + shadow.transform *= transform + shadow.transform /= rotated_matrix + //Apply our matrix + transform = rotated_matrix + overlays += shadows + + //Now we are facing this direction + current_angle = angle + +///Setter proc for colors +/atom/movable/lighting_mask/proc/set_color(colour = "#ffffff") + color = colour + +///Setter proc for the intensity of the mask +/atom/movable/lighting_mask/proc/set_intensity(intensity = 1) + if(intensity >= 0) + alpha = ALPHA_TO_INTENSITY(intensity) + blend_mode = BLEND_ADD + else + alpha = ALPHA_TO_INTENSITY(-intensity) + blend_mode = BLEND_SUBTRACT + +///The holder atom turned, spins the mask if it's needed +/atom/movable/lighting_mask/proc/rotate_mask_on_holder_turn(new_direction) + SIGNAL_HANDLER + rotate(dir2angle(new_direction) - 180) + +///Flickering lighting mask +/atom/movable/lighting_mask/flicker + icon_state = "light_flicker" + +///Conical Light mask +/atom/movable/lighting_mask/conical + icon_state = "light_conical" + is_directional = TRUE + +///Rotating Light mask +/atom/movable/lighting_mask/rotating + icon_state = "light_rotating-1" + +/atom/movable/lighting_mask/rotating/Initialize(mapload, ...) + . = ..() + icon_state = "light_rotating-[rand(1, 3)]" + +///rotating light mask, but only pointing in one direction +/atom/movable/lighting_mask/rotating_conical + icon_state = "light_conical_rotating" + +/atom/movable/lighting_mask/ex_act(severity, target) + return + +#undef LIGHTING_MASK_SPRITE_SIZE +#undef LIGHTING_MASK_RADIUS diff --git a/code/modules/lighting/lighting_mask/lighting_mask_holder.dm b/code/modules/lighting/lighting_mask/lighting_mask_holder.dm new file mode 100644 index 00000000000..750a16fa1bf --- /dev/null +++ b/code/modules/lighting/lighting_mask/lighting_mask_holder.dm @@ -0,0 +1,22 @@ +///Holder for lighting mask, this is done for ensuing correct render as a viscontents +/obj/effect/lighting_mask_holder + name = "" + anchored = TRUE + appearance_flags = NONE //Removes TILE_BOUND meaning that the lighting mask will be visible even if the source turf is not. + glide_size = INFINITY //prevent shadow jitter + ///The movable mask this holder is holding in its vis contents + var/atom/movable/lighting_mask/held_mask + +/obj/effect/lighting_mask_holder/proc/assign_mask(atom/movable/lighting_mask/mask) + vis_contents += mask + held_mask = mask + mask.mask_holder = src + +/obj/effect/lighting_mask_holder/Destroy(force) + vis_contents -= held_mask + QDEL_NULL(held_mask) + return ..() + +/obj/effect/lighting_mask_holder/Moved(atom/OldLoc, Dir) + . = ..() + held_mask?.queue_mask_update()//held mask can be null when it is deleted diff --git a/code/modules/lighting/lighting_mask/shadow_calculator.dm b/code/modules/lighting/lighting_mask/shadow_calculator.dm new file mode 100644 index 00000000000..2571bf870d2 --- /dev/null +++ b/code/modules/lighting/lighting_mask/shadow_calculator.dm @@ -0,0 +1,662 @@ +//Lighting texture scales in world units (divide by 32) +//256 = 8,4,2 +//1024 = 32,16,8 +#define LIGHTING_SHADOW_TEX_SIZE 8 + +///Eyeball number for radius based offsets do not touch +#define RADIUS_BASED_OFFSET 3.5 + +///Inserts a coord list into a grouped list +#define COORD_LIST_ADD(listtoadd, x, y) \ + if(islist(listtoadd["[x]"])) { \ + var/list/_L = listtoadd["[x]"]; \ + BINARY_INSERT_NUM(y, _L); \ + } else { \ + listtoadd["[x]"] = list(y);\ + } + +#ifdef SHADOW_DEBUG +///Color coded atom debug, note will break when theres planetside lgihting +#define DEBUG_HIGHLIGHT(x, y, colour) \ + do { \ + var/turf/T = locate(x, y, 3); \ + if(T) { \ + T.color = colour; \ + }\ + } while (FALSE) + +//For debugging use when we want to know if a turf is being affected multiple times +//#define DEBUG_HIGHLIGHT(x, y, colour) do{var/turf/T=locate(x,y,2);if(T){switch(T.color){if("#ff0000"){T.color = "#00ff00"}if("#00ff00"){T.color="#0000ff"}else{T.color="#ff0000"}}}}while(0) +#define DO_SOMETHING_IF_DEBUGGING_SHADOWS(something) something +#else +#define DEBUG_HIGHLIGHT(x, y, colour) +#define DO_SOMETHING_IF_DEBUGGING_SHADOWS(something) +#endif + +/atom/movable/lighting_mask/proc/link_turf_to_light(turf/T) + LAZYOR(affecting_turfs, T) + LAZYOR(T.hybrid_lights_affecting, src) + +/atom/movable/lighting_mask/proc/unlink_turf_from_light(turf/T) + LAZYREMOVE(affecting_turfs, T) + LAZYREMOVE(T.hybrid_lights_affecting, src) + +///Enqueues the mask in the queue properly +/atom/movable/lighting_mask/proc/queue_mask_update() + SSlighting.mask_queue |= src + awaiting_update = TRUE + +/** + * Returns a list of matrices corresponding to the matrices that should be applied to triangles of + * coordinates (0,0),(1,0),(0,1) to create a triangcalculate_shadows_matricesle that respresents the shadows + * takes in the old turf to smoothly animate shadow movement + */ +/atom/movable/lighting_mask/proc/calculate_lighting_shadows() + //Check to make sure lighting is actually started + //If not count the amount of duplicate requests created. + if(!SSlighting.started) + if(awaiting_update) + SSlighting.duplicate_shadow_updates_in_init++ + return + queue_mask_update() + return + awaiting_update = FALSE + //we moved to nullspace meanwhile dont bother + if(!attached_atom.loc) + return + + //Incremement the global counter for shadow calculations + SSlighting.total_shadow_calculations ++ + + //Ceiling the range since we need it in integer form + var/range = ceil(radius) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/timer = TICK_USAGE) + + //Work out our position + //Calculate shadow origin offset + var/invert_offsets = attached_atom.dir & (NORTH | EAST) + var/left_or_right = attached_atom.dir & (EAST | WEST) + var/offset_x = (left_or_right ? attached_atom.light_pixel_y : attached_atom.light_pixel_x) * (invert_offsets ? -1 : 1) + var/offset_y = (left_or_right ? attached_atom.light_pixel_x : attached_atom.light_pixel_y) * (invert_offsets ? -1 : 1) + + //Get the origin points + var/turf/our_turf = get_turf(attached_atom) //The mask is in nullspace, so we need the source turf of the container + + //Account for pixel shifting and light offset + calculated_position_x = our_turf.x + ((offset_x) / world.icon_size) + calculated_position_y = our_turf.y + ((offset_y) / world.icon_size) + + //Remove the old shadows + overlays.Cut() + + + //Reset the list + if(islist(affecting_turfs)) + for(var/turf/T as anything in affecting_turfs) + LAZYREMOVE(T?.hybrid_lights_affecting, src) + //The turf is no longer affected by any lights, make it non-luminous. + var/area/A = T.loc + if(T?.luminosity && !A.base_lighting_alpha) + T.luminosity -= 1 + + //Clear the list + LAZYCLEARLIST(affecting_turfs) + LAZYCLEARLIST(shadows) + + //Optimise grouping by storing as + // Key : x (AS A STRING BECAUSE BYOND DOESNT ALLOW FOR INT KEY DICTIONARIES) + // Value: List(y values) + var/list/opaque_atoms_in_view = list() + + //Rebuild the list + var/is_on_closed_turf = our_turf.density + var/list/turfs = list() + DVIEW(turfs, range, get_turf(attached_atom), INVISIBILITY_LIGHTING) + for(var/turf/thing in turfs) //most expensive part of shadow code is this DVIEW and group_atoms + link_turf_to_light(thing) + //The turf is now affected by our light, make it luminous + thing.luminosity += 1 + //Dont consider shadows about our turf. + if(!is_on_closed_turf) + if(thing == our_turf) + continue + if(thing.directional_opacity) + //At this point we no longer care about + //the atom itself, only the position values + COORD_LIST_ADD(opaque_atoms_in_view, thing.x, thing.y) + DEBUG_HIGHLIGHT(thing.x, thing.y, "#0000FF") + + //We are too small to consider shadows on, luminsoty has been considered at least. + if(radius < 2) + return + + DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("[TICK_USAGE_TO_MS(timer)]ms to process view([range], src).")) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/temp_timer = TICK_USAGE) + + //Group atoms together for optimisation + var/list/grouped_atoms = group_atoms(opaque_atoms_in_view) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("[TICK_USAGE_TO_MS(temp_timer)]ms to process group_atoms")) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/total_coordgroup_time = 0) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/total_cornergroup_time = 0) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/triangle_time = 0) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/culling_time = 0) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/triangle_to_matrix_time = 0) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/matrix_division_time = 0) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/MA_new_time = 0) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/MA_vars_time = 0) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/overlays_add_time = 0) + + var/list/overlays_to_add = list() + for(var/group in grouped_atoms) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE) + + var/list/coordgroup = calculate_corners_in_group(group) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(total_coordgroup_time += TICK_USAGE_TO_MS(temp_timer)) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE) + + //This is where the lines are made + var/list/cornergroup = get_corners_from_coords(coordgroup) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(total_cornergroup_time += TICK_USAGE_TO_MS(temp_timer)) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE) + + var/list/culledlinegroup = cull_blocked_in_group(cornergroup, opaque_atoms_in_view) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(culling_time += TICK_USAGE_TO_MS(temp_timer)) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE) + + if(!LAZYLEN(culledlinegroup)) + continue + + var/list/triangles = calculate_triangle_vertices(culledlinegroup) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(triangle_time += TICK_USAGE_TO_MS(temp_timer)) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE) + + for(var/triangle in triangles) + var/matrix/triangle_matrix = triangle_to_matrix(triangle) + + DO_SOMETHING_IF_DEBUGGING_SHADOWS(triangle_to_matrix_time += TICK_USAGE_TO_MS(temp_timer)) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE) + + triangle_matrix /= transform + + DO_SOMETHING_IF_DEBUGGING_SHADOWS(matrix_division_time += TICK_USAGE_TO_MS(temp_timer)) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE) + + var/mutable_appearance/shadow = new() + + DO_SOMETHING_IF_DEBUGGING_SHADOWS(MA_new_time += TICK_USAGE_TO_MS(temp_timer)) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE) + + shadow.icon = LIGHTING_ICON_BIG + shadow.icon_state = "triangle" + shadow.color = "#000" + shadow.transform = triangle_matrix + shadow.render_target = SHADOW_RENDER_TARGET + shadow.blend_mode = BLEND_OVERLAY + + DO_SOMETHING_IF_DEBUGGING_SHADOWS(MA_vars_time += TICK_USAGE_TO_MS(temp_timer)) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE) + + LAZYADD(shadows, shadow) + overlays_to_add += shadow + + DO_SOMETHING_IF_DEBUGGING_SHADOWS(overlays_add_time += TICK_USAGE_TO_MS(temp_timer)) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(temp_timer = TICK_USAGE) + + DO_SOMETHING_IF_DEBUGGING_SHADOWS(var/overlay_apply_time = TICK_USAGE) + + overlays += overlays_to_add //batch appearance generation for free lag(tm) + + DO_SOMETHING_IF_DEBUGGING_SHADOWS(overlay_apply_time = TICK_USAGE_TO_MS(overlay_apply_time)) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("total_coordgroup_time: [total_coordgroup_time]ms")) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("total_cornergroup_time: [total_cornergroup_time]ms")) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("triangle_time calculation: [triangle_time]ms")) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("triangle_to_matrix_time: [triangle_to_matrix_time]ms")) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("Culling Time: [culling_time]ms")) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("matrix_division_time: [matrix_division_time]ms")) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("MA_new_time: [MA_new_time]ms")) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("MA_vars_time: [MA_vars_time]ms")) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("overlays_add_time: [overlays_add_time]ms")) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("overlay_apply_time: [overlay_apply_time]ms")) + DO_SOMETHING_IF_DEBUGGING_SHADOWS(log_game("[TICK_USAGE_TO_MS(timer)]ms to process total.")) + + +/** + * Converts a triangle into a matrix that can be applied to a standardized triangle + * to make it represent the points. + */ +/atom/movable/lighting_mask/proc/triangle_to_matrix(list/triangle) + //We need the world position raw, if we use the calculated position then the pixel values will cancel. + var/turf/our_turf = get_turf(attached_atom) + var/ourx = our_turf.x + var/oury = our_turf.y + + var/originx = triangle[1][1] - ourx //~Simultaneous Variable: U + var/originy = triangle[1][2] - oury //~Simultaneous Variable: V + //Get points translating the first point to (0, 0) + var/translatedPoint2x = triangle[2][1] - ourx //Simultaneous Variable: W + var/translatedPoint2y = triangle[2][2] - oury //Simultaneous Variable: X + var/translatedPoint3x = triangle[3][1] - ourx //Simultaneous Variable: Y + var/translatedPoint3y = triangle[3][2] - oury //Simultaneous Variable: Z + //message_admins("Point 1: ([originx], [originy])") + //message_admins("Point 2: ([translatedPoint2x], [translatedPoint2y])") + //message_admins("Point 3: ([translatedPoint3x], [translatedPoint3y])") + //Assumption that is incorrect + //Triangle points are + // (-4, -4) + // (-4, 4) + // ( 4, -4) + //Would be much easier if it was (0, 0) instead of (-4, -4) but since we have 6 inputs and 6 unknowns + //we can solve the values of the matrix pretty easilly simultaneously. + //In fact since variables U,W,Y,A,B,C are separate to V,X,Z,D,E,F its easy since its 2 identical tri-variable simultaneous equations. + //By solving the equations simultaneously we get these results: + //a = (y-u)/8 + var/a = (translatedPoint3x - originx) / LIGHTING_SHADOW_TEX_SIZE + //b = (w-u)/ 8 + var/b = (translatedPoint2x - originx) / LIGHTING_SHADOW_TEX_SIZE + //c = (y+w)/2 + var/c = (translatedPoint3x + translatedPoint2x) / 2 + //d = (z-v)/8 + var/d = (translatedPoint3y - originy) / LIGHTING_SHADOW_TEX_SIZE + //e = (x-v)/8 + var/e = (translatedPoint2y - originy) / LIGHTING_SHADOW_TEX_SIZE + //f = (z+x)/2 + var/f = (translatedPoint3y + translatedPoint2y) / 2 + //Matrix time g + //a,b,d and e can be used to define the shape, C and F can be used for translation god matrices are so beautiful + //Completely random offset that I didnt derive, I just trialled and errored for about 4 hours until it randomly worked + //var/radius_based_offset = radius * 3 + RADIUS_BASED_OFFSET <-- for 1024x1024 lights DO NOT USE 1024x1024 SHADOWS UNLESS YOU ARE PLAYING WITH RTX200000 OR SOMETHING + var/radius_based_offset = RADIUS_BASED_OFFSET + var/matrix/M = matrix(a, b, (c * 32) - ((radius_based_offset) * 32), d, e, (f * 32) - ((radius_based_offset) * 32)) + //log_game("[M.a], [M.d], 0") + //log_game("[M.b], [M.e], 0") + //log_game("[M.c], [M.f], 1") + return M + +/** + * Basically takes the 2-4 corners, extends them and then generates triangle coordinates representing shadows + * Input: list(list(list(x, y), list(x, y))) + * Layer 1: Lines + * Layer 2: Vertex + * Layer 3: X/Y value + * OUTPUT: The same thing but with 3 lists embedded rather than 2 because they are triangles not lines now. + */ +/atom/movable/lighting_mask/proc/calculate_triangle_vertices(list/cornergroup) + var/shadow_radius = max(radius + 1, 3) + //Get the origin poin's + var/ourx = calculated_position_x + var/oury = calculated_position_y + //The output + . = list() + //Every line has 2 triangles innit + for(var/list/line as anything in cornergroup) + //Get the corner vertices + var/vertex1 = line[1] + var/vertex2 = line[2] + //Extend them and get end vertices + //Calculate vertex 3 position + var/delta_x = vertex1[1] - ourx + var/delta_y = vertex1[2] - oury + var/vertex3 = extend_line_to_radius(delta_x, delta_y, shadow_radius, ourx, oury) + var/vertex3side = (vertex3[1] - ourx) == -shadow_radius ? WEST : (vertex3[1] - ourx) == shadow_radius ? EAST : (vertex3[2] - oury) == shadow_radius ? NORTH : SOUTH + + //For vertex 4 + delta_x = vertex2[1] - ourx + delta_y = vertex2[2] - oury + var/vertex4 = extend_line_to_radius(delta_x, delta_y, shadow_radius, ourx, oury) + var/vertex4side = (vertex4[1] - ourx) == -shadow_radius ? WEST : (vertex4[1] - ourx) == shadow_radius ? EAST : (vertex4[2] - oury) == shadow_radius ? NORTH : SOUTH + + //If vertex3 is not on the same border as vertex 4 then we need more triangles to fill in the space. + if(vertex3side != vertex4side) + var/eitherNorth = (vertex3side == NORTH || vertex4side == NORTH) + var/eitherEast = (vertex3side == EAST || vertex4side == EAST) + var/eitherSouth = (vertex3side == SOUTH || vertex4side == SOUTH) + var/eitherWest = (vertex3side == WEST || vertex4side == WEST) + if(eitherNorth && eitherEast) + //Add a vertex top right + var/vertex5 = list(shadow_radius + ourx, shadow_radius + oury) + var/triangle3 = list(vertex3, vertex4, vertex5) + . += list(triangle3) + else if(eitherNorth && eitherWest) + //Add a vertex top left + var/vertex5 = list(-shadow_radius + ourx, shadow_radius + oury) + var/triangle3 = list(vertex3, vertex4, vertex5) + . += list(triangle3) + else if(eitherNorth && eitherSouth) //BLOCKER IS A | SHAPE + //If vertex3 is to the right of the center, both vertices are to the right. + if(vertex3[1] > ourx) + //New vertexes are on the right + var/vertex5 = list(ourx + shadow_radius, oury + shadow_radius) + var/vertex6 = list(ourx + shadow_radius, oury - shadow_radius) + //If vertex 4 is greater than 3 then triangles link as 4,5,6 and 3,4,6 + if(vertex4[2] > vertex3[2]) + var/triangle3 = list(vertex3, vertex5, vertex6) + . += list(triangle3) + var/triangle4 = list(vertex3, vertex4, vertex5) + . += list(triangle4) + else + //Vertex 3 is greater than 4, so triangles link as 3,5,6 and 3,4,6 + var/triangle3 = list(vertex3, vertex4, vertex5) + . += list(triangle3) + var/triangle4 = list(vertex4, vertex5, vertex6) + . += list(triangle4) + else + //New vertexes are on the left + var/vertex5 = list(ourx - shadow_radius, oury + shadow_radius) + var/vertex6 = list(ourx - shadow_radius, oury - shadow_radius) + //If vertex 4 is higher than 3 then triangles link as 4,5,6 and 3,4,6 + if(vertex4[2] > vertex3[2]) + var/triangle3 = list(vertex3, vertex5, vertex6) + . += list(triangle3) + var/triangle4 = list(vertex3, vertex4, vertex5) + . += list(triangle4) + else + //Vertex 3 is greater than 4, so triangles link as 3,5,6 and 3,4,6 + var/triangle3 = list(vertex3, vertex4, vertex5) + . += list(triangle3) + var/triangle4 = list(vertex4, vertex5, vertex6) + . += list(triangle4) + else if(eitherEast && eitherSouth) + //Add a vertex bottom right + var/vertex5 = list(shadow_radius + ourx, -shadow_radius + oury) + var/triangle3 = list(vertex3, vertex4, vertex5) + . += list(triangle3) + else if(eitherEast && eitherWest) //BLOCKER IS A --- SHAPE + //If vertex3 is above the center, then pointers are along the top + if(vertex3[2] > oury) + //New vertexes are on the right + var/vertex5 = list(ourx + shadow_radius, oury + shadow_radius) + var/vertex6 = list(ourx - shadow_radius, oury + shadow_radius) + //If vertex 4 is greater than 3 then triangles link as 4,5,6 and 3,4,6 + if(vertex4[1] > vertex3[1]) + var/triangle3 = list(vertex3, vertex5, vertex6) + . += list(triangle3) + var/triangle4 = list(vertex3, vertex4, vertex5) + . += list(triangle4) + else + //Vertex 3 is greater than 4, so triangles link as 3,5,6 and 3,4,6 + var/triangle3 = list(vertex3, vertex4, vertex5) + . += list(triangle3) + var/triangle4 = list(vertex4, vertex5, vertex6) + . += list(triangle4) + else + //New vertexes are on the bottom + var/vertex5 = list(ourx + shadow_radius, oury - shadow_radius) + var/vertex6 = list(ourx - shadow_radius, oury - shadow_radius) + //If vertex 4 is higher than 3 then triangles link as 4,5,6 and 3,4,6 + if(vertex4[1] > vertex3[1]) + var/triangle3 = list(vertex3, vertex4, vertex5) + . += list(triangle3) + var/triangle4 = list(vertex3, vertex5, vertex6) + . += list(triangle4) + else + //Vertex 3 is greater than 4, so triangles link as 3,5,6 and 3,4,6 + var/triangle3 = list(vertex3, vertex4, vertex5) + . += list(triangle3) + var/triangle4 = list(vertex4, vertex5, vertex6) + . += list(triangle4) + else if(eitherSouth && eitherWest) + //Bottom left + var/vertex5 = list(-shadow_radius + ourx, -shadow_radius + oury) + var/triangle3 = list(vertex3, vertex4, vertex5) + . += list(triangle3) + else + //bug + stack_trace("Major error: vertex in a bad position (North: [eitherNorth], East: [eitherEast], South: [eitherSouth], West: [eitherWest])") + + //Generate triangles + var/triangle1 = list(vertex1, vertex2, vertex3) + var/triangle2 = list(vertex2, vertex3, vertex4) + . += list(triangle1) + . += list(triangle2) + +///Takes in the list of lines and sight blockers and returns only the lines that are not blocked +/atom/movable/lighting_mask/proc/cull_blocked_in_group(list/lines, list/sight_blockers) + . = list() + for(var/list/line in lines) + var/vertex1 = line[1] + var/vertex2 = line[2] + var/list/lines_to_add = list() + if(vertex1[1] == vertex2[1]) + //Vertical line. + //Requires a block to the left and right all the way from the bottom to the top + var/left = vertex1[1] - 0.5 + var/right = vertex1[1] + 0.5 + var/bottom = min(vertex1[2], vertex2[2]) + 0.5 + var/top = max(vertex1[2], vertex2[2]) - 0.5 + var/list/current_bottom_vertex = list(vertex1[1], bottom - 0.5) + var/list/current_top_vertex = list(vertex1[1], bottom - 0.5) + for(var/i in bottom to top) + var/list/left_list = sight_blockers["[left]"] + var/isLeftBlocked = left_list?.Find(i) ? TRUE : FALSE + var/list/right_list = sight_blockers["[right]"] + var/isRightBlocked = right_list?.Find(i) ? TRUE : FALSE + if(isLeftBlocked == isRightBlocked) + if(current_bottom_vertex[2] != current_top_vertex[2]) + lines_to_add += list(list(current_bottom_vertex, current_top_vertex)) + current_bottom_vertex = list(vertex1[1], i + 0.5) + current_top_vertex = list(vertex1[1], i + 0.5) + if(current_bottom_vertex[2] != current_top_vertex[2]) + lines_to_add += list(list(current_bottom_vertex, current_top_vertex)) + else + //Horizontal line + //Requires a block above and below for every position from left to right + var/left = min(vertex1[1], vertex2[1]) + 0.5 + var/right = max(vertex1[1], vertex2[1]) - 0.5 + var/top = vertex1[2] + 0.5 + var/bottom = vertex1[2] - 0.5 + var/list/current_left_vertex = list(left - 0.5, vertex1[2]) + var/list/current_right_vertex = list(left - 0.5, vertex1[2]) + for(var/i in left to right) + var/list/check_list = sight_blockers["[i]"] + var/isAboveBlocked = check_list?.Find(top) ? TRUE : FALSE + var/isBelowBlocked = check_list?.Find(bottom) ? TRUE : FALSE + if(isAboveBlocked == isBelowBlocked) + if(current_left_vertex[1] != current_right_vertex[1]) + lines_to_add += list(list(current_left_vertex, current_right_vertex)) + current_left_vertex = list(i + 0.5, vertex1[2]) + current_right_vertex = list(i + 0.5, vertex1[2]) + if(current_left_vertex[1] != current_right_vertex[1]) + lines_to_add += list(list(current_left_vertex, current_right_vertex)) + . += lines_to_add + +/** + * Converts the corners into the 3 (or 2) valid points + * For example if a wall is top right of the source, the bottom left wall corner + * can be removed otherwise the wall itself will be in the shadow. + * Input: list(list(x1, y1), list(x2, y2)) + * Output: list(list(list(x, y), list(x, y))) <-- 2 coordinates that form a line + */ +/atom/movable/lighting_mask/proc/get_corners_from_coords(list/coordgroup) + //Get the raw numbers + var/xlow = coordgroup[1][1] + var/ylow = coordgroup[1][2] + var/xhigh = coordgroup[2][1] + var/yhigh = coordgroup[2][2] + + var/ourx = calculated_position_x + var/oury = calculated_position_y + + //The source is above the point (Bottom Quad) + if(oury > yhigh) + //Bottom Right + if(ourx < xlow) + return list( + list(list(xlow, ylow), list(xhigh, ylow)), + list(list(xhigh, ylow), list(xhigh, yhigh)), + ) + //Bottom Left + else if(ourx > xhigh) + return list( + list(list(xlow, yhigh), list(xlow, ylow)), + list(list(xlow, ylow), list(xhigh, ylow)), + ) + //Bottom Middle + else + return list( + list(list(xlow, yhigh), list(xlow, ylow)), + list(list(xlow, ylow), list(xhigh, ylow)), + list(list(xhigh, ylow), list(xhigh, yhigh)) + ) + //The source is below the point (Top quad) + else if(oury < ylow) + //Top Right + if(ourx < xlow) + return list( + list(list(xlow, yhigh), list(xhigh, yhigh)), + list(list(xhigh, yhigh), list(xhigh, ylow)), + ) + //Top Left + else if(ourx > xhigh) + return list( + list(list(xlow, ylow), list(xlow, yhigh)), + list(list(xlow, yhigh), list(xhigh, yhigh)), + ) + //Top Middle + else + return list( + list(list(xlow, ylow), list(xlow, yhigh)), + list(list(xlow, yhigh), list(xhigh, yhigh)), + list(list(xhigh, yhigh), list(xhigh, ylow)) + ) + //the source is between the group Middle something + else + //Middle Right + if(ourx < xlow) + return list( + list(list(xlow, yhigh), list(xhigh, yhigh)), + list(list(xhigh, yhigh), list(xhigh, ylow)), + list(list(xhigh, ylow), list(xlow, ylow)) + ) + //Middle Left + else if(ourx > xhigh) + return list( + list(list(xhigh, ylow), list(xlow, ylow)), + list(list(xlow, ylow), list(xlow, yhigh)), + list(list(xlow, yhigh), list(xhigh, yhigh)) + ) + //Middle Middle (Why?????????) + else + return list( + list(list(xhigh, ylow), list(xlow, ylow)), + list(list(xlow, ylow), list(xlow, yhigh)), + list(list(xlow, yhigh), list(xhigh, yhigh)), + list(list(xlow, yhigh), list(xhigh, ylow)) + ) + +//Calculates the coordinates of the corner +//Takes a list of blocks and calculates the bottom left corner and the top right corner. +//Input: Group list(list(list(x,y), list(x,y)), list(list(x, y))) +//Output: Coordinates list(list(left, bottom), list(right, top)) +/atom/movable/lighting_mask/proc/calculate_corners_in_group(list/group) + if(length(group) == 0) + CRASH("Calculate_corners_in_group called on a group of length 0. Critical error.") + if(length(group) == 1) + var/x = group[1][1] + var/y = group[1][2] + return list( + list(x - 0.5, y - 0.5), + list(x + 0.5, y + 0.5) + ) + //Group is multiple length, find top left and bottom right + var/first = group[1] + var/second = group[2] + var/group_direction = NORTH + if(first[1] != second[1]) + group_direction = EAST +#ifdef SHADOW_DEBUG6 + else if(first[2] != second[2]) + message_admins("Major error, group is not 1xN or Nx1") +#endif + var/lowest = INFINITY + var/highest = 0 + for(var/vector in group) + var/value_to_comp = vector[1] + if(group_direction == NORTH) + value_to_comp = vector[2] + lowest = min(lowest, value_to_comp) + highest = max(highest, value_to_comp) + //done ez + if(group_direction == NORTH) + return list( + list(first[1] - 0.5, lowest - 0.5), + list(first[1] + 0.5, highest + 0.5) + ) + else + return list( + list(lowest - 0.5, first[2] - 0.5), + list(highest + 0.5, first[2] + 0.5) + ) + +///Groups things into vertical and horizontal lines. +///Input: All atoms ungrouped list(atom1, atom2, atom3) +///Output: List(List(Group), list(group2), ... , list(groupN)) +///Output: List(List(atom1, atom2), list(atom3, atom4...), ... , list(atom)) +/atom/movable/lighting_mask/proc/group_atoms(list/ungrouped_things) + . = list() + //Ungrouped things comes in as + // Key: X + // Value = list(y values) + //This makes sorting vertically easy, however sorting horizontally is harder + //While grouping elements vertically, we can put them into a new list with + // Key: Y + // Value = list(x values) + //to make it much easier. + var/list/horizontal_atoms = list() + //================================================= + //Vertical sorting (X locked) + for(var/x_key in ungrouped_things) + var/list/y_components = ungrouped_things[x_key] + var/pointer = y_components[1] + var/list/group = list(list(text2num(x_key), y_components[1])) + for(var/i in 2 to length(y_components)) + var/next = y_components[i] + if(next != pointer + 1) + if(length(group) == 1) + //Add the element in group to horizontal + COORD_LIST_ADD(horizontal_atoms, pointer, text2num(x_key)) + DEBUG_HIGHLIGHT(text2num(x_key), pointer, "#FFFF00") + else + //Add the group to the output + . += list(group) + group = list() + group += list(list(text2num(x_key), next)) + DEBUG_HIGHLIGHT(text2num(x_key), next, "#FF0000") + pointer = next + if(length(group) == 1) + //Add the element in group to horizontal + COORD_LIST_ADD(horizontal_atoms, pointer, text2num(x_key)) + DEBUG_HIGHLIGHT(text2num(x_key), pointer, "#FFFF00") + else + //Add the group to the output + . += list(group) + //================================================= + //Horizontal sorting (Y locked) + for(var/y_key in horizontal_atoms) + var/list/x_components = horizontal_atoms[y_key] + var/pointer = x_components[1] + var/list/group = list(list(x_components[1], text2num(y_key))) + for(var/i in 2 to length(x_components)) + var/next = x_components[i] + if(next != pointer + 1) + . += list(group) + group = list() + group += list(list(next, text2num(y_key))) + DEBUG_HIGHLIGHT(next, text2num(y_key), "#00FF00") + pointer = next + . += list(group) + +///gets a line from a x and y, to the offset x and y of length radius +/proc/extend_line_to_radius(delta_x, delta_y, radius, offset_x, offset_y) + if(abs(delta_x) < abs(delta_y)) + //top or bottom + var/proportion = radius / abs(delta_y) + return list(delta_x * proportion + offset_x, delta_y * proportion + offset_y) + else + var/proportion = radius / abs(delta_x) + return list(delta_x * proportion + offset_x, delta_y * proportion + offset_y) + +#undef LIGHTING_SHADOW_TEX_SIZE +#undef COORD_LIST_ADD +#undef DEBUG_HIGHLIGHT +#undef DO_SOMETHING_IF_DEBUGGING_SHADOWS diff --git a/code/modules/lighting/lighting_overlay.dm b/code/modules/lighting/lighting_overlay.dm deleted file mode 100644 index 05655ff0837..00000000000 --- a/code/modules/lighting/lighting_overlay.dm +++ /dev/null @@ -1,161 +0,0 @@ -/atom/movable/lighting_overlay - name = "" - anchored = TRUE - icon = LIGHTING_ICON - icon_state = LIGHTING_BASE_ICON_STATE - color = LIGHTING_BASE_MATRIX - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - layer = LIGHTING_LAYER - plane = LIGHTING_PLANE - invisibility = INVISIBILITY_LIGHTING - simulated = 0 - blend_mode = BLEND_OVERLAY - appearance_flags = NO_CLIENT_COLOR - - var/needs_update = FALSE - - #if WORLD_ICON_SIZE != 32 - transform = matrix(WORLD_ICON_SIZE / 32, 0, (WORLD_ICON_SIZE - 32) / 2, 0, WORLD_ICON_SIZE / 32, (WORLD_ICON_SIZE - 32) / 2) - #endif - -/atom/movable/lighting_overlay/Initialize(mapload, ...) - . = ..() - SSlighting.total_lighting_overlays++ - - var/turf/T = loc // If this runtimes atleast we'll know what's creating overlays in things that aren't turfs. - T.lighting_overlay = src - T.luminosity = 0 - - needs_update = TRUE - SSlighting.overlay_queue += src - -/atom/movable/lighting_overlay/Destroy(force = FALSE) - if (!force) - return QDEL_HINT_LETMELIVE // STOP DELETING ME - - //L_PROF(loc, "overlay_destroy") - SSlighting.total_lighting_overlays-- - - var/turf/T = loc - if (istype(T)) - T.lighting_overlay = null - T.luminosity = 1 - - SSlighting.overlay_queue -= src - - return ..() - -// This is a macro PURELY so that the if below is actually readable. -#define ALL_EQUAL ((rr == gr && gr == br && br == ar) && (rg == gg && gg == bg && bg == ag) && (rb == gb && gb == bb && bb == ab)) - -/atom/movable/lighting_overlay/proc/update_overlay() - var/turf/T = loc - if (!isturf(T)) // Erm... - if (loc) - warning("A lighting overlay realised its loc was NOT a turf (actual loc: [loc], [loc.type]) in update_overlay() and got deleted!") - - else - warning("A lighting overlay realised it was in nullspace in update_overlay() and got deleted!") - - qdel(src, TRUE) - return - - // See LIGHTING_CORNER_DIAGONAL in lighting_corner.dm for why these values are what they are. - var/list/corners = T.corners - - //Local cache, because otherwise it accesses the global variable repeatedly, which is slower - var/dummy_lighting_corner_cache = dummy_lighting_corner - - var/datum/lighting_corner/cr = dummy_lighting_corner_cache - var/datum/lighting_corner/cg = dummy_lighting_corner_cache - var/datum/lighting_corner/cb = dummy_lighting_corner_cache - var/datum/lighting_corner/ca = dummy_lighting_corner_cache - if (corners) - cr = corners[3] || dummy_lighting_corner_cache - cg = corners[2] || dummy_lighting_corner_cache - cb = corners[4] || dummy_lighting_corner_cache - ca = corners[1] || dummy_lighting_corner_cache - - luminosity = max(cr.cache_mx, cg.cache_mx, cb.cache_mx, ca.cache_mx) > LIGHTING_SOFT_THRESHOLD - - var/rr = cr.cache_r - var/rg = cr.cache_g - var/rb = cr.cache_b - - var/gr = cg.cache_r - var/gg = cg.cache_g - var/gb = cg.cache_b - - var/br = cb.cache_r - var/bg = cb.cache_g - var/bb = cb.cache_b - - var/ar = ca.cache_r - var/ag = ca.cache_g - var/ab = ca.cache_b - - if ((rr & gr & br & ar) && (rg + gg + bg + ag + rb + gb + bb + ab == 8)) - icon_state = LIGHTING_TRANSPARENT_ICON_STATE - color = null - else if (!luminosity) - icon_state = LIGHTING_DARKNESS_ICON_STATE - color = null - else if (rr == LIGHTING_DEFAULT_TUBE_R && rg == LIGHTING_DEFAULT_TUBE_G && rb == LIGHTING_DEFAULT_TUBE_B && ALL_EQUAL) - icon_state = LIGHTING_STATION_ICON_STATE - color = null - else - icon_state = LIGHTING_BASE_ICON_STATE - if (islist(color)) - var/list/c_list = color - c_list[CL_MATRIX_RR] = rr - c_list[CL_MATRIX_RG] = rg - c_list[CL_MATRIX_RB] = rb - c_list[CL_MATRIX_GR] = gr - c_list[CL_MATRIX_GG] = gg - c_list[CL_MATRIX_GB] = gb - c_list[CL_MATRIX_BR] = br - c_list[CL_MATRIX_BG] = bg - c_list[CL_MATRIX_BB] = bb - c_list[CL_MATRIX_AR] = ar - c_list[CL_MATRIX_AG] = ag - c_list[CL_MATRIX_AB] = ab - color = c_list - else - color = list( - rr, rg, rb, 0, - gr, gg, gb, 0, - br, bg, bb, 0, - ar, ag, ab, 0, - 0, 0, 0, 1 - ) - -#undef ALL_EQUAL - -// Variety of overrides so the overlays don't get affected by weird things. - -/atom/movable/lighting_overlay/ex_act(severity) - return 0 - -/atom/movable/lighting_overlay/singularity_act() - return - -/atom/movable/lighting_overlay/singularity_pull() - return - -/atom/movable/lighting_overlay/singuloCanEat() - return FALSE - -/atom/movable/lighting_overlay/can_fall() - return FALSE - -// Override here to prevent things accidentally moving around overlays. -/atom/movable/lighting_overlay/forceMove(atom/destination, no_tp = FALSE, harderforce = FALSE) - if(harderforce) - //L_PROF(loc, "overlay_forcemove") - . = ..() - -/atom/movable/lighting_overlay/shuttle_move(turf/loc) - return - -/atom/movable/lighting_overlay/conveyor_act() - return diff --git a/code/modules/lighting/lighting_profiler.dm b/code/modules/lighting/lighting_profiler.dm deleted file mode 100644 index ec6ae781125..00000000000 --- a/code/modules/lighting/lighting_profiler.dm +++ /dev/null @@ -1,41 +0,0 @@ -// Writes lighting updates to the database. -// FOR DEBUGGING ONLY! - -/proc/lprof_write(var/atom/movable/obj, var/type = "UNKNOWN") - if (!GLOB.lighting_profiling || !obj || !establish_db_connection(GLOB.dbcon)) - return - - var/x = null - var/y = null - var/z = null - - var/name = null - var/locname = null - if (istype(obj)) - name = obj.name - locname = obj.loc.name - x = obj.loc.x - y = obj.loc.y - z = obj.loc.z - - var/static/DBQuery/lprof_q - if (!lprof_q) - lprof_q = GLOB.dbcon.NewQuery({"INSERT INTO ss13dbg_lighting (time,tick_usage,type,name,loc_name,x,y,z) - VALUES (:time:,:tick_usage:,:type:,:name:,:loc_name:,:x:,:y:,:z:);"}) - - lprof_q.Execute( - list( - "time" = world.time, - "tick_usage" = world.tick_usage, - "type" = type, - "name" = name, - "loc_name" = locname, - "x" = x, - "y" = y, - "z" = z)) - - var/err = lprof_q.ErrorMsg() - if (err) - LOG_DEBUG("lprof_write: SQL Error: [err]") - message_admins(SPAN_DANGER("SQL Error during lighting profiling; disabling!")) - GLOB.lighting_profiling = FALSE diff --git a/code/modules/lighting/lighting_setup.dm b/code/modules/lighting/lighting_setup.dm deleted file mode 100644 index 68311a32b2f..00000000000 --- a/code/modules/lighting/lighting_setup.dm +++ /dev/null @@ -1,10 +0,0 @@ -/proc/create_all_lighting_overlays() - for(var/zlevel = 1 to world.maxz) - create_lighting_overlays_zlevel(zlevel) - -/proc/create_lighting_overlays_zlevel(var/zlevel) - ASSERT(zlevel) - - for(var/turf/T in block(locate(1, 1, zlevel), locate(world.maxx, world.maxy, zlevel))) - if(T.dynamic_lighting) - T.lighting_build_overlay() diff --git a/code/modules/lighting/lighting_source.dm b/code/modules/lighting/lighting_source.dm deleted file mode 100644 index 7bf7c40f7ed..00000000000 --- a/code/modules/lighting/lighting_source.dm +++ /dev/null @@ -1,468 +0,0 @@ -// This is where the fun begins. -// These are the main datums that emit light. - -/datum/light_source - var/atom/top_atom // The atom we're emitting light from (for example a mob if we're from a flashlight that's being held). - var/atom/source_atom // The atom that we belong to. - - var/turf/source_turf // The turf under the above. - var/light_power // Intensity of the emitter light. - var/light_range // The range of the emitted light. - var/light_color // The colour of the light, string, decomposed by parse_light_color() - var/light_uv // The intensity of UV light, between 0 and 255. - var/light_angle // The light's emission angle, in degrees. - - // Variables for keeping track of the colour. - var/lum_r - var/lum_g - var/lum_b - var/lum_u - - // The lumcount values used to apply the light. - var/tmp/applied_lum_r - var/tmp/applied_lum_g - var/tmp/applied_lum_b - var/tmp/applied_lum_u - - // Variables used to keep track of the atom's angle. - var/tmp/limit_a_x // The first test point's X coord for the cone. - var/tmp/limit_a_y // The first test point's Y coord for the cone. - var/tmp/limit_a_t // The first test point's angle. - var/tmp/limit_b_x // The second test point's X coord for the cone. - var/tmp/limit_b_y // The second test point's Y coord for the cone. - var/tmp/limit_b_t // The second test point's angle. - var/tmp/cached_origin_x // The last known X coord of the origin. - var/tmp/cached_origin_y // The last known Y coord of the origin. - var/tmp/old_direction // The last known direction of the origin. - var/tmp/test_x_offset // How much the X coord should be offset due to direction. - var/tmp/test_y_offset // How much the Y coord should be offset due to direction. - var/tmp/facing_opaque = FALSE - - var/list/datum/lighting_corner/effect_str // List used to store how much we're affecting corners. - var/list/turf/affecting_turfs - - var/applied = FALSE // Whether we have applied our light yet or not. - - var/needs_update = LIGHTING_NO_UPDATE - - var/skip_falloff = FALSE // ONLY for use with sunlight, behavior is undefined if TRUE on regular sources. - -/datum/light_source/New(atom/owner, atom/top) - SSlighting.total_lighting_sources++ - source_atom = owner // Set our new owner. - - LAZYADD(source_atom.light_sources, src) - - top_atom = top - if (top_atom != source_atom) - LAZYADD(top_atom.light_sources, src) - - source_turf = top_atom - light_power = source_atom.light_power - light_range = source_atom.light_range - light_color = source_atom.light_color - light_uv = source_atom.uv_intensity - light_angle = source_atom.light_wedge - - parse_light_color() - - update() - - //L_PROF(source_atom, "source_new([type])") - -// Kill ourselves. -/datum/light_source/Destroy(force) - //L_PROF(source_atom, "source_destroy") - SSlighting.total_lighting_sources-- - - remove_lum() - if (source_atom) - LAZYREMOVE(source_atom.light_sources, src) - - if (top_atom) - LAZYREMOVE(top_atom.light_sources, src) - - . = ..() - if (!force) - return QDEL_HINT_IWILLGC - -#ifdef USE_INTELLIGENT_LIGHTING_UPDATES -// Picks either scheduled or instant updates based on current server load. -#define INTELLIGENT_UPDATE(level) \ - var/_should_update = needs_update == LIGHTING_NO_UPDATE; \ - if (needs_update < level) { \ - needs_update = level; \ - } \ - if (_should_update) { \ - if (world.tick_usage > Master.current_ticklimit || SSlighting.force_queued) { \ - SSlighting.light_queue += src; \ - } \ - else { \ - SSlighting.total_instant_updates += 1; \ - update_corners(TRUE); \ - needs_update = LIGHTING_NO_UPDATE; \ - } \ - } -#else -#define INTELLIGENT_UPDATE(level) \ - if (needs_update == LIGHTING_NO_UPDATE) \ - SSlighting.light_queue += src; \ - if (needs_update < level) \ - needs_update = level; -#endif - -// This proc will cause the light source to update the top atom, and add itself to the update queue. -/datum/light_source/proc/update(atom/new_top_atom) - // This top atom is different. - if (new_top_atom && new_top_atom != top_atom) - if(top_atom != source_atom) // Remove ourselves from the light sources of that top atom. - LAZYREMOVE(top_atom.light_sources, src) - - top_atom = new_top_atom - - if (top_atom != source_atom) - LAZYADD(top_atom.light_sources, src) // Add ourselves to the light sources of our new top atom. - - //L_PROF(source_atom, "source_update") - - INTELLIGENT_UPDATE(LIGHTING_CHECK_UPDATE) - -// Will force an update without checking if it's actually needed. -/datum/light_source/proc/force_update() - //L_PROF(source_atom, "source_forceupdate") - - INTELLIGENT_UPDATE(LIGHTING_FORCE_UPDATE) - -// Will cause the light source to recalculate turfs that were removed or added to visibility only. -/datum/light_source/proc/vis_update() - //L_PROF(source_atom, "source_visupdate") - - INTELLIGENT_UPDATE(LIGHTING_VIS_UPDATE) - -// Decompile the hexadecimal colour into lumcounts of each perspective. -/datum/light_source/proc/parse_light_color() - if (light_color) - lum_r = GetRedPart (light_color) / 255 - lum_g = GetGreenPart (light_color) / 255 - lum_b = GetBluePart (light_color) / 255 - else - lum_r = 1 - lum_g = 1 - lum_b = 1 - - if (light_uv) - lum_u = light_uv / 255 - else - lum_u = 0 - -#define POLAR_TO_CART_X(R,T) ((R) * cos(T)) -#define POLAR_TO_CART_Y(R,T) ((R) * sin(T)) -#define PSEUDO_WEDGE(A_X,A_Y,B_X,B_Y) ((A_X)*(B_Y) - (A_Y)*(B_X)) -#define MINMAX(NUM) ((NUM) < 0 ? -round(-(NUM)) : round(NUM)) -#define ARBITRARY_NUMBER 10 - -/datum/light_source/proc/regenerate_angle(ndir) - old_direction = ndir - - var/turf/front = get_step(source_turf, old_direction) - facing_opaque = (front && front.has_opaque_atom) - - cached_origin_x = test_x_offset = source_turf.x - cached_origin_y = test_y_offset = source_turf.y - - if (facing_opaque) - return - - var/angle = light_angle * 0.5 - switch (old_direction) - if (NORTH) - limit_a_t = angle + 90 - limit_b_t = -(angle) + 90 - ++test_y_offset - - if (SOUTH) - limit_a_t = (angle) - 90 - limit_b_t = -(angle) - 90 - --test_y_offset - - if (EAST) - limit_a_t = angle - limit_b_t = -(angle) - ++test_x_offset - - if (WEST) - limit_a_t = angle + 180 - limit_b_t = -(angle) - 180 - --test_x_offset - - // Convert our angle + range into a vector. - limit_a_x = POLAR_TO_CART_X(light_range + ARBITRARY_NUMBER, limit_a_t) - limit_a_x = MINMAX(limit_a_x) - limit_a_y = POLAR_TO_CART_Y(light_range + ARBITRARY_NUMBER, limit_a_t) - limit_a_y = MINMAX(limit_a_y) - limit_b_x = POLAR_TO_CART_X(light_range + ARBITRARY_NUMBER, limit_b_t) - limit_b_x = MINMAX(limit_b_x) - limit_b_y = POLAR_TO_CART_Y(light_range + ARBITRARY_NUMBER, limit_b_t) - limit_b_y = MINMAX(limit_b_y) - -#undef ARBITRARY_NUMBER -#undef POLAR_TO_CART_X -#undef POLAR_TO_CART_Y -#undef MINMAX - -/datum/light_source/proc/remove_lum(now = FALSE) - applied = FALSE - - var/thing - for (thing in affecting_turfs) - var/turf/T = thing - LAZYREMOVE(T.affecting_lights, src) - - affecting_turfs = null - - for (thing in effect_str) - var/datum/lighting_corner/C = thing - REMOVE_CORNER(C,now) - - LAZYREMOVE(C.affecting, src) - - effect_str = null - -/datum/light_source/proc/recalc_corner(datum/lighting_corner/C, now = FALSE) - LAZYINITLIST(effect_str) - if (effect_str[C]) // Already have one. - REMOVE_CORNER(C,now) - effect_str[C] = 0 - - var/actual_range = light_range - - var/Sx = source_turf.x - var/Sy = source_turf.y - var/Sz = source_turf.z - - if (skip_falloff) - APPLY_CORNER_SIMPLE(C) - else - var/height = C.z == Sz ? LIGHTING_HEIGHT : CALCULATE_CORNER_HEIGHT(C.z, Sz) - APPLY_CORNER(C, now, Sx, Sy, height) - - UNSETEMPTY(effect_str) - -// If you update this, update the equivalent proc in lighting_source_novis.dm. -/datum/light_source/proc/update_corners(now = FALSE) - var/update = FALSE - - if (QDELETED(source_atom)) - qdel(src) - return - - if (source_atom.light_power != light_power) - light_power = source_atom.light_power - update = TRUE - - if (source_atom.light_range != light_range) - light_range = source_atom.light_range - update = TRUE - - if (!top_atom) - top_atom = source_atom - update = TRUE - - if (top_atom.loc != source_turf) - source_turf = top_atom.loc - update = TRUE - - if (!light_range || !light_power) - qdel(src) - return - - if (isturf(top_atom)) - if (source_turf != top_atom) - source_turf = top_atom - update = TRUE - else if (top_atom.loc != source_turf) - source_turf = top_atom.loc - update = TRUE - - if (!source_turf) - return // Somehow we've got a light in nullspace, no-op. - - if (light_range && light_power && !applied) - update = TRUE - - if (source_atom.light_color != light_color) - light_color = source_atom.light_color - parse_light_color() - update = TRUE - - else if (applied_lum_r != lum_r || applied_lum_g != lum_g || applied_lum_b != lum_b) - update = TRUE - - if (source_atom.light_wedge != light_angle) - light_angle = source_atom.light_wedge - update = TRUE - - if (light_angle) - var/ndir - if(istype(top_atom, /mob) && top_atom:facing_dir) - var/mob/mob = top_atom - if(mob.facing_dir) - ndir = mob.facing_dir - else - ndir = top_atom.dir - else - ndir = top_atom.dir - - if (old_direction != ndir) // If our direction has changed, we need to regenerate all the angle info. - regenerate_angle(ndir) - update = TRUE - else // Check if it was just a x/y translation, and update our vars without an regenerate_angle() call if it is. - var/co_updated = FALSE - if (source_turf.x != cached_origin_x) - test_x_offset += source_turf.x - cached_origin_x - cached_origin_x = source_turf.x - - co_updated = TRUE - - if (source_turf.y != cached_origin_y) - test_y_offset += source_turf.y - cached_origin_y - cached_origin_y = source_turf.y - - co_updated = TRUE - - if (co_updated) - // We might be facing a wall now. - var/turf/front = get_step(source_turf, old_direction) - var/new_fo = (front && front.has_opaque_atom) - if (new_fo != facing_opaque) - facing_opaque = new_fo - regenerate_angle(ndir) - - update = TRUE - - if (update) - needs_update = LIGHTING_CHECK_UPDATE - else if (needs_update == LIGHTING_CHECK_UPDATE) - return // No change. - - var/list/datum/lighting_corner/corners = list() - var/list/turf/turfs = list() - var/thing - var/datum/lighting_corner/C - var/turf/T - var/list/Tcorners - var/Sx = source_turf.x - var/Sy = source_turf.y - var/Sz = source_turf.z - var/corner_height = LIGHTING_HEIGHT - var/actual_range = (light_angle && facing_opaque) ? light_range * LIGHTING_BLOCKED_FACTOR : light_range - var/test_x - var/test_y - - FOR_DVIEW(T, Ceiling(actual_range), source_turf, 0) - check_t: - - if (light_angle && !facing_opaque) // Directional lighting coordinate filter. - test_x = T.x - test_x_offset - test_y = T.y - test_y_offset - - // if the signs of both of these are NOT the same, the point is NOT within the cone. - if ((PSEUDO_WEDGE(limit_a_x, limit_a_y, test_x, test_y) > 0) || (PSEUDO_WEDGE(test_x, test_y, limit_b_x, limit_b_y) > 0)) - continue - - if (TURF_IS_DYNAMICALLY_LIT_UNSAFE(T) || T.light_sources) - Tcorners = T.corners - if (!T.lighting_corners_initialised) - T.lighting_corners_initialised = TRUE - - if (!Tcorners) - T.corners = list(null, null, null, null) - Tcorners = T.corners - - for (var/i = 1 to 4) - if (Tcorners[i]) - continue - - Tcorners[i] = new /datum/lighting_corner(T, LIGHTING_CORNER_DIAGONAL[i]) - - if (!T.has_opaque_atom) - for(var/v = 1 to 4) - var/val = Tcorners[v] - if(val) - corners[val] = 0 - - - - turfs += T - - // Note: above is defined on ALL turfs, but below is only defined on OPEN TURFS. - - // Upwards lights are handled at the corner level, so only search down. - if (T && (T.z_flags & ZM_MIMIC_BELOW) && T.below) - T = T.below - goto check_t - - END_FOR_DVIEW - - LAZYINITLIST(affecting_turfs) - - var/list/L = turfs - affecting_turfs // New turfs, add us to the affecting lights of them. - affecting_turfs += L - for (var/turf/affected_turf as anything in L) - if(!QDELETED(affected_turf)) - T = affected_turf - LAZYADD(T.affecting_lights, src) - - L = affecting_turfs - turfs // Now-gone turfs, remove us from the affecting lights. - affecting_turfs -= L - for (thing in L) - T = thing - LAZYREMOVE(T.affecting_lights, src) - - LAZYINITLIST(effect_str) - if (needs_update == LIGHTING_VIS_UPDATE) - for (thing in corners - effect_str) - C = thing - LAZYADD(C.affecting, src) - if (!C.active) - effect_str[C] = 0 - continue - - APPLY_CORNER_BY_HEIGHT(now) - else - L = corners - effect_str - for (thing in L) - C = thing - LAZYADD(C.affecting, src) - if (!C.active) - effect_str[C] = 0 - continue - - APPLY_CORNER_BY_HEIGHT(now) - - for (thing in corners - L) - C = thing - if (!C.active) - effect_str[C] = 0 - continue - - APPLY_CORNER_BY_HEIGHT(now) - - L = effect_str - corners - for (thing in L) - C = thing - REMOVE_CORNER(C, now) - LAZYREMOVE(C.affecting, src) - - effect_str -= L - - applied_lum_r = lum_r - applied_lum_g = lum_g - applied_lum_b = lum_b - applied_lum_u = lum_u - - UNSETEMPTY(effect_str) - UNSETEMPTY(affecting_turfs) - -#undef INTELLIGENT_UPDATE -#undef PSEUDO_WEDGE diff --git a/code/modules/lighting/lighting_source_sunlight.dm b/code/modules/lighting/lighting_source_sunlight.dm deleted file mode 100644 index 6124e517266..00000000000 --- a/code/modules/lighting/lighting_source_sunlight.dm +++ /dev/null @@ -1,197 +0,0 @@ -#ifdef ENABLE_SUNLIGHT - -/datum/light_source/sunlight - skip_falloff = TRUE - -/datum/light_source/sunlight/update_corners() - var/update = FALSE - - if (QDELETED(source_atom)) - qdel(src) - return - - if (source_atom.light_power != light_power) - light_power = source_atom.light_power - update = TRUE - - if (source_atom.light_range != light_range) - light_range = source_atom.light_range - update = TRUE - - if (!top_atom) - top_atom = source_atom - update = TRUE - - if (top_atom.loc != source_turf) - source_turf = top_atom.loc - update = TRUE - - if (!light_range || !light_power) - qdel(src) - return - - if (isturf(top_atom)) - if (source_turf != top_atom) - source_turf = top_atom - update = TRUE - else if (top_atom.loc != source_turf) - source_turf = top_atom.loc - update = TRUE - - if (!source_turf) - return // Somehow we've got a light in nullspace, no-op. - - if (light_range && light_power && !applied) - update = TRUE - - if (source_atom.light_color != light_color) - light_color = source_atom.light_color - parse_light_color() - update = TRUE - - else if (applied_lum_r != lum_r || applied_lum_g != lum_g || applied_lum_b != lum_b) - update = TRUE - - if (update) - needs_update = LIGHTING_CHECK_UPDATE - else if (needs_update == LIGHTING_CHECK_UPDATE) - return // No change. - - var/list/datum/lighting_corner/corners = list() - var/list/turf/turfs = list() - var/thing - var/datum/lighting_corner/C - var/turf/T - var/Tthing - var/list/Tcorners - - // We don't need no damn vis checks! - for (Tthing in RANGE_TURFS(Ceiling(light_range), source_turf)) - T = Tthing - if (GLOB.the_station_areas[T.loc]) - continue - - check_t: - - if (TURF_IS_DYNAMICALLY_LIT_UNSAFE(T) || T.light_sources) - Tcorners = T.corners - if (!T.lighting_corners_initialised) - T.lighting_corners_initialised = TRUE - - if (!Tcorners) - T.corners = list(null, null, null, null) - Tcorners = T.corners - - for (var/i = 1 to 4) - if (Tcorners[i]) - continue - - Tcorners[i] = new /datum/lighting_corner(T, LIGHTING_CORNER_DIAGONAL[i]) - - if (!T.has_opaque_atom) - corners[Tcorners[1]] = 0 - corners[Tcorners[2]] = 0 - corners[Tcorners[3]] = 0 - corners[Tcorners[4]] = 0 - - turfs += T - - CHECK_TICK - - // Sunlight only checks downwards as it has no need to shine upwards, really. - if (T && (T.z_flags & ZM_MIMIC_BELOW) && T.below) - T = T.below - goto check_t - - LAZYINITLIST(affecting_turfs) - - var/list/L = turfs - affecting_turfs // New turfs, add us to the affecting lights of them. - affecting_turfs += L - for (thing in L) - T = thing - LAZYADD(T.affecting_lights, src) - - L = affecting_turfs - turfs // Now-gone turfs, remove us from the affecting lights. - affecting_turfs -= L - for (thing in L) - T = thing - LAZYREMOVE(T.affecting_lights, src) - - LAZYINITLIST(effect_str) - if (needs_update == LIGHTING_VIS_UPDATE) - for (thing in corners - effect_str) - C = thing - LAZYADD(C.affecting, src) - if (!C.active) - effect_str[C] = 0 - continue - - APPLY_CORNER_SIMPLE(C) - else - L = corners - effect_str - for (thing in L) - C = thing - LAZYADD(C.affecting, src) - if (!C.active) - effect_str[C] = 0 - continue - - APPLY_CORNER_SIMPLE(C) - - for (thing in corners - L) - C = thing - if (!C.active) - effect_str[C] = 0 - continue - - APPLY_CORNER_SIMPLE(C) - - L = effect_str - corners - for (thing in L) - C = thing - REMOVE_CORNER(C, FALSE) - LAZYREMOVE(C.affecting, src) - - effect_str -= L - - applied_lum_r = lum_r - applied_lum_g = lum_g - applied_lum_b = lum_b - applied_lum_u = lum_u - - UNSETEMPTY(effect_str) - UNSETEMPTY(affecting_turfs) - -/datum/light_source/sunlight/regenerate_angle() - return - -#define QUEUE_UPDATE(level) \ - if (needs_update == LIGHTING_NO_UPDATE) \ - SSlighting.light_queue += src; \ - if (needs_update < level) \ - needs_update = level; - -/datum/light_source/sunlight/update(atom/new_top_atom) - // This top atom is different. - if (new_top_atom && new_top_atom != top_atom) - if(top_atom != source_atom) // Remove ourselves from the light sources of that top atom. - LAZYREMOVE(top_atom.light_sources, src) - - top_atom = new_top_atom - - if (top_atom != source_atom) - LAZYADD(top_atom.light_sources, src) // Add ourselves to the light sources of our new top atom. - - //L_PROF(source_atom, "source_update") - - QUEUE_UPDATE(LIGHTING_CHECK_UPDATE) - -/datum/light_source/sunlight/force_update() - QUEUE_UPDATE(LIGHTING_FORCE_UPDATE) - -/datum/light_source/sunlight/vis_update() - QUEUE_UPDATE(LIGHTING_VIS_UPDATE) - -#undef QUEUE_UPDATE - -#endif diff --git a/code/modules/lighting/lighting_static/static_lighting_area.dm b/code/modules/lighting/lighting_static/static_lighting_area.dm new file mode 100644 index 00000000000..2e95c77e9ec --- /dev/null +++ b/code/modules/lighting/lighting_static/static_lighting_area.dm @@ -0,0 +1,12 @@ +/area + ///Whether this area allows static lighting and thus loads the lighting objects + var/static_lighting = TRUE + +//Non static lighting areas. +//Any lighting area that wont support static lights. +//These areas will NOT have corners generated. + +/area/space + static_lighting = FALSE + base_lighting_alpha = 255 + diff --git a/code/modules/lighting/lighting_static/static_lighting_atom.dm b/code/modules/lighting/lighting_static/static_lighting_atom.dm new file mode 100644 index 00000000000..0f7be52b351 --- /dev/null +++ b/code/modules/lighting/lighting_static/static_lighting_atom.dm @@ -0,0 +1,25 @@ + +/atom + ///The light source, datum. Dont fuck with this directly + var/tmp/datum/static_light_source/static_light + ///Static light sources currently attached to this atom, this includes ones owned by atoms inside this atom + var/tmp/list/static_light_sources + +///Pretty simple, just updates static lights on this atom +/atom/proc/static_update_light() + set waitfor = FALSE + if (QDELETED(src)) + return + + if (!light_power || !light_range) // We won't emit light anyways, destroy the light source. + QDEL_NULL(static_light) + else + if(!ismovableatom(loc)) // We choose what atom should be the top atom of the light here. + . = src + else + . = loc + + if(static_light) // Update the light or create it if it does not exist. + static_light.update(.) + else + static_light = new/datum/static_light_source(src, .) diff --git a/code/modules/lighting/lighting_static/static_lighting_corner.dm b/code/modules/lighting/lighting_static/static_lighting_corner.dm new file mode 100644 index 00000000000..4f026e05e86 --- /dev/null +++ b/code/modules/lighting/lighting_static/static_lighting_corner.dm @@ -0,0 +1,176 @@ +// Because we can control each corner of every lighting object. +// And corners get shared between multiple turfs (unless you're on the corners of the map, then 1 corner doesn't). +// For the record: these should never ever ever be deleted, even if the turf doesn't have dynamic lighting. + +/datum/static_lighting_corner + var/list/datum/static_light_source/affecting // Light sources affecting us. + + var/x = 0 + var/y = 0 + + var/turf/master_NE + var/turf/master_SE + var/turf/master_SW + var/turf/master_NW + + var/lum_r = 0 + var/lum_g = 0 + var/lum_b = 0 + + //true color values, guaranteed to be between 0 and 1 + var/cache_r = LIGHTING_SOFT_THRESHOLD + var/cache_g = LIGHTING_SOFT_THRESHOLD + var/cache_b = LIGHTING_SOFT_THRESHOLD + + ///the maximum of lum_r, lum_g, and lum_b. if this is > 1 then the three cached color values are divided by this + var/largest_color_luminosity = 0 + + ///whether we are to be added to SSlighting's corners_queue list for an update + var/needs_update = FALSE + +/datum/static_lighting_corner/New(turf/new_turf, diagonal) + . = ..() + save_master(new_turf, turn(diagonal, 180)) + + var/vertical = diagonal & ~(diagonal - 1) // The horizontal directions (4 and 8) are bigger than the vertical ones (1 and 2), so we can reliably say the lsb is the horizontal direction. + var/horizontal = diagonal & ~vertical // Now that we know the horizontal one we can get the vertical one. + + x = new_turf.x + (horizontal == EAST ? 0.5 : -0.5) + y = new_turf.y + (vertical == NORTH ? 0.5 : -0.5) + + // My initial plan was to make this loop through a list of all the dirs (horizontal, vertical, diagonal). + // Issue being that the only way I could think of doing it was very messy, slow and honestly overengineered. + // So we'll have this hardcode instead. + var/turf/new_master_turf + + // Diagonal one is easy. + new_master_turf = get_step(new_turf, diagonal) + if(new_master_turf) // In case we're on the map's border. + save_master(new_master_turf, diagonal) + + // Now the horizontal one. + new_master_turf = get_step(new_turf, horizontal) + if(new_master_turf) // Ditto. + save_master(new_master_turf, ((new_master_turf.x > x) ? EAST : WEST) | ((new_master_turf.y > y) ? NORTH : SOUTH)) // Get the dir based on coordinates. + + // And finally the vertical one. + new_master_turf = get_step(new_turf, vertical) + if (new_master_turf) + save_master(new_master_turf, ((new_master_turf.x > x) ? EAST : WEST) | ((new_master_turf.y > y) ? NORTH : SOUTH)) // Get the dir based on coordinates. + +/datum/static_lighting_corner/proc/save_master(turf/master, dir) + switch (dir) + if (NORTHEAST) + master_NE = master + master.lighting_corner_SW = src + if (SOUTHEAST) + master_SE = master + master.lighting_corner_NW = src + if (SOUTHWEST) + master_SW = master + master.lighting_corner_NE = src + if (NORTHWEST) + master_NW = master + master.lighting_corner_SE = src + +/datum/static_lighting_corner/proc/self_destruct_if_idle() + if (!LAZYLEN(affecting)) + qdel(src, force = TRUE) + +/datum/static_lighting_corner/proc/vis_update() + for (var/datum/static_light_source/light_source as anything in affecting) + light_source.vis_update() + +/datum/static_lighting_corner/proc/full_update() + for (var/datum/static_light_source/light_source as anything in affecting) + light_source.recalc_corner(src) + +// God that was a mess, now to do the rest of the corner code! Hooray! +/datum/static_lighting_corner/proc/update_lumcount(delta_r, delta_g, delta_b) + + if(!(delta_r || delta_g || delta_b)) // 0 is falsey ok + return + + lum_r += delta_r + lum_g += delta_g + lum_b += delta_b + + if(!needs_update) + needs_update = TRUE + SSlighting.corners_queue += src + +/datum/static_lighting_corner/proc/update_objects() + // Cache these values a head of time so 4 individual lighting objects don't all calculate them individually. + var/lum_r = src.lum_r + var/lum_g = src.lum_g + var/lum_b = src.lum_b + var/largest_color_luminosity = max(lum_r, lum_g, lum_b) // Scale it so one of them is the strongest lum, if it is above 1. + . = 1 // factor + if (largest_color_luminosity > 1) + . = 1 / largest_color_luminosity + + #if LIGHTING_SOFT_THRESHOLD != 0 + else if (largest_color_luminosity < LIGHTING_SOFT_THRESHOLD) + . = 0 // 0 means soft lighting. + + cache_r = round(lum_r * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD + cache_g = round(lum_g * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD + cache_b = round(lum_b * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD + #else + cache_r = round(lum_r * ., LIGHTING_ROUND_VALUE) + cache_g = round(lum_g * ., LIGHTING_ROUND_VALUE) + cache_b = round(lum_b * ., LIGHTING_ROUND_VALUE) + #endif + + src.largest_color_luminosity = round(largest_color_luminosity, LIGHTING_ROUND_VALUE) + + var/datum/static_lighting_object/lighting_object = master_NE?.static_lighting_object + if (lighting_object && !lighting_object.needs_update) + lighting_object.needs_update = TRUE + SSlighting.objects_queue += lighting_object + + lighting_object = master_SE?.static_lighting_object + if (lighting_object && !lighting_object.needs_update) + lighting_object.needs_update = TRUE + SSlighting.objects_queue += lighting_object + + lighting_object = master_SW?.static_lighting_object + if (lighting_object && !lighting_object.needs_update) + lighting_object.needs_update = TRUE + SSlighting.objects_queue += lighting_object + + lighting_object = master_NW?.static_lighting_object + if (lighting_object && !lighting_object.needs_update) + lighting_object.needs_update = TRUE + SSlighting.objects_queue += lighting_object + + self_destruct_if_idle() + + +/datum/static_lighting_corner/dummy/New() + return + + +/datum/static_lighting_corner/Destroy(force) + if (!force) + return QDEL_HINT_LETMELIVE + + for(var/datum/static_light_source/light_source as anything in affecting) + LAZYREMOVE(light_source.effect_str, src) + affecting = null + + if(master_NE) + master_NE.lighting_corner_SW = null + master_NE.lighting_corners_initialised = FALSE + if(master_SE) + master_SE.lighting_corner_NW = null + master_SE.lighting_corners_initialised = FALSE + if(master_SW) + master_SW.lighting_corner_NE = null + master_SW.lighting_corners_initialised = FALSE + if(master_NW) + master_NW.lighting_corner_SE = null + master_NW.lighting_corners_initialised = FALSE + if(needs_update) + SSlighting.corners_queue -= src + return ..() diff --git a/code/modules/lighting/lighting_static/static_lighting_object.dm b/code/modules/lighting/lighting_static/static_lighting_object.dm new file mode 100644 index 00000000000..bc61bdb06c1 --- /dev/null +++ b/code/modules/lighting/lighting_static/static_lighting_object.dm @@ -0,0 +1,115 @@ +/datum/static_lighting_object + ///the underlay we are currently applying to our turf to apply light + var/mutable_appearance/current_underlay + + ///whether we are already in the SSlighting.objects_queue list + var/needs_update = FALSE + + ///the turf that our light is applied to + var/turf/affected_turf + +/datum/static_lighting_object/New(turf/source) + if(!isturf(source)) + qdel(src, force=TRUE) + stack_trace("a lighting object was assigned to [source], a non turf! ") + return + ..() + + current_underlay = mutable_appearance(LIGHTING_ICON, "transparent", FLOAT_LAYER, LIGHTING_PLANE, 255, RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM) + + affected_turf = source + if (affected_turf.static_lighting_object) + qdel(affected_turf.static_lighting_object, force = TRUE) + stack_trace("a lighting object was assigned to a turf that already had a lighting object!") + + affected_turf.static_lighting_object = src + affected_turf.luminosity = 0 + + needs_update = TRUE + SSlighting.objects_queue += src + +/datum/static_lighting_object/Destroy(force) + if (!force) + return QDEL_HINT_LETMELIVE + SSlighting.objects_queue -= src + if (isturf(affected_turf)) + affected_turf.static_lighting_object = null + affected_turf.luminosity = 1 + affected_turf.underlays -= current_underlay + affected_turf = null + return ..() + +/datum/static_lighting_object/proc/update() + + // To the future coder who sees this and thinks + // "Why didn't he just use a loop?" + // Well my man, it's because the loop performed like shit. + // And there's no way to improve it because + // without a loop you can make the list all at once which is the fastest you're gonna get. + // Oh it's also shorter line wise. + // Including with these comments. + + var/static/datum/static_lighting_corner/dummy/dummy_lighting_corner = new + + var/datum/static_lighting_corner/red_corner = affected_turf.lighting_corner_SW || dummy_lighting_corner + var/datum/static_lighting_corner/green_corner = affected_turf.lighting_corner_SE || dummy_lighting_corner + var/datum/static_lighting_corner/blue_corner = affected_turf.lighting_corner_NW || dummy_lighting_corner + var/datum/static_lighting_corner/alpha_corner = affected_turf.lighting_corner_NE || dummy_lighting_corner + + var/max = max(red_corner.largest_color_luminosity, green_corner.largest_color_luminosity, blue_corner.largest_color_luminosity, alpha_corner.largest_color_luminosity) + + var/rr = red_corner.cache_r + var/rg = red_corner.cache_g + var/rb = red_corner.cache_b + + var/gr = green_corner.cache_r + var/gg = green_corner.cache_g + var/gb = green_corner.cache_b + + var/br = blue_corner.cache_r + var/bg = blue_corner.cache_g + var/bb = blue_corner.cache_b + + var/ar = alpha_corner.cache_r + var/ag = alpha_corner.cache_g + var/ab = alpha_corner.cache_b + + #if LIGHTING_SOFT_THRESHOLD != 0 + var/set_luminosity = max > LIGHTING_SOFT_THRESHOLD + #else + // Because of floating points�?, it won't even be a flat 0. + // This number is mostly arbitrary. + var/set_luminosity = max > 1e-6 + #endif + + if((rr & gr & br & ar) && (rg + gg + bg + ag + rb + gb + bb + ab == 8)) + //anything that passes the first case is very likely to pass the second, and addition is a little faster in this case + affected_turf.underlays -= current_underlay + current_underlay.icon_state = "lighting_transparent" + current_underlay.color = null + affected_turf.underlays += current_underlay + else if(!set_luminosity) + affected_turf.underlays -= current_underlay + current_underlay.icon_state = "lighting_dark" + current_underlay.color = null + affected_turf.underlays += current_underlay + else + affected_turf.underlays -= current_underlay + current_underlay.icon_state = null + current_underlay.color = list( + rr, rg, rb, 00, + gr, gg, gb, 00, + br, bg, bb, 00, + ar, ag, ab, 00, + 00, 00, 00, 01 + ) + + affected_turf.underlays += current_underlay + + var/area/A = affected_turf.loc + //We are luminous + if(set_luminosity) + affected_turf.luminosity = set_luminosity + //We are not lit by static light OR dynamic light. + else if(!LAZYLEN(affected_turf.hybrid_lights_affecting) && !A.base_lighting_alpha) + affected_turf.luminosity = 0 diff --git a/code/modules/lighting/lighting_static/static_lighting_setup.dm b/code/modules/lighting/lighting_static/static_lighting_setup.dm new file mode 100644 index 00000000000..6e1641585b9 --- /dev/null +++ b/code/modules/lighting/lighting_static/static_lighting_setup.dm @@ -0,0 +1,10 @@ +/proc/create_all_lighting_objects() + for(var/area/A in world) + + if(!A.static_lighting) + continue + + for(var/turf/T in A) + new/datum/static_lighting_object(T) + CHECK_TICK + CHECK_TICK diff --git a/code/modules/lighting/lighting_static/static_lighting_source.dm b/code/modules/lighting/lighting_static/static_lighting_source.dm new file mode 100644 index 00000000000..f22ed40418d --- /dev/null +++ b/code/modules/lighting/lighting_static/static_lighting_source.dm @@ -0,0 +1,306 @@ +// This is where the fun begins. +// These are the main datums that emit light. + +/datum/static_light_source + ///The atom we're emitting light from (for example a mob if we're from a flashlight that's being held). + var/atom/top_atom + ///The atom that we belong to. + var/atom/source_atom + + ///The turf under the source atom. + var/turf/source_turf + ///The turf the top_atom appears to over. + var/turf/pixel_turf + ///Intensity of the emitter light. + var/light_power + /// The range of the emitted light. + var/light_range + /// The colour of the light, string, decomposed by parse_light_color() + var/light_color + // Variables for keeping track of the colour. + var/lum_r + var/lum_g + var/lum_b + + // The lumcount values used to apply the light. + var/tmp/applied_lum_r + var/tmp/applied_lum_g + var/tmp/applied_lum_b + + /// List used to store how much we're affecting corners. + var/list/datum/static_lighting_corner/effect_str + + /// Whether we have applied our light yet or not. + var/applied = FALSE + + /// whether we are to be added to SSlighting's static_sources_queue list for an update + var/needs_update = LIGHTING_NO_UPDATE + +// Thanks to Lohikar for flinging this tiny bit of code at me, increasing my brain cell count from 1 to 2 in the process. +// This macro will only offset up to 1 tile, but anything with a greater offset is an outlier and probably should handle its own lighting offsets. +// Anything pixelshifted 16px or more will be considered on the next tile. +#define GET_APPROXIMATE_PIXEL_DIR(PX, PY) ((!(PX) ? 0 : ((PX >= 16 ? EAST : (PX <= -16 ? WEST : 0)))) | (!PY ? 0 : (PY >= 16 ? NORTH : (PY <= -16 ? SOUTH : 0)))) +#define UPDATE_APPROXIMATE_PIXEL_TURF var/_mask = GET_APPROXIMATE_PIXEL_DIR(top_atom.pixel_x, top_atom.pixel_y); pixel_turf = _mask ? (get_step(source_turf, _mask) || source_turf) : source_turf + +/datum/static_light_source/New(atom/owner, atom/top) + source_atom = owner // Set our new owner. + LAZYADD(source_atom.static_light_sources, src) + top_atom = top + if (top_atom != source_atom) + LAZYADD(top_atom.static_light_sources, src) + + source_turf = top_atom + UPDATE_APPROXIMATE_PIXEL_TURF + + light_power = source_atom.light_power + light_range = source_atom.light_range + light_color = source_atom.light_color + + PARSE_LIGHT_COLOR(src) + + update() + +/datum/static_light_source/Destroy(force) + remove_lum() + if (source_atom) + LAZYREMOVE(source_atom.static_light_sources, src) + + if (top_atom) + LAZYREMOVE(top_atom.static_light_sources, src) + + if (needs_update) + SSlighting.static_sources_queue -= src + return ..() + +#define EFFECT_UPDATE(level) \ + if (needs_update == LIGHTING_NO_UPDATE) \ + SSlighting.static_sources_queue += src; \ + if (needs_update < level) \ + needs_update = level; \ + + +/// This proc will cause the light source to update the top atom, and add itself to the update queue. +/datum/static_light_source/proc/update(atom/new_top_atom) + // This top atom is different. + if (new_top_atom && new_top_atom != top_atom) + if(top_atom != source_atom && top_atom.static_light_sources) // Remove ourselves from the light sources of that top atom. + LAZYREMOVE(top_atom.static_light_sources, src) + + top_atom = new_top_atom + + if (top_atom != source_atom) + LAZYADD(top_atom.static_light_sources, src) // Add ourselves to the light sources of our new top atom. + + EFFECT_UPDATE(LIGHTING_CHECK_UPDATE) + +/// Will force an update without checking if it's actually needed. +/datum/static_light_source/proc/force_update() + EFFECT_UPDATE(LIGHTING_FORCE_UPDATE) + +/// Will cause the light source to recalculate turfs that were removed or added to visibility only. +/datum/static_light_source/proc/vis_update() + EFFECT_UPDATE(LIGHTING_VIS_UPDATE) + +// Macro that applies light to a new corner. +// It is a macro in the interest of speed, yet not having to copy paste it. +// If you're wondering what's with the backslashes, the backslashes cause BYOND to not automatically end the line. +// As such this all gets counted as a single line. +// The braces and semicolons are there to be able to do this on a single line. + +//Original lighting falloff calculation. This looks the best out of the three. However, this is also the most expensive. +//#define LUM_FALLOFF(C, T) (1 - CLAMP01(sqrt((C.x - T.x) ** 2 + (C.y - T.y) ** 2 + LIGHTING_HEIGHT) / max(1, light_range))) + +//Cubic lighting falloff. This has the *exact* same range as the original lighting falloff calculation, down to the exact decimal, but it looks a little unnatural due to the harsher falloff and how it's generally brighter across the board. +//#define LUM_FALLOFF(C, T) (1 - CLAMP01((((C.x - T.x) * (C.x - T.x)) + ((C.y - T.y) * (C.y - T.y)) + LIGHTING_HEIGHT) / max(1, light_range*light_range))) + +//Linear lighting falloff. This resembles the original lighting falloff calculation the best, but results in lights having a slightly larger range, which is most noticeable with large light sources. This also results in lights being diamond-shaped, fuck. This looks the darkest out of the three due to how lights are brighter closer to the source compared to the original falloff algorithm. This falloff method also does not at all take into account lighting height, as it acts as a flat reduction to light range with this method. +//#define LUM_FALLOFF(C, T) (1 - CLAMP01(((abs(C.x - T.x) + abs(C.y - T.y))) / max(1, light_range+1))) + +//Linear lighting falloff but with an octagonal shape in place of a diamond shape. Lummox JR please add pointer support. +#define GET_LUM_DIST(DISTX, DISTY) (DISTX + DISTY + abs(DISTX - DISTY)*0.4) +#define LUM_FALLOFF(C, T) (1 - CLAMP01(max(GET_LUM_DIST(abs(C.x - T.x), abs(C.y - T.y)),LIGHTING_HEIGHT) / max(1, light_range+1))) + +#define APPLY_CORNER(C) \ + . = LUM_FALLOFF(C, pixel_turf); \ + . *= light_power; \ + var/OLD = effect_str[C]; \ + C.update_lumcount \ + ( \ + (. * lum_r) - (OLD * applied_lum_r), \ + (. * lum_g) - (OLD * applied_lum_g), \ + (. * lum_b) - (OLD * applied_lum_b) \ + ); + +#define REMOVE_CORNER(C) \ + . = -effect_str[C]; \ + C.update_lumcount \ + ( \ + . * applied_lum_r, \ + . * applied_lum_g, \ + . * applied_lum_b \ + ); + +/// This is the define used to calculate falloff. +/datum/static_light_source/proc/remove_lum() + applied = FALSE + for(var/datum/static_lighting_corner/corner as anything in effect_str) + REMOVE_CORNER(corner) + LAZYREMOVE(corner.affecting, src) + + effect_str = null + +/datum/static_light_source/proc/recalc_corner(datum/static_lighting_corner/corner) + LAZYINITLIST(effect_str) + if (effect_str[corner]) // Already have one. + REMOVE_CORNER(corner) + effect_str[corner] = 0 + + APPLY_CORNER(corner) + effect_str[corner] = . + +/datum/static_light_source/proc/update_corners() + var/update = FALSE + var/atom/source_atom = src.source_atom + + if (QDELETED(source_atom)) + qdel(src) + return + + if (source_atom.light_power != light_power) + light_power = source_atom.light_power + update = TRUE + + if (source_atom.light_range != light_range) + light_range = source_atom.light_range + update = TRUE + + if (!top_atom) + top_atom = source_atom + update = TRUE + + if (!light_range || !light_power) + qdel(src) + return + + if (isturf(top_atom)) + if (source_turf != top_atom) + source_turf = top_atom + UPDATE_APPROXIMATE_PIXEL_TURF + update = TRUE + else if (top_atom.loc != source_turf) + source_turf = top_atom.loc + UPDATE_APPROXIMATE_PIXEL_TURF + update = TRUE + else + var/pixel_loc = get_turf_pixel(top_atom) + if (pixel_loc != pixel_turf) + pixel_turf = pixel_loc + update = TRUE + + if (!isturf(source_turf)) + if (applied) + remove_lum() + return + + if (light_range && light_power && !applied) + update = TRUE + + if (source_atom.light_color != light_color) + light_color = source_atom.light_color + PARSE_LIGHT_COLOR(src) + update = TRUE + + else if (applied_lum_r != lum_r || applied_lum_g != lum_g || applied_lum_b != lum_b) + update = TRUE + + if (update) + needs_update = LIGHTING_CHECK_UPDATE + applied = TRUE + else if (needs_update == LIGHTING_CHECK_UPDATE) + return //nothing's changed + + var/list/datum/static_lighting_corner/corners = list() + var/list/turf/turfs = list() + if (source_turf) + var/oldlum = source_turf.luminosity + source_turf.luminosity = ceil(light_range) + for(var/turf/T in view(ceil(light_range), source_turf)) + if(!IS_OPAQUE_TURF(T)) + if (!T.lighting_corners_initialised) + T.static_generate_missing_corners() + corners[T.lighting_corner_NE] = 0 + corners[T.lighting_corner_SE] = 0 + corners[T.lighting_corner_SW] = 0 + corners[T.lighting_corner_NW] = 0 + turfs += T + + var/turf/above = GET_TURF_ABOVE(T) + + while(above && istransparentturf(above)) + if (!above.lighting_corners_initialised) + above.static_generate_missing_corners() + corners[above.lighting_corner_NE] = 0 + corners[above.lighting_corner_SE] = 0 + corners[above.lighting_corner_SW] = 0 + corners[above.lighting_corner_NW] = 0 + + above = GET_TURF_ABOVE(above) + + turfs += above + + var/turf/below = GET_TURF_BELOW(T) + var/turf/previous = T + + while(below && istransparentturf(previous)) + if (!below.lighting_corners_initialised) + below.static_generate_missing_corners() + corners[below.lighting_corner_NE] = 0 + corners[below.lighting_corner_SE] = 0 + corners[below.lighting_corner_SW] = 0 + corners[below.lighting_corner_NW] = 0 + + previous = below + below = GET_TURF_BELOW(below) + + source_turf.luminosity = oldlum + + var/list/datum/static_lighting_corner/new_corners = (corners - effect_str) + LAZYINITLIST(effect_str) + if (needs_update == LIGHTING_VIS_UPDATE) + for (var/datum/static_lighting_corner/corner as anything in new_corners) + APPLY_CORNER(corner) + if (. != 0) + LAZYADD(corner.affecting, src) + effect_str[corner] = . + else + for (var/datum/static_lighting_corner/corner as anything in new_corners) + APPLY_CORNER(corner) + if (. != 0) + LAZYADD(corner.affecting, src) + effect_str[corner] = . + + for (var/datum/static_lighting_corner/corner as anything in corners - new_corners) // Existing corners + APPLY_CORNER(corner) + if (. != 0) + effect_str[corner] = . + else + LAZYREMOVE(corner.affecting, src) + effect_str -= corner + + var/list/datum/static_lighting_corner/gone_corners = effect_str - corners + for (var/datum/static_lighting_corner/corner as anything in gone_corners) + REMOVE_CORNER(corner) + LAZYREMOVE(corner.affecting, src) + effect_str -= gone_corners + + applied_lum_r = lum_r + applied_lum_g = lum_g + applied_lum_b = lum_b + + UNSETEMPTY(effect_str) + +#undef EFFECT_UPDATE +#undef LUM_FALLOFF +#undef GET_LUM_DIST +#undef REMOVE_CORNER +#undef APPLY_CORNER diff --git a/code/modules/lighting/lighting_static/static_lighting_turf.dm b/code/modules/lighting/lighting_static/static_lighting_turf.dm new file mode 100644 index 00000000000..ec91e17e4fc --- /dev/null +++ b/code/modules/lighting/lighting_static/static_lighting_turf.dm @@ -0,0 +1,64 @@ +/turf + var/tmp/lighting_corners_initialised = FALSE + var/tmp/datum/static_lighting_object/static_lighting_object + + ///Lighting Corner datums. + var/tmp/datum/static_lighting_corner/lighting_corner_NE + var/tmp/datum/static_lighting_corner/lighting_corner_SE + var/tmp/datum/static_lighting_corner/lighting_corner_SW + var/tmp/datum/static_lighting_corner/lighting_corner_NW + +/turf/proc/static_lighting_clear_overlay() + if (static_lighting_object) + qdel(static_lighting_object, TRUE) + +/// Builds a lighting object for us, but only if our area is dynamic. +/turf/proc/static_lighting_build_overlay(area/our_area = loc) + if(static_lighting_object) + qdel(static_lighting_object, force=TRUE) //Shitty fix for lighting objects persisting after death + + new/datum/static_lighting_object(src) + + + +// Returns a boolean whether the turf is on soft lighting. +// Soft lighting being the threshold at which point the overlay considers +// itself as too dark to allow sight and see_in_dark becomes useful. +// So basically if this returns true the tile is unlit black. +/turf/proc/static_is_softly_lit() + if (!static_lighting_object) + return FALSE + + return !(luminosity || dynamic_lumcount) + +///Transfer the lighting of one area to another +/turf/proc/transfer_area_lighting(area/old_area, area/new_area) + if(SSlighting.initialized) + if (new_area.static_lighting != old_area.static_lighting) + if (new_area.static_lighting) + static_lighting_build_overlay(new_area) + else + static_lighting_clear_overlay() + //Inherit overlay of new area + if(old_area.lighting_effect) + overlays -= old_area.lighting_effect + if(new_area.lighting_effect) + overlays += new_area.lighting_effect + + + +/turf/proc/static_generate_missing_corners() + if (!lighting_corner_NE) + lighting_corner_NE = new/datum/static_lighting_corner(src, NORTH|EAST) + + if (!lighting_corner_SE) + lighting_corner_SE = new/datum/static_lighting_corner(src, SOUTH|EAST) + + if (!lighting_corner_SW) + lighting_corner_SW = new/datum/static_lighting_corner(src, SOUTH|WEST) + + if (!lighting_corner_NW) + lighting_corner_NW = new/datum/static_lighting_corner(src, NORTH|WEST) + + lighting_corners_initialised = TRUE + diff --git a/code/modules/lighting/lighting_turf.dm b/code/modules/lighting/lighting_turf.dm index ea6c460b230..cc2b27c9035 100644 --- a/code/modules/lighting/lighting_turf.dm +++ b/code/modules/lighting/lighting_turf.dm @@ -1,184 +1,84 @@ -/turf - var/dynamic_lighting = TRUE - luminosity = 1 +///Estimates the light power based on the alpha of the light and the range. +///Assumes a linear fallout at (0, alpha/255) to (range, 0) +///Used for lightig mask lumcount calculations +#define LIGHT_POWER_ESTIMATION(alpha, range, distance) max((alpha * (range - distance)) / (255 * range), 0) - var/tmp/lighting_corners_initialised = FALSE - - var/tmp/list/datum/light_source/affecting_lights // List of light sources affecting this turf. - var/tmp/atom/movable/lighting_overlay/lighting_overlay // Our lighting overlay. - var/tmp/list/datum/lighting_corner/corners - var/tmp/has_opaque_atom = FALSE // Not to be confused with opacity, this will be TRUE if there's any opaque atom on the tile. - -// Causes any affecting light sources to be queued for a visibility update, for example a door got opened. +/// Causes any affecting light sources to be queued for a visibility update, for example a door got opened. /turf/proc/reconsider_lights() - //L_PROF(src, "turf_reconsider") - var/datum/light_source/L - for (var/thing in affecting_lights) - L = thing - L.vis_update() + //Consider static lights + lighting_corner_NE?.vis_update() + lighting_corner_SE?.vis_update() + lighting_corner_SW?.vis_update() + lighting_corner_NW?.vis_update() -// Forces a lighting update. Reconsider lights is preferred when possible. -/turf/proc/force_update_lights() - //L_PROF(src, "turf_forceupdate") - var/datum/light_source/L - for (var/thing in affecting_lights) - L = thing - L.force_update() - -/turf/proc/lighting_clear_overlay() - if (lighting_overlay) - if (lighting_overlay.loc != src) - var/turf/badT = lighting_overlay.loc - crash_with("Lighting overlay variable on turf [DEBUG_REF(src)] is insane, lighting overlay actually located on [DEBUG_REF(lighting_overlay.loc)] at ([badT.x],[badT.y],[badT.z])!") - - qdel(lighting_overlay, TRUE) - lighting_overlay = null - - //L_PROF(src, "turf_clear_overlay") - - for (var/datum/lighting_corner/C in corners) - C.update_active() - -// Builds a lighting overlay for us, but only if our area is dynamic. -/turf/proc/lighting_build_overlay() - if (lighting_overlay) - return - - //L_PROF(src, "turf_build_overlay") - - var/area/A = loc - if (A.dynamic_lighting && dynamic_lighting) - if (!lighting_corners_initialised || !corners) - generate_missing_corners() - - new /atom/movable/lighting_overlay(src) - - for (var/datum/lighting_corner/C in corners) - if (!C.active) // We would activate the corner, calculate the lighting for it. - for (var/L in C.affecting) - var/datum/light_source/S = L - S.recalc_corner(C, TRUE) - - C.active = TRUE - -// Returns the average color of this tile. Roughly corresponds to the color of a single old-style lighting overlay. -/turf/proc/get_avg_color() - if (!lighting_overlay) - return null - - var/lum_r - var/lum_g - var/lum_b - - for (var/datum/lighting_corner/L in corners) - lum_r += L.lum_r - lum_g += L.lum_g - lum_b += L.lum_b - - lum_r = CLAMP01(lum_r / 4) * 255 - lum_g = CLAMP01(lum_g / 4) * 255 - lum_b = CLAMP01(lum_b / 4) * 255 - - return "#[num2hex(lum_r, 2)][num2hex(lum_g, 2)][num2hex(lum_g, 2)]" - -#define SCALE(targ,min,max) (targ - min) / (max - min) + //consider dynamic lights + for(var/atom/movable/lighting_mask/mask as anything in hybrid_lights_affecting) + mask.queue_mask_update() // Used to get a scaled lumcount. /turf/proc/get_lumcount(minlum = 0, maxlum = 1) - if (!lighting_overlay) - return 0.5 - var/totallums = 0 - for (var/datum/lighting_corner/L in corners) - totallums += L.lum_r + L.lum_b + L.lum_g + if (static_lighting_object) + var/datum/static_lighting_corner/L + L = lighting_corner_NE + if (L) + totallums += L.lum_r + L.lum_b + L.lum_g + L = lighting_corner_SE + if (L) + totallums += L.lum_r + L.lum_b + L.lum_g + L = lighting_corner_SW + if (L) + totallums += L.lum_r + L.lum_b + L.lum_g + L = lighting_corner_NW + if (L) + totallums += L.lum_r + L.lum_b + L.lum_g - totallums /= 12 // 4 corners, each with 3 channels, get the average. + totallums /= 12 // 4 corners, each with 3 channels, get the average. - totallums = SCALE(totallums, minlum, maxlum) + totallums = (totallums - minlum) / (maxlum - minlum) - return CLAMP01(totallums) - -// Gets the current UV illumination of the turf. Always 100% for space & other static-lit tiles. -/turf/proc/get_uv_lumcount(minlum = 0, maxlum = 1) - if (!lighting_overlay) - return 1 - - L_PROF(src, "turf_get_uv") - - var/totallums = 0 - for (var/datum/lighting_corner/L in corners) - totallums += L.lum_u - - totallums /= 4 // average of four corners. - - totallums = SCALE(totallums, minlum, maxlum) - - return CLAMP01(totallums) - -#undef SCALE - -// Can't think of a good name, this proc will recalculate the has_opaque_atom variable. -/turf/proc/recalc_atom_opacity() -#ifdef AO_USE_LIGHTING_OPACITY - var/old = has_opaque_atom -#endif - - has_opaque_atom = FALSE - if (opacity) - has_opaque_atom = TRUE + totallums = CLAMP01(totallums) else - for (var/thing in src) // Loop through every movable atom on our tile - var/atom/movable/A = thing - if (A.opacity && !QDELETED(A)) - has_opaque_atom = TRUE - break // No need to continue if we find something opaque. - -#ifdef AO_USE_LIGHTING_OPACITY - if (old != has_opaque_atom) - regenerate_ao() -#endif - -/turf/Exited(atom/movable/Obj, atom/newloc) - . = ..() - - if (Obj && Obj.opacity) - recalc_atom_opacity() // Make sure to do this before reconsider_lights(), incase we're on instant updates. - reconsider_lights() - -/turf/proc/transfer_area_lighting(area/old_area, area/new_area) - if (new_area.dynamic_lighting != old_area.dynamic_lighting) - if (new_area.dynamic_lighting) - lighting_build_overlay() + totallums = 1 + for(var/atom/movable/lighting_mask/mask as anything in hybrid_lights_affecting) + if(mask.blend_mode == BLEND_ADD) + totallums += LIGHT_POWER_ESTIMATION(mask.alpha, mask.radius, get_dist(src, get_turf(mask.attached_atom))) else - lighting_clear_overlay() + totallums -= LIGHT_POWER_ESTIMATION(mask.alpha, mask.radius, get_dist(src, get_turf(mask.attached_atom))) + totallums += dynamic_lumcount + return clamp(totallums, 0.0, 1.0) -// This is inlined in lighting_source.dm and lighting_source_novis.dm. -// Update them too if you change this. -/turf/proc/get_corners() - if (!dynamic_lighting && !light_sources) - return null - - if (!lighting_corners_initialised) - generate_missing_corners() - - if (has_opaque_atom) - return null // Since this proc gets used in a for loop, null won't be looped though. - - return corners - -// This is inlined in lighting_source.dm and lighting_source_novis.dm. -// Update them too if you change this. -/turf/proc/generate_missing_corners() - if (!dynamic_lighting && !light_sources) +///Proc to add movable sources of opacity on the turf and let it handle lighting code. +/turf/proc/add_opacity_source(atom/movable/new_source) + LAZYADD(opacity_sources, new_source) + if(opacity) return + recalculate_directional_opacity() - lighting_corners_initialised = TRUE - if (!corners) - corners = list(null, null, null, null) - for (var/i = 1 to 4) - if (corners[i]) // Already have a corner on this direction. - continue +///Proc to remove movable sources of opacity on the turf and let it handle lighting code. +/turf/proc/remove_opacity_source(atom/movable/old_source) + LAZYREMOVE(opacity_sources, old_source) + if(opacity) //Still opaque, no need to worry on updating. + return + recalculate_directional_opacity() - corners[i] = new/datum/lighting_corner(src, LIGHTING_CORNER_DIAGONAL[i]) + +///Calculate on which directions this turfs block view. +/turf/proc/recalculate_directional_opacity() + . = directional_opacity + if(opacity) + directional_opacity = ALL_CARDINALS + if(. != directional_opacity) + reconsider_lights() + return + directional_opacity = NONE + for(var/atom/movable/opacity_source as anything in opacity_sources) + if(opacity_source.atom_flags & ATOM_FLAG_CHECKS_BORDER) + directional_opacity |= opacity_source.dir + else //If fulltile and opaque, then the whole tile blocks view, no need to continue checking. + directional_opacity = ALL_CARDINALS + break + if(. != directional_opacity && (. == ALL_CARDINALS || directional_opacity == ALL_CARDINALS)) + reconsider_lights() //The lighting system only cares whether the tile is fully concealed from all directions or not. diff --git a/code/modules/lighting/lighting_verbs.dm b/code/modules/lighting/lighting_verbs.dm deleted file mode 100644 index ceb67c51993..00000000000 --- a/code/modules/lighting/lighting_verbs.dm +++ /dev/null @@ -1,102 +0,0 @@ -GLOBAL_LIST_INIT(admin_verbs_lighting, list( - /client/proc/lighting_hide_verbs, - /client/proc/lighting_flush, - /client/proc/lighting_reconsider_target, - /client/proc/lighting_build_overlay, - /client/proc/lighting_clear_overlay, - /client/proc/lighting_toggle_profiling -)) - -/client/proc/lighting_show_verbs() - set category = "Debug" - set name = "Show Lighting Verbs" - set desc = "Shows the lighting debug verbs." - - if (!check_rights(R_DEBUG|R_DEV)) return - - to_chat(src, SPAN_NOTICE("Lighting debug verbs have been shown.")) - add_verb(src, GLOB.admin_verbs_lighting) - -/client/proc/lighting_hide_verbs() - set category = "Lighting" - set name = "Hide Lighting Verbs" - set desc = "Hides the lighting debug verbs." - - if (!check_rights(R_DEBUG|R_DEV)) return - - to_chat(src, SPAN_NOTICE("Lighting debug verbs have been hidden.")) - remove_verb(src, GLOB.admin_verbs_lighting) - -/client/proc/lighting_flush() - set category = "Lighting" - set name = "Flush Work Queue" - set desc = "Flushes the lighting processor's current work queue." - - if (!check_rights(R_DEBUG|R_DEV)) return - - if (alert("Flush Lighting Work Queue? This will invalidate all pending lighting updates.", "Reset Lighting", "No", "No", "Yes") != "Yes") - return - - log_and_message_admins("has flushed the lighting processor queues.") - SSlighting.light_queue = list() - SSlighting.corner_queue = list() - SSlighting.overlay_queue = list() - -/client/proc/lighting_reconsider_target(turf/T in world) - set category = "Lighting" - set name = "Reconsider Visibility" - set desc = "Triggers a visibility update for a turf." - - if (!check_rights(R_DEBUG|R_DEV)) return - - if (TURF_IS_DYNAMICALLY_LIT(T)) - to_chat(src, "That turf is not dynamically lit.") - return - - log_and_message_admins("has triggered a lighting update for turf [REF(T)] - [T] at ([T.x],[T.y],[T.z]) in area [T.loc].") - - T.reconsider_lights() - -/client/proc/lighting_build_overlay(turf/T in world) - set category = "Lighting" - set name = "Build Overlay" - set desc = "Builds a lighting overlay for a turf if it does not have one." - - if (!check_rights(R_DEBUG|R_DEV)) return - - if (T.lighting_overlay) - to_chat(src, "That turf already has a lighting overlay.") - return - - log_and_message_admins("has generated a lighting overlay for turf [REF(T)] - [T] ([T.x],[T.y],[T.z]) in area [T.loc].") - - T.lighting_build_overlay() - -/client/proc/lighting_clear_overlay(turf/T in world) - set category = "Lighting" - set name = "Clear Overlay" - set desc = "Clears a lighting overlay for a turf if it has one." - - if (!check_rights(R_DEBUG|R_DEV)) return - - if (!T.lighting_overlay) - to_chat(src, "That turf doesn't have a lighting overlay.") - return - - log_and_message_admins("has cleared a lighting overlay for turf [REF(T)] - [T] ([T.x],[T.y],[T.z]) in area [T.loc].") - - T.lighting_clear_overlay() - -/client/proc/lighting_toggle_profiling() - set category = "Lighting" - set name = "Profile Lighting" - set desc = "Spams the database with lighting updates. Y'know, just 'cause." - - if (!check_rights(R_DEBUG|R_SERVER)) return - - if (!establish_db_connection(GLOB.dbcon)) - to_chat(usr, SPAN_ALERT("Unable to start profiling: No active database connection.")) - return - - GLOB.lighting_profiling = !GLOB.lighting_profiling - log_and_message_admins("has [GLOB.lighting_profiling ? "enabled" : "disabled"] lighting profiling.") diff --git a/code/modules/lighting/~lighting_undefs.dm b/code/modules/lighting/~lighting_undefs.dm deleted file mode 100644 index dd53aa937f5..00000000000 --- a/code/modules/lighting/~lighting_undefs.dm +++ /dev/null @@ -1,13 +0,0 @@ -#undef LIGHTING_HEIGHT - -#undef LIGHTING_ICON - -#undef LIGHTING_BASE_MATRIX - -#undef LUM_FALLOFF -#undef REMOVE_CORNER -#undef APPLY_CORNER - -#undef CALCULATE_CORNER_HEIGHT -#undef APPLY_CORNER_BY_HEIGHT -#undef APPLY_CORNER_SIMPLE diff --git a/code/modules/mapping/map_template.dm b/code/modules/mapping/map_template.dm index 9885f829136..86e8a83f7f0 100644 --- a/code/modules/mapping/map_template.dm +++ b/code/modules/mapping/map_template.dm @@ -54,7 +54,6 @@ /datum/map_template/proc/load_new_z(var/no_changeturf = TRUE) var/x = round((world.maxx - width)/2) var/y = round((world.maxy - height)/2) - var/initial_z = world.maxz + 1 if (x < 1) x = 1 if (y < 1) y = 1 @@ -97,8 +96,6 @@ //initialize things that are normally initialized after map load init_atoms(atoms_to_initialise) init_shuttles(shuttle_state) - for(var/light_z = initial_z to world.maxz) - create_lighting_overlays_zlevel(light_z) log_game("Z-level [name] loaded at [x], [y], [world.maxz]") message_admins("Z-level [name] loaded at [x], [y], [world.maxz]") SSicon_smooth.can_fire = TRUE @@ -164,10 +161,17 @@ T.post_change(FALSE) if(template_flags & TEMPLATE_FLAG_NO_RUINS) T.turf_flags |= TURF_NORUINS + if(istype(T,/turf/simulated)) var/turf/simulated/sim = T sim.update_air_properties() + if(SSlighting.initialized) //don't generate lighting overlays before SSlighting in case these templates are loaded before + var/area/A = T.loc + if(A?.area_has_base_lighting) + continue + T.static_lighting_build_overlay() + /datum/map_template/proc/load(turf/T, centered = FALSE) if(centered) T = locate(T.x - round(width / 2) , T.y - round(height / 2) , T.z) diff --git a/code/modules/mapping/reader.dm b/code/modules/mapping/reader.dm index a83b502eb0c..f52208b7ece 100644 --- a/code/modules/mapping/reader.dm +++ b/code/modules/mapping/reader.dm @@ -140,6 +140,7 @@ GLOBAL_DATUM_INIT(_preloader, /dmm_suite/preloader, new) else world.maxz = zcrd //create a new z_level if needed SEND_GLOBAL_SIGNAL(COMSIG_GLOB_NEW_Z, world.maxz) + SSzcopy.calculate_zstack_limits() if(!no_changeturf) WARNING("Z-level expansion occurred without no_changeturf set, this may cause problems when /turf/post_change is called.") diff --git a/code/modules/mapping/space_management/zlevel_manager.dm b/code/modules/mapping/space_management/zlevel_manager.dm index d9c2d797106..f813d2c4ed8 100644 --- a/code/modules/mapping/space_management/zlevel_manager.dm +++ b/code/modules/mapping/space_management/zlevel_manager.dm @@ -13,6 +13,7 @@ generate_linkages_for_z_level(new_z) adding_new_zlevel = FALSE SEND_GLOBAL_SIGNAL(COMSIG_GLOB_NEW_Z, S) + SSzcopy.calculate_zstack_limits() return S /datum/controller/subsystem/mapping/proc/get_level(z) diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index b6f61c4c5a1..3c0a2159c27 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -549,7 +549,6 @@ light_power = 1 light_range = 6 - light_wedge = LIGHT_WIDE light_color = LIGHT_COLOR_FIRE /obj/vehicle/train/cargo/engine/mining/Initialize() @@ -601,7 +600,6 @@ light_power = 1 light_range = 3 - light_wedge = LIGHT_OMNI light_color = LIGHT_COLOR_FIRE /obj/item/key/minecarts diff --git a/code/modules/mining/mine_turf_types.dm b/code/modules/mining/mine_turf_types.dm index c6684439104..9df91fea42c 100644 --- a/code/modules/mining/mine_turf_types.dm +++ b/code/modules/mining/mine_turf_types.dm @@ -107,7 +107,7 @@ /turf/simulated/floor/exoplanet/basalt/cave/Initialize() // to make these tiles dark even on daytime exoplanets . = ..() - set_light(0, 1, null) + set_light(0) footprint_color = null update_icon(1) diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index 01db9e9be79..4d943feeb4e 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -76,12 +76,16 @@ GLOBAL_LIST_INIT(mineral_can_smooth_with, list( if(is_station_level(z)) GLOB.station_turfs += src - if(dynamic_lighting) - luminosity = 0 - else - luminosity = 1 + if (light_range && light_power) + update_light() - has_opaque_atom = TRUE + //Get area light + var/area/current_area = loc + if(current_area?.lighting_effect) + overlays += current_area.lighting_effect + + if(opacity) + directional_opacity = ALL_CARDINALS if(smoothing_flags) canSmoothWith = GLOB.mineral_can_smooth_with @@ -210,12 +214,16 @@ GLOBAL_LIST_INIT(mineral_can_smooth_with, list( if(is_station_level(z)) GLOB.station_turfs += src - if(dynamic_lighting) - luminosity = 0 - else - luminosity = 1 + if (light_range && light_power) + update_light() - has_opaque_atom = TRUE + //Get area light + var/area/current_area = loc + if(current_area?.lighting_effect) + overlays += current_area.lighting_effect + + if(opacity) + directional_opacity = ALL_CARDINALS if(smoothing_flags) canSmoothWith = asteroid_can_smooth_with @@ -753,14 +761,6 @@ GLOBAL_LIST_INIT(asteroid_floor_smooth, list( if(is_station_level(z)) GLOB.station_turfs += src - if(dynamic_lighting) - luminosity = 0 - else - luminosity = 1 - - if(mapload && permit_ao) - queue_ao() - if(smoothing_flags) canSmoothWith = GLOB.asteroid_floor_smooth pixel_x = -4 @@ -769,6 +769,11 @@ GLOBAL_LIST_INIT(asteroid_floor_smooth, list( if(light_range && light_power) update_light() + //Get area light + var/area/current_area = loc + if(current_area?.lighting_effect) + overlays += current_area.lighting_effect + return INITIALIZE_HINT_NORMAL /turf/simulated/floor/exoplanet/asteroid/ex_act(severity) @@ -926,7 +931,7 @@ GLOBAL_LIST_INIT(asteroid_floor_smooth, list( return /turf/simulated/floor/exoplanet/asteroid/proc/gets_dug(mob/user) - AddOverlays("asteroid_dug", TRUE) + AddOverlays("asteroid_dug") if(prob(75)) new /obj/item/ore/glass(src) @@ -980,7 +985,7 @@ GLOBAL_LIST_INIT(asteroid_floor_smooth, list( if(dug <= 10) dug += 1 - AddOverlays("asteroid_dug", TRUE) + AddOverlays("asteroid_dug") else var/turf/below = GET_TURF_BELOW(src) if(below) diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm index d3c86706839..318a4a1567d 100644 --- a/code/modules/mining/minebot.dm +++ b/code/modules/mining/minebot.dm @@ -132,7 +132,7 @@ /mob/living/silicon/robot/drone/mining/update_robot_light() if(lights_on) - set_light(5, 1, LIGHT_COLOR_FIRE, angle = LIGHT_OMNI) + set_light(5, 1, LIGHT_COLOR_FIRE) else set_light(0) diff --git a/code/modules/mob/abstract/freelook/eye.dm b/code/modules/mob/abstract/freelook/eye.dm index 27a9cd9b755..fa18f23cfa5 100644 --- a/code/modules/mob/abstract/freelook/eye.dm +++ b/code/modules/mob/abstract/freelook/eye.dm @@ -22,7 +22,6 @@ var/mob/owner = null var/list/visibleChunks = list() - var/ghostimage = null var/datum/visualnet/visualnet ///Set if the eye uses special click handling. Distinct from parent mob click handling for AI eye. var/click_handler_type = /datum/click_handler/eye @@ -30,21 +29,7 @@ ///Whether or not our eye uses normal living vision handling var/living_eye = TRUE -/mob/abstract/eye/New() - ghostimage = image(src.icon,src,src.icon_state) - SSmobs.ghost_darkness_images |= ghostimage //so ghosts can see the eye when they disable darkness - SSmobs.ghost_sightless_images |= ghostimage //so ghosts can see the eye when they disable ghost sight - updateallghostimages() - ..() - /mob/abstract/eye/Destroy() - if (ghostimage) - SSmobs.ghost_darkness_images -= ghostimage - SSmobs.ghost_sightless_images -= ghostimage - qdel(ghostimage) - ghostimage = null - updateallghostimages() - release(owner) owner = null visualnet = null diff --git a/code/modules/mob/abstract/ghost/ghost.dm b/code/modules/mob/abstract/ghost/ghost.dm index d0162ea6937..39c9b2ec8f2 100644 --- a/code/modules/mob/abstract/ghost/ghost.dm +++ b/code/modules/mob/abstract/ghost/ghost.dm @@ -1,10 +1,8 @@ /mob/abstract/ghost stat = DEAD - /// Toggle darkness. - var/see_darkness = FALSE /// Is the ghost able to see things humans can't? - var/ghostvision = FALSE + var/ghostvision = TRUE /// This variable generally controls whether a ghost has restrictions on where it can go or not (ex. if the ghost can bypass holy places). var/has_ghost_restrictions = TRUE /// If the ghost has antagHUD. @@ -56,17 +54,22 @@ set name = "Toggle Darkness" set category = "Ghost" - see_darkness = !see_darkness - update_sight() - -/mob/abstract/ghost/proc/update_sight() - set_sight(sight|SEE_TURFS|SEE_MOBS|SEE_OBJS) - set_see_invisible(SEE_INVISIBLE_LEVEL_TWO) - - if (!see_darkness) - set_see_invisible(SEE_INVISIBLE_NOLIGHTING) - else - set_see_invisible(ghostvision ? SEE_INVISIBLE_OBSERVER : SEE_INVISIBLE_LIVING) + var/level_message + switch(lighting_alpha) + if(LIGHTING_PLANE_ALPHA_VISIBLE) + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE + level_message = "half night vision" + if(LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE) + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + level_message = "three quarters night vision" + if(LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE) + lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE + level_message = "full night vision" + if(LIGHTING_PLANE_ALPHA_INVISIBLE) + lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE + level_message = "no night vision" + to_chat(src, SPAN_NOTICE("Night vision mode switched and saved to [level_message].")) + sync_lighting_plane_alpha() /mob/abstract/ghost/verb/toggle_ghostsee() set name = "Toggle Ghost Vision" @@ -152,6 +155,20 @@ to_chat(src, SPAN_NOTICE("Now following \the [target].")) update_sight() +/mob/abstract/ghost/proc/update_sight() + //if they are on a restricted level, then set the ghost vision for them. + if(on_restricted_level()) + //On the restricted level they have the same sight as the mob + set_sight(sight&(~SEE_TURFS)&(~SEE_MOBS)&(~SEE_OBJS)) + else + //Outside of the restrcited level, they have enhanced vision + set_sight(sight|SEE_TURFS|SEE_MOBS|SEE_OBJS) + + if(ghostvision) + set_see_invisible(SEE_INVISIBLE_OBSERVER) //overmap viewing breaks if this is lower + else + set_see_invisible(SEE_INVISIBLE_LIVING) + /mob/abstract/ghost/proc/on_restricted_level(var/check) if(!check) check = z diff --git a/code/modules/mob/abstract/ghost/observer/login.dm b/code/modules/mob/abstract/ghost/observer/login.dm deleted file mode 100644 index 7bbc25e8d36..00000000000 --- a/code/modules/mob/abstract/ghost/observer/login.dm +++ /dev/null @@ -1,5 +0,0 @@ -/mob/abstract/ghost/observer/LateLogin() - ..() - if (ghostimage) - ghostimage.icon_state = src.icon_state - updateghostimages() diff --git a/code/modules/mob/abstract/ghost/observer/observer.dm b/code/modules/mob/abstract/ghost/observer/observer.dm index aadc4fdd5ab..a360afa2762 100644 --- a/code/modules/mob/abstract/ghost/observer/observer.dm +++ b/code/modules/mob/abstract/ghost/observer/observer.dm @@ -8,6 +8,7 @@ blinded = FALSE anchored = TRUE // don't get pushed around invisibility = INVISIBILITY_OBSERVER + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE simulated = FALSE universal_speak = TRUE incorporeal_move = INCORPOREAL_GHOST @@ -28,8 +29,6 @@ var/admin_ghosted = 0 /// If this ghost has enabled chat anonymization. var/anonsay = 0 - /// This mob's ghost image, for deleting and stuff. - var/image/ghostimage /// If the ghost can be seen through cult shenanigans. var/is_manifest = 0 /// Cooldown for ghost abilities, such as move_item(). @@ -42,10 +41,6 @@ set_stat(DEAD) - ghostimage = image(icon, src, icon_state) - SSmobs.ghost_darkness_images |= ghostimage - updateallghostimages() - var/turf/T if (ismob(body)) T = get_turf(body) //Where is the body located? @@ -54,6 +49,7 @@ var/originaldesc = desc var/o_transform = transform set_appearance(body) + underlays.Cut() appearance_flags = KEEP_TOGETHER desc = originaldesc transform = o_transform @@ -88,15 +84,6 @@ name = capitalize(pick(GLOB.first_names_male)) + " " + capitalize(pick(GLOB.last_names)) real_name = name -/mob/abstract/ghost/observer/Destroy() - if (ghostimage) - SSmobs.ghost_darkness_images -= ghostimage - qdel(ghostimage) - ghostimage = null - updateallghostimages() - - return ..() - /mob/abstract/ghost/observer/proc/initialise_postkey(set_timers = TRUE) //This function should be run after a ghost has been created and had a ckey assigned if (!set_timers) @@ -574,47 +561,12 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/abstract/ghost/observer/can_admin_interact() return check_rights(R_ADMIN, 0, src) -/mob/abstract/ghost/observer/update_sight() - //if they are on a restricted level, then set the ghost vision for them. - if(on_restricted_level()) - //On the restricted level they have the same sight as the mob - set_sight(sight&(~SEE_TURFS)&(~SEE_MOBS)&(~SEE_OBJS)) - set_see_invisible(SEE_INVISIBLE_OBSERVER) - else - //Outside of the restrcited level, they have enhanced vision - set_sight(sight|SEE_TURFS|SEE_MOBS|SEE_OBJS) - set_see_invisible(SEE_INVISIBLE_LEVEL_TWO) - - if (!see_darkness) - set_see_invisible(SEE_INVISIBLE_NOLIGHTING) - else - set_see_invisible(ghostvision ? SEE_INVISIBLE_OBSERVER : SEE_INVISIBLE_LIVING) - - updateghostimages() - -/proc/updateallghostimages() - for (var/mob/abstract/ghost/observer/O in GLOB.player_list) - O.updateghostimages() - -/mob/abstract/ghost/observer/proc/updateghostimages() - if (!client) - return - if (see_darkness || !ghostvision) - client.images -= SSmobs.ghost_darkness_images - client.images |= SSmobs.ghost_sightless_images - else - //add images for the 60inv things ghosts can normally see when darkness is enabled so they can see them now - client.images -= SSmobs.ghost_sightless_images - client.images |= SSmobs.ghost_darkness_images - if (ghostimage) - client.images -= ghostimage //remove ourself - /** * We use this proc to set appearance because doing so resets the plane. * We want the plane to stay at GHOST_PLANE to avoid weird overlaying stuff. */ -/mob/abstract/ghost/observer/proc/set_appearance(new_appearance) - appearance = new_appearance +/mob/abstract/ghost/observer/proc/set_appearance(mob/body) + appearance = body.appearance plane = GHOST_PLANE /mob/abstract/ghost/observer/MayRespawn(var/feedback = 0, var/respawn_type = null) diff --git a/code/modules/mob/living/carbon/diona_base.dm b/code/modules/mob/living/carbon/diona_base.dm index 687b3dbf5c5..961ec4504a6 100644 --- a/code/modules/mob/living/carbon/diona_base.dm +++ b/code/modules/mob/living/carbon/diona_base.dm @@ -493,7 +493,7 @@ Lightstates: light_factor = 1 if (T) - var/raw = min(T.get_uv_lumcount(0, 2) * light_factor * 5.5, 5.5) + var/raw = min(T.get_lumcount(0, 1) * light_factor * 5.5, 5.5) return raw - 1.5 /// Getter for health. diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 28f7351f405..2652b8724bb 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1553,6 +1553,8 @@ nutrition_loss = HUNGER_FACTOR * species.nutrition_loss_factor hydration_loss = THIRST_FACTOR * species.hydration_loss_factor + default_lighting_alpha = species.default_lighting_alpha + speech_bubble_type = species.possible_speech_bubble_types[1] if(typing_indicator) adjust_typing_indicator_offsets(typing_indicator) diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index c1d96fd77a7..301b443944c 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -1,4 +1,5 @@ /mob/living/carbon/human + light_system = MOVABLE_LIGHT blocks_emissive = EMISSIVE_BLOCK_NONE @@ -39,6 +40,8 @@ var/damage_multiplier = 1 //multiplies melee combat damage var/icon_update = 1 //whether icon updating shall take place + var/default_lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE + var/lipstick_color = null //no lipstick by default var/age = 30 //Player's age (pure fluff) diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index 4cd32138245..8a42240dcbd 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -79,7 +79,9 @@ equipment_prescription = equipment_prescription || G.prescription if(G.overlay) equipment_overlays |= G.overlay - if(G.see_invisible >= 0) + if(G.lighting_alpha != lighting_alpha) + lighting_alpha = G.lighting_alpha + if(G.see_invisible) if(equipment_see_invis) equipment_see_invis = min(equipment_see_invis, G.see_invisible) else diff --git a/code/modules/mob/living/carbon/human/human_powers.dm b/code/modules/mob/living/carbon/human/human_powers.dm index 2eb7f87c842..61620471722 100644 --- a/code/modules/mob/living/carbon/human/human_powers.dm +++ b/code/modules/mob/living/carbon/human/human_powers.dm @@ -672,7 +672,7 @@ if (!stop_sight_update) to_chat(src, SPAN_NOTICE("Your eyes shift around, allowing you to see in the dark.")) src.stop_sight_update = 1 - src.see_invisible = SEE_INVISIBLE_NOLIGHTING + src.lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE else to_chat(src, SPAN_NOTICE("You return your vision to normal.")) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 0b983e4ea2f..25c8e47c522 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -1497,6 +1497,7 @@ return if((mutations & XRAY)) set_sight(sight|SEE_TURFS|SEE_MOBS|SEE_OBJS) + lighting_alpha = default_lighting_alpha /** * This proc assumes that if shock_value = null, then a shock value was NOT passed in, and thus it calculates it itself. diff --git a/code/modules/mob/living/carbon/human/species/outsider/revenant.dm b/code/modules/mob/living/carbon/human/species/outsider/revenant.dm index 4f5da19aed0..b0b020a15e5 100644 --- a/code/modules/mob/living/carbon/human/species/outsider/revenant.dm +++ b/code/modules/mob/living/carbon/human/species/outsider/revenant.dm @@ -61,6 +61,7 @@ spawn_flags = IS_RESTRICTED vision_flags = DEFAULT_SIGHT | SEE_MOBS + default_lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE has_organ = list( BP_EYES = /obj/item/organ/internal/eyes/night/revenant diff --git a/code/modules/mob/living/carbon/human/species/outsider/undead.dm b/code/modules/mob/living/carbon/human/species/outsider/undead.dm index b6e583af2f0..9896f9ae2e9 100644 --- a/code/modules/mob/living/carbon/human/species/outsider/undead.dm +++ b/code/modules/mob/living/carbon/human/species/outsider/undead.dm @@ -198,6 +198,7 @@ slowdown = 1 vision_flags = DEFAULT_SIGHT + default_lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE reagent_tag = IS_UNDEAD diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 6d4c1e9ad1b..ff9882e1af8 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -450,6 +450,8 @@ var/snore_key = "snore" /// Whether this species can choose to sleep indefinitely var/indefinite_sleep = FALSE + /// The default lighting alpha of this species. Override to set innate NVGs. + var/default_lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE /datum/species/proc/get_eyes(var/mob/living/carbon/human/H) return @@ -736,7 +738,8 @@ var/obj/item/organ/internal/eyes/night/NE = H.get_eyes() if(istype(NE) && NE.night_vision && NE.can_change_invisible()) - H.set_see_invisible(SEE_INVISIBLE_NOLIGHTING) + H.lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE + H.update_sight() return 1 diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index e328c6ea64f..1bc2562975e 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -516,7 +516,7 @@ There are several things that need to be remembered: var/datum/sprite_accessory/hair_style = GLOB.hair_styles_list[h_style] if (hair_style) var/col = species.get_light_color(src) || "#FFFFFF" - set_light(species.light_range, species.light_power, col, uv = 0, angle = LIGHT_WIDE) + set_light(species.light_range, species.light_power, col) else set_light(0) @@ -1509,6 +1509,11 @@ There are several things that need to be remembered: if(QDELETED(src)) return + if(!on_fire) + set_light_on(FALSE) + else + set_light_on(TRUE) + var/image/fire_image_lower = on_fire ? image(species.onfire_overlay, "lower", layer = FIRE_LAYER_LOWER) : null var/image/fire_image_upper = on_fire ? image(species.onfire_overlay, "upper", layer = FIRE_LAYER_UPPER) : null diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 1660485bd97..d0f69bde4c1 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -173,6 +173,7 @@ var/list/vision = get_accumulated_vision_handlers() set_sight(sight | vision[1]) set_see_invisible(max(vision[2], see_invisible)) + sync_lighting_plane_alpha() /mob/living/proc/update_living_sight() var/set_sight_flags = is_ventcrawling ? (SEE_TURFS) : sight & ~(SEE_TURFS|SEE_MOBS|SEE_OBJS) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 3ce068fc9ea..53806ec14c9 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -113,7 +113,6 @@ light_power = 0 light_range = 4 light_color = COLOR_BRIGHT_GREEN - light_wedge = 45 /mob/living/silicon/pai/movement_delay() return 0.8 @@ -140,21 +139,21 @@ /mob/living/silicon/pai/proc/toggle_flashlight() flashlight_active = !flashlight_active if(flashlight_active) - set_light(4, 1, COLOR_BRIGHT_GREEN, angle = 45) + set_light(4, 1, COLOR_BRIGHT_GREEN) else set_light(0) -/mob/living/silicon/pai/set_light(l_range, l_power, l_color, uv, angle, no_update) +/mob/living/silicon/pai/set_light(l_range, l_power, l_color) ..() if(istype(loc, /obj/item/holder/pai)) var/obj/item/holder/pai/P = loc - P.set_light(l_range, l_power, l_color, uv, angle, no_update) + P.set_light(l_range, l_power, l_color) /mob/living/silicon/pai/post_scoop() ..() if(istype(loc, /obj/item/holder/pai)) var/obj/item/holder/pai/P = loc - P.set_light(light_range, light_power, light_color, uv_intensity, light_wedge) + P.set_light(light_range, light_power, light_color) /mob/living/silicon/pai/Initialize(mapload) var/obj/item/device/paicard/paicard = loc diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm index 1c070db78b3..7d6113b5b84 100644 --- a/code/modules/mob/living/silicon/robot/life.dm +++ b/code/modules/mob/living/silicon/robot/life.dm @@ -154,10 +154,10 @@ set_see_invisible(SEE_INVISIBLE_LEVEL_TWO) else if((sight_mode & BORGMESON) && (sight_mode & BORGTHERM)) set_sight(sight|SEE_TURFS|SEE_MOBS) - set_see_invisible(SEE_INVISIBLE_NOLIGHTING) + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE else if(sight_mode & BORGMESON) set_sight(sight|SEE_TURFS) - set_see_invisible(SEE_INVISIBLE_NOLIGHTING) + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE else if(sight_mode & BORGMATERIAL) set_sight(sight|SEE_OBJS) else if(sight_mode & BORGTHERM) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 608b737f638..4d0b9bb0bfc 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -34,7 +34,6 @@ var/speed = 0 // Lighting and sight - light_wedge = LIGHT_WIDE var/lights_on = FALSE // Is our integrated light on? var/intense_light = FALSE // Whether cyborg's integrated light was upgraded var/sight_mode = NO_HUD diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 95b2ff3c750..46c9a136989 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -53,7 +53,6 @@ var/can_hear_hivenet = TRUE // Misc - uv_intensity = 175 //Lights cast by robots have reduced effect on diona mob_thinks = FALSE var/can_speak_basic = TRUE diff --git a/code/modules/mob/living/simple_animal/friendly/cosmozoan.dm b/code/modules/mob/living/simple_animal/friendly/cosmozoan.dm index c028b97b3cb..71a80211459 100644 --- a/code/modules/mob/living/simple_animal/friendly/cosmozoan.dm +++ b/code/modules/mob/living/simple_animal/friendly/cosmozoan.dm @@ -31,7 +31,7 @@ minbodytemp = 0 flying = TRUE - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE sample_data = list("Cellular biochemistry include bioluminescent reactions", "Tissue sample contains micro-gas release structures") /mob/living/simple_animal/cosmozoan/Initialize() diff --git a/code/modules/mob/living/simple_animal/friendly/ratking.dm b/code/modules/mob/living/simple_animal/friendly/ratking.dm index bebb36362e0..4714ba0016f 100644 --- a/code/modules/mob/living/simple_animal/friendly/ratking.dm +++ b/code/modules/mob/living/simple_animal/friendly/ratking.dm @@ -21,7 +21,7 @@ icon_dead = "rat_gray_dead" icon_rest = "rat_gray_sleep" - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE var/swarm_name = "peasentry" var/announce_name = "Request" diff --git a/code/modules/mob/living/simple_animal/hostile/adhomai.dm b/code/modules/mob/living/simple_animal/hostile/adhomai.dm index 0557cd92897..dafedd145cf 100644 --- a/code/modules/mob/living/simple_animal/hostile/adhomai.dm +++ b/code/modules/mob/living/simple_animal/hostile/adhomai.dm @@ -101,7 +101,7 @@ environment_smash = 1 attack_emote = "wiggles toward" - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE blood_type = "#281C2D" @@ -131,7 +131,7 @@ mob_size = 5 attack_emote = "hums at" - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE smart_ranged = TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/bat.dm b/code/modules/mob/living/simple_animal/hostile/bat.dm index 8749a22d2fe..cc7b213a78a 100644 --- a/code/modules/mob/living/simple_animal/hostile/bat.dm +++ b/code/modules/mob/living/simple_animal/hostile/bat.dm @@ -79,7 +79,3 @@ /mob/living/simple_animal/hostile/scarybat/cult/cultify() return - -/mob/living/simple_animal/hostile/scarybat/cult/Life(seconds_per_tick, times_fired) - ..() - check_horde() diff --git a/code/modules/mob/living/simple_animal/hostile/cavern_geist.dm b/code/modules/mob/living/simple_animal/hostile/cavern_geist.dm index e44baeca4b2..168123e81cf 100644 --- a/code/modules/mob/living/simple_animal/hostile/cavern_geist.dm +++ b/code/modules/mob/living/simple_animal/hostile/cavern_geist.dm @@ -33,7 +33,7 @@ attacktext = "mangled" attack_sound = 'sound/weapons/bloodyslice.ogg' - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE pixel_x = -16 speed = -1 diff --git a/code/modules/mob/living/simple_animal/hostile/changeling.dm b/code/modules/mob/living/simple_animal/hostile/changeling.dm index f51f2a63704..adcd2b33365 100644 --- a/code/modules/mob/living/simple_animal/hostile/changeling.dm +++ b/code/modules/mob/living/simple_animal/hostile/changeling.dm @@ -37,7 +37,7 @@ attack_sound = 'sound/weapons/bloodyslice.ogg' emote_sounds = list('sound/effects/creatures/bear_loud_1.ogg', 'sound/effects/creatures/bear_loud_2.ogg', 'sound/effects/creatures/bear_loud_3.ogg', 'sound/effects/creatures/bear_loud_4.ogg') - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE minbodytemp = 0 maxbodytemp = 350 @@ -166,7 +166,7 @@ attacktext = "mangled" attack_sound = 'sound/weapons/bloodyslice.ogg' - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE pass_flags = PASSTABLE diff --git a/code/modules/mob/living/simple_animal/hostile/creature.dm b/code/modules/mob/living/simple_animal/hostile/creature.dm index 783cd5823bd..20f6ff6ebc5 100644 --- a/code/modules/mob/living/simple_animal/hostile/creature.dm +++ b/code/modules/mob/living/simple_animal/hostile/creature.dm @@ -37,6 +37,3 @@ /mob/living/simple_animal/hostile/creature/cult/cultify() return -/mob/living/simple_animal/hostile/creature/cult/Life(seconds_per_tick, times_fired) - ..() - check_horde() diff --git a/code/modules/mob/living/simple_animal/hostile/faithless.dm b/code/modules/mob/living/simple_animal/hostile/faithless.dm index 59984542d04..90a58866544 100644 --- a/code/modules/mob/living/simple_animal/hostile/faithless.dm +++ b/code/modules/mob/living/simple_animal/hostile/faithless.dm @@ -64,10 +64,6 @@ /mob/living/simple_animal/hostile/faithless/cult/cultify() return -/mob/living/simple_animal/hostile/faithless/cult/Life(seconds_per_tick, times_fired) - ..() - check_horde() - /mob/living/simple_animal/hostile/faithless/can_fall() return FALSE diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 1a4f8c8563e..d6e07302eec 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -520,42 +520,6 @@ ABSTRACT_TYPE(/mob/living/simple_animal/hostile) return UnarmedAttack(target, TRUE) return ..() -/mob/living/simple_animal/hostile/proc/check_horde() - if(GLOB.evacuation_controller.is_prepared()) - if(!enroute && !last_found_target) //The shuttle docked, all monsters rush for the escape hallway - if(!shuttletarget && GLOB.escape_list.len) //Make sure we didn't already assign it a target, and that there are targets to pick - shuttletarget = pick(GLOB.escape_list) //Pick a shuttle target - enroute = 1 - stop_automated_movement = 1 - if(!src.stat) - horde() - - if(get_dist(src, shuttletarget) <= 2) //The monster reached the escape hallway - enroute = 0 - stop_automated_movement = 0 - -/mob/living/simple_animal/hostile/proc/horde() - var/turf/T = get_step_to(src, shuttletarget) - for(var/atom/A in T) - if(istype(A,/obj/machinery/door/airlock)) - var/obj/machinery/door/airlock/D = A - D.open(1) - else if(istype(A,/obj/structure/simple_door)) - var/obj/structure/simple_door/D = A - if(D.density) - D.Open() - else if(istype(A,/obj/structure/cult/pylon)) - A.attack_generic(src, rand(melee_damage_lower, melee_damage_upper)) - else if(istype(A, /obj/structure/window) || istype(A, /obj/structure/closet) || istype(A, /obj/structure/table) || istype(A, /obj/structure/grille)) - A.attack_generic(src, rand(melee_damage_lower, melee_damage_upper)) - Move(T) - var/atom/target = FindTarget() - if(istype(target) && !QDELETED(target)) - set_last_found_target(target) - if(!last_found_target || enroute) - if(!src.stat) - horde() - ////////////////////////////// ///////VALIDATOR PROCS//////// ////////////////////////////// diff --git a/code/modules/mob/living/simple_animal/hostile/icarus_drone.dm b/code/modules/mob/living/simple_animal/hostile/icarus_drone.dm index bfd6f141d1e..e7ec42a57c5 100644 --- a/code/modules/mob/living/simple_animal/hostile/icarus_drone.dm +++ b/code/modules/mob/living/simple_animal/hostile/icarus_drone.dm @@ -56,7 +56,7 @@ tameable = FALSE flying = TRUE - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE psi_pingable = FALSE sample_data = null diff --git a/code/modules/mob/living/simple_animal/hostile/ipc_zombie.dm b/code/modules/mob/living/simple_animal/hostile/ipc_zombie.dm index 4e3c5a9d9e9..ec911058fc0 100644 --- a/code/modules/mob/living/simple_animal/hostile/ipc_zombie.dm +++ b/code/modules/mob/living/simple_animal/hostile/ipc_zombie.dm @@ -41,9 +41,6 @@ ///Overlay of a screen to display on the zombie's monitor var/image/screen_overlay - ///Emissive overlay of above - var/image/emissive_overlay - ///IPC corpse to spawn on the simplemob's death var/corpse = /obj/effect/landmark/corpse/ipc_zombie diff --git a/code/modules/mob/living/simple_animal/hostile/krampus.dm b/code/modules/mob/living/simple_animal/hostile/krampus.dm index 0117abe17ca..208e0b17131 100644 --- a/code/modules/mob/living/simple_animal/hostile/krampus.dm +++ b/code/modules/mob/living/simple_animal/hostile/krampus.dm @@ -30,7 +30,7 @@ attacktext = "punished" attack_sound = 'sound/weapons/bladeslice.ogg' - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE minbodytemp = 0 maxbodytemp = 350 diff --git a/code/modules/mob/living/simple_animal/hostile/moghes.dm b/code/modules/mob/living/simple_animal/hostile/moghes.dm index cd57c5e0fea..a88c5558c55 100644 --- a/code/modules/mob/living/simple_animal/hostile/moghes.dm +++ b/code/modules/mob/living/simple_animal/hostile/moghes.dm @@ -31,7 +31,7 @@ attacktext = "chomped" attack_sound = 'sound/weapons/bloodyslice.ogg' - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE faction = "Moghes" butchering_products = list(/obj/item/stack/material/animalhide/lizard = 20) diff --git a/code/modules/mob/living/simple_animal/hostile/morph.dm b/code/modules/mob/living/simple_animal/hostile/morph.dm index 11db0c0af39..512237860b2 100644 --- a/code/modules/mob/living/simple_animal/hostile/morph.dm +++ b/code/modules/mob/living/simple_animal/hostile/morph.dm @@ -32,7 +32,7 @@ melee_damage_lower = 12 melee_damage_upper = 16 - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE stop_sight_update = TRUE minbodytemp = 0 @@ -95,10 +95,10 @@ set desc = "Toggles whether you see light or not." set category = "Abilities" - if(see_invisible == SEE_INVISIBLE_NOLIGHTING) - see_invisible = SEE_INVISIBLE_LIVING + if(lighting_alpha == LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE) + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE else - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE /mob/living/simple_animal/hostile/morph/examine(mob/user, distance, is_adjacent, infix, suffix, show_extended) if(morphed) diff --git a/code/modules/mob/living/simple_animal/hostile/phoron_worm.dm b/code/modules/mob/living/simple_animal/hostile/phoron_worm.dm index 18d67639116..28e7fcf4e18 100644 --- a/code/modules/mob/living/simple_animal/hostile/phoron_worm.dm +++ b/code/modules/mob/living/simple_animal/hostile/phoron_worm.dm @@ -31,7 +31,7 @@ mob_swap_flags = HUMAN|SIMPLE_ANIMAL|SLIME|MONKEY mob_push_flags = ALLMOBS - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE minbodytemp = 0 maxbodytemp = 350 diff --git a/code/modules/mob/living/simple_animal/hostile/pra.dm b/code/modules/mob/living/simple_animal/hostile/pra.dm index 27822a1c937..46022240be0 100644 --- a/code/modules/mob/living/simple_animal/hostile/pra.dm +++ b/code/modules/mob/living/simple_animal/hostile/pra.dm @@ -195,7 +195,7 @@ tameable = FALSE flying = TRUE - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE emote_sounds = list('sound/effects/creatures/PRA_drone.ogg') diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/cavern.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/cavern.dm index ad99e686a85..f272c63c2b9 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/cavern.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/cavern.dm @@ -45,7 +45,7 @@ faction = "cavern" flying = TRUE - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE /mob/living/simple_animal/hostile/retaliate/cavern_dweller/Allow_Spacemove(var/check_drift = 0) return 1 @@ -110,7 +110,6 @@ max_n2 = 0 minbodytemp = 0 light_range = 10 - light_wedge = LIGHT_WIDE psi_pingable = FALSE faction = "sol" diff --git a/code/modules/mob/living/simple_animal/hostile/sarlacc.dm b/code/modules/mob/living/simple_animal/hostile/sarlacc.dm index ae27fcef94c..74c3627dcec 100644 --- a/code/modules/mob/living/simple_animal/hostile/sarlacc.dm +++ b/code/modules/mob/living/simple_animal/hostile/sarlacc.dm @@ -316,7 +316,7 @@ desc = "This pulsating brain seems somehow connected to all the other orifices in this room..." icon = 'icons/mob/npc/cavern.dmi' icon_state = "sarlaccbrain" - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE universal_speak = 1 universal_understand = 1 diff --git a/code/modules/mob/living/simple_animal/hostile/space_fauna.dm b/code/modules/mob/living/simple_animal/hostile/space_fauna.dm index 7fdc843352f..e05265e87eb 100644 --- a/code/modules/mob/living/simple_animal/hostile/space_fauna.dm +++ b/code/modules/mob/living/simple_animal/hostile/space_fauna.dm @@ -53,7 +53,7 @@ attack_emote = "nashes at" flying = TRUE - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE smart_melee = FALSE sample_data = list("Cellular structure shows adaptation for survival in vacuum", "Genetic biomarkers identified linked with agressiveness", "Tissue sample contains micro-gas release structures") @@ -307,5 +307,5 @@ attack_emote = "nashes at" flying = TRUE - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE sample_data = list("Cellular structure shows adaptation for survival in vacuum", "Genetic biomarkers identified linked with agressiveness", "Tissue sample contains micro-gas release structures") diff --git a/code/modules/mob/living/simple_animal/hostile/spider_queen.dm b/code/modules/mob/living/simple_animal/hostile/spider_queen.dm index b18a752db6f..ecad360d847 100644 --- a/code/modules/mob/living/simple_animal/hostile/spider_queen.dm +++ b/code/modules/mob/living/simple_animal/hostile/spider_queen.dm @@ -13,7 +13,7 @@ emote_hear = list("chitters") speak_chance = 5 turns_per_move = 5 - see_invisible = SEE_INVISIBLE_NOLIGHTING + lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE meat_type = /obj/item/reagent_containers/food/snacks/xenomeat organ_names = list("thorax", "legs", "head") response_help = "pets" diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index cd7de8d61d6..93a78353f8f 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1574,15 +1574,15 @@ // if(thing.item_flags & SLOWS_WHILE_IN_HAND) . += thing -/mob/proc/check_emissive_equipment() - var/old_zflags = z_flags - z_flags &= ~ZMM_MANGLE_PLANES - for(var/atom/movable/AM in get_equipped_items(INCLUDE_POCKETS|INCLUDE_HELD)) - if(AM.z_flags & ZMM_MANGLE_PLANES) - z_flags |= ZMM_MANGLE_PLANES - break - if(old_zflags != z_flags) - UPDATE_OO_IF_PRESENT +///Set the lighting plane hud alpha to the mobs lighting_alpha var +/mob/proc/sync_lighting_plane_alpha() + if(hud_used) + var/atom/movable/screen/plane_master/lighting/lighting = hud_used.plane_masters["[LIGHTING_PLANE]"] + if (lighting) + lighting.alpha = lighting_alpha + var/atom/movable/screen/plane_master/lighting/exterior_lighting = hud_used.plane_masters["[EXTERIOR_LIGHTING_PLANE]"] + if (exterior_lighting) + exterior_lighting.alpha = min(GLOB.minimum_exterior_lighting_alpha, lighting_alpha) #undef UNBUCKLED #undef PARTIALLY_BUCKLED diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index f1208af42b9..b7ada2c1f4a 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -6,6 +6,8 @@ sight = DEFAULT_SIGHT blocks_emissive = EMISSIVE_BLOCK_GENERIC pass_flags_self = PASSMOB + // Determines what the alpha of the lighting is to this mob. + var/lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE var/datum/mind/mind var/static/next_mob_id = 0 diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 7f0ef278a8a..d29835b4a33 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -452,11 +452,6 @@ use_mob.forceMove(get_step(use_mob, direct)) use_mob.dir = direct - // Crossed is always a bit iffy - for(var/obj/S in use_mob.loc) - if(istype(S,/obj/effect/step_trigger) || istype(S,/obj/effect/beam)) - S.Crossed(use_mob) - var/area/A = get_area_master(use_mob) if(A) A.Entered(use_mob) diff --git a/code/modules/multiz/turfs/open_space.dm b/code/modules/multiz/turfs/open_space.dm index 464fe6817dd..8e7a4443e06 100644 --- a/code/modules/multiz/turfs/open_space.dm +++ b/code/modules/multiz/turfs/open_space.dm @@ -175,9 +175,10 @@ /turf/simulated/open/Initialize(mapload) . = ..() icon_state = "" // Clear out the debug icon. - + ADD_TRAIT(src, TURF_Z_TRANSPARENT_TRAIT, TRAIT_SOURCE_INHERENT) update(mapload) + /** * Updates the turf with open turf's variables and basically resets it properly. */ diff --git a/code/modules/multiz/zmimic/mimic_movable.dm b/code/modules/multiz/zmimic/mimic_movable.dm index 169ef9a5172..7b52e762cb4 100644 --- a/code/modules/multiz/zmimic/mimic_movable.dm +++ b/code/modules/multiz/zmimic/mimic_movable.dm @@ -74,47 +74,6 @@ return ..() -/atom/movable/openspace/multiplier/proc/copy_lighting(atom/movable/lighting_overlay/LO) - appearance = LO - layer = MIMICED_LIGHTING_LAYER - plane = OPEN_SPACE_PLANE_END - set_invisibility(0) - if (icon_state == null) - blend_mode = BLEND_MULTIPLY - // We're using a color matrix, so just darken the colors across the board. - // Bay stores lights as inverted so the lighting PM can invert it for darksight, but - // we don't have a plane master, so invert it again. - var/list/c_list = color - c_list[CL_MATRIX_RR] *= -SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_RG] *= -SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_RB] *= -SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_GR] *= -SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_GG] *= -SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_GB] *= -SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_BR] *= -SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_BG] *= -SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_BB] *= -SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_AR] *= -SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_AG] *= -SHADOWER_DARKENING_FACTOR - c_list[CL_MATRIX_AB] *= -SHADOWER_DARKENING_FACTOR - color = c_list - else - // Not a color matrix, so we just ignore the lighting values. - icon_state = "dark" // this is actually just a white sprite, which is what this blending needs - color = list( - SHADOWER_DARKENING_FACTOR, 0, 0, - 0, SHADOWER_DARKENING_FACTOR, 0, - 0, 0, SHADOWER_DARKENING_FACTOR - ) - - var/turf/parent = loc - ASSERT(isturf(parent)) - if (LAZYLEN(parent.ao_overlays_mimic)) - overlays += parent.ao_overlays_mimic - - if (bound_overlay) - update_above() - // -- OPENSPACE OVERLAY -- // todo: rename diff --git a/code/modules/organs/internal/species/tajara.dm b/code/modules/organs/internal/species/tajara.dm index 04e84b9d7d7..061fa190cab 100644 --- a/code/modules/organs/internal/species/tajara.dm +++ b/code/modules/organs/internal/species/tajara.dm @@ -93,13 +93,14 @@ night_vision = TRUE if(can_change_invisible()) - owner.set_see_invisible(SEE_INVISIBLE_NOLIGHTING) + owner.lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE if(status & ORGAN_ROBOT) if(vision_mechanical_color) owner.add_client_color(vision_mechanical_color) else if(vision_color) owner.add_client_color(vision_color) + owner.update_sight() /obj/item/organ/internal/eyes/night/proc/disable_night_vision() if(!owner) @@ -108,13 +109,14 @@ return night_vision = FALSE if(can_change_invisible()) - owner.set_see_invisible(SEE_INVISIBLE_LIVING) + owner.lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE if(status & ORGAN_ROBOT) if(vision_mechanical_color) owner.remove_client_color(vision_mechanical_color) else if(vision_color) owner.remove_client_color(vision_color) + owner.update_sight() /obj/item/organ/internal/stomach/tajara name = "reinforced stomach" diff --git a/code/modules/organs/subtypes/augment/augments/sight_lights.dm b/code/modules/organs/subtypes/augment/augments/sight_lights.dm index 7e203eef974..14c81fa9350 100644 --- a/code/modules/organs/subtypes/augment/augments/sight_lights.dm +++ b/code/modules/organs/subtypes/augment/augments/sight_lights.dm @@ -31,18 +31,19 @@ lights_on = !lights_on if(lights_on) - set_light(lights_range, lights_intensity, lights_color, uv = 0, angle = LIGHT_WIDE) + set_light_range_power_color(lights_range, lights_intensity, lights_color) + set_light_on(TRUE) else - set_light(0) + set_light_on(FALSE) /obj/item/organ/internal/augment/sightlights/emp_act(severity) . = ..() - set_light(0) + set_light_on(FALSE) /obj/item/organ/internal/augment/sightlights/take_damage(var/amount, var/silent = 0) . = ..() - set_light(0) + set_light_on(FALSE) /obj/item/organ/internal/augment/sightlights/take_internal_damage(var/amount, var/silent = 0) . = ..() - set_light(0) + set_light_on(FALSE) diff --git a/code/modules/organs/subtypes/autakh.dm b/code/modules/organs/subtypes/autakh.dm index d0e0e063228..203aeadc01a 100644 --- a/code/modules/organs/subtypes/autakh.dm +++ b/code/modules/organs/subtypes/autakh.dm @@ -226,7 +226,7 @@ return FALSE if(!online) - set_light(3, 2, LIGHT_COLOR_RED, uv = 0, angle = LIGHT_WIDE) + set_light(3, 2, LIGHT_COLOR_RED) owner.change_eye_color(250, 130, 130) owner.update_eyes() online = TRUE diff --git a/code/modules/organs/subtypes/parasite/black_kois.dm b/code/modules/organs/subtypes/parasite/black_kois.dm index 06fe25816b6..f99087dc451 100644 --- a/code/modules/organs/subtypes/parasite/black_kois.dm +++ b/code/modules/organs/subtypes/parasite/black_kois.dm @@ -84,8 +84,9 @@ owner.set_default_language(LANGUAGE_LIIDRA) removed_langs = TRUE - owner.set_see_invisible(SEE_INVISIBLE_NOLIGHTING) + owner.lighting_alpha = LIGHTING_PLANE_ALPHA_SOMEWHAT_INVISIBLE owner.add_client_color(/datum/client_color/vaurca) + owner.update_sight() if(prob(10)) if(owner.can_feel_pain()) diff --git a/code/modules/overmap/_defines.dm b/code/modules/overmap/_defines.dm index 2397936f9b7..4ddcf323a45 100644 --- a/code/modules/overmap/_defines.dm +++ b/code/modules/overmap/_defines.dm @@ -12,17 +12,16 @@ GLOBAL_LIST_EMPTY(map_sectors) /// to an instance of `/datum/map_template`. GLOBAL_LIST_EMPTY(map_templates) -/area/overmap/ +/area/overmap name = "System Map" icon_state = "start" requires_power = 0 base_turf = /turf/unsimulated/map - dynamic_lighting = 0 + base_lighting_alpha = 255 /turf/unsimulated/map icon = 'icons/obj/overmap/overmap.dmi' icon_state = "map" - permit_ao = FALSE /turf/unsimulated/map/edge opacity = 1 diff --git a/code/modules/overmap/exoplanets/decor/_turfs.dm b/code/modules/overmap/exoplanets/decor/_turfs.dm index caebf8f887e..3b0772ec47c 100644 --- a/code/modules/overmap/exoplanets/decor/_turfs.dm +++ b/code/modules/overmap/exoplanets/decor/_turfs.dm @@ -139,7 +139,6 @@ desc = "Government didn't want you to see this!" density = TRUE blocks_air = TRUE - dynamic_lighting = FALSE icon = null icon_state = null diff --git a/code/modules/overmap/exoplanets/themes/_theme.dm b/code/modules/overmap/exoplanets/themes/_theme.dm index e91f2166949..44ed9c82588 100644 --- a/code/modules/overmap/exoplanets/themes/_theme.dm +++ b/code/modules/overmap/exoplanets/themes/_theme.dm @@ -270,7 +270,7 @@ gen_turf.resources[ORE_SAND] = rand(3, 5) gen_turf.resources[ORE_COAL] = rand(3, 5) if(ground_resources_roll) - var/image/resource_indicator = image('icons/obj/mining.dmi', null, "indicator_" + ground_resources_roll, gen_turf.layer, pick(GLOB.cardinals)) + var/image/resource_indicator = image('icons/obj/mining.dmi', null, "indicator_" + ground_resources_roll, dir = pick(GLOB.cardinals)) resource_indicator.alpha = rand(30, 60) gen_turf.resource_indicator = resource_indicator if(!gen_turf.density) @@ -279,6 +279,12 @@ var/rand_vals = ground_ore_levels[ground_resources_roll][OT] gen_turf.resources[OT] = rand(rand_vals[1], rand_vals[2]) + if(SSlighting.initialized) //don't generate lighting overlays before SSlighting in case these templates are loaded before + var/area/A = gen_turf.loc + if(A?.area_has_base_lighting) + continue + gen_turf.static_lighting_build_overlay() + if(gen_turf.density) // No need to check flora/fauna/grass if we're a wall continue diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 7875ca2a1e4..f912fdd62be 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -80,7 +80,6 @@ ABSTRACT_TYPE(/obj/machinery/power/apc) gfi_layer_rotation = GFI_ROTATION_DEFDIR clicksound = /singleton/sound_category/switch_sound obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - z_flags = ZMM_MANGLE_PLANES var/area/area var/areastring = null var/obj/item/cell/cell @@ -388,17 +387,17 @@ ABSTRACT_TYPE(/obj/machinery/power/apc) if(update & 3) if(update_state & UPDATE_BLUESCREEN) - set_light(l_range = L_WALLMOUNT_RANGE, l_power = L_WALLMOUNT_POWER, l_color = COLOR_BLUE) + set_light_color(LIGHT_COLOR_BLUE) + set_light(L_WALLMOUNT_RANGE) else if(!(stat & (BROKEN|MAINT)) && update_state & UPDATE_ALLGOOD) - var/color switch(charging) if(CHARGING_OFF) - color = "#F86060" + set_light_color("#F86060") if(CHARGING_ON) - color = "#A8B0F8" + set_light_color("#A8B0F8") if(CHARGING_FULL) - color = "#82FF4C" - set_light(l_range = L_WALLMOUNT_RANGE, l_power = L_WALLMOUNT_POWER, l_color = color) + set_light_color("#82FF4C") + set_light(L_WALLMOUNT_RANGE) else set_light(0) diff --git a/code/modules/power/lights/fixtures.dm b/code/modules/power/lights/fixtures.dm index c09d27eef4e..7d06275f530 100644 --- a/code/modules/power/lights/fixtures.dm +++ b/code/modules/power/lights/fixtures.dm @@ -19,14 +19,13 @@ always_area_sensitive = TRUE gfi_layer_rotation = GFI_ROTATION_DEFDIR obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED - var/brightness_range = 8 // luminosity when on, also used in power calculation - var/brightness_power = 0.45 - var/night_brightness_range = 6 + var/brightness_range = 7 // luminosity when on, also used in power calculation + var/brightness_power = 1 + var/night_brightness_range = 5 var/night_brightness_power = 0.4 var/supports_nightmode = TRUE var/nightmode = FALSE var/brightness_color = LIGHT_COLOR_HALOGEN - uv_intensity = 255 var/status = LIGHT_OK // LIGHT_OK, _EMPTY, _BURNED or _BROKEN var/flickering = 0 var/light_type = /obj/item/light/tube // the type of light item diff --git a/code/modules/power/radial_floodlight.dm b/code/modules/power/radial_floodlight.dm index 46dbe7b4ab8..ea4e1b303e2 100644 --- a/code/modules/power/radial_floodlight.dm +++ b/code/modules/power/radial_floodlight.dm @@ -7,9 +7,9 @@ density = TRUE active_power_usage = 800 light_color = LIGHT_COLOR_TUNGSTEN + light_range = 8 var/on = FALSE - var/brightness_on = 12 /obj/machinery/power/radial_floodlight/proc/toggle_active(var/force_state) if(!isnull(force_state)) @@ -19,7 +19,7 @@ else on = !on if(on) - set_light(brightness_on, 1) + set_light(light_range, 1) START_PROCESSING(SSprocessing, src) else set_light(0) diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index 186d925ebbd..1bdf5d49905 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -59,6 +59,7 @@ origin_tech = list(TECH_COMBAT = 1) attack_verb = list("struck", "hit", "bashed") zoomdevicename = "scope" + light_system = DIRECTIONAL_LIGHT /* * Suppression vars @@ -461,9 +462,11 @@ handle_post_fire() // should be safe to not include arguments here, as there are failsafes in effect (?) + var/prev_light = light_range if (muzzle_flash) - set_light(muzzle_flash) - addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, set_light), 0), 2, TIMER_UNIQUE | TIMER_OVERRIDE) + set_light_range(muzzle_flash) + set_light_on(TRUE) + addtimer(CALLBACK(src, PROC_REF(reset_light_range), prev_light), 0.5 SECONDS) update_icon() if(i < burst) @@ -477,6 +480,12 @@ accuracy = initial(accuracy) //Reset the gun's accuracy +/// called by a timer to remove the light range from muzzle flash +/obj/item/gun/proc/reset_light_range(lightrange) + set_light_range(lightrange) + if(lightrange <= 0) + set_light_on(FALSE) + //obtains the next projectile to fire /obj/item/gun/proc/consume_next_projectile() return null @@ -513,8 +522,11 @@ ) if(muzzle_flash) - set_light(muzzle_flash) - addtimer(CALLBACK(src, TYPE_PROC_REF(/atom, set_light), 0), 2) + var/prev_light = light_range + if (muzzle_flash) + set_light_range(muzzle_flash) + set_light_on(TRUE) + addtimer(CALLBACK(src, PROC_REF(reset_light_range), prev_light), 0.5 SECONDS) if(recoil) shake_camera(user, recoil + 1, recoil) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 8599fee3eec..d22d3b8abf1 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -720,6 +720,8 @@ process_hitscan() if(QDELETED(src)) return + else + generate_muzzle_flash() if(!(datum_flags & DF_ISPROCESSING)) START_PROCESSING(SSprojectiles, src) pixel_move(pixel_speed_multiplier, FALSE) //move it now! @@ -1009,6 +1011,19 @@ beam_segments[beam_index] = point_cache generate_hitscan_tracers(null, null, impacting) +/obj/projectile/proc/generate_muzzle_flash(duration = 3) + if(duration <= 0) + return + if(!muzzle_type || suppressed) + return + var/datum/point/p = trajectory + var/atom/movable/thing = new muzzle_type + p.move_atom_to_src(thing) + var/matrix/M = new + M.Turn(original_angle) + thing.transform = M + QDEL_IN(thing, duration) + /obj/projectile/proc/generate_hitscan_tracers(cleanup = TRUE, duration = 3, impacting = TRUE) if(!length(beam_segments)) return @@ -1024,7 +1039,8 @@ matrix.Turn(original_angle) thing.transform = matrix thing.color = color - thing.set_light(muzzle_flash_range, muzzle_flash_intensity, muzzle_flash_color_override? muzzle_flash_color_override : color) + thing.set_light_range_power_color(muzzle_flash_range, muzzle_flash_intensity, muzzle_flash_color_override ? muzzle_flash_color_override : color) + thing.set_light_on(TRUE) QDEL_IN(thing, duration) if(impacting && impact_type && duration > 0) var/datum/point/p = beam_segments[beam_segments[beam_segments.len]] @@ -1034,7 +1050,8 @@ matrix.Turn(Angle) thing.transform = matrix thing.color = color - thing.set_light(impact_light_range, impact_light_intensity, impact_light_color_override? impact_light_color_override : color) + thing.set_light_range_power_color(impact_light_range, impact_light_intensity, impact_light_color_override? impact_light_color_override : color) + thing.set_light_on(TRUE) QDEL_IN(thing, duration) if(cleanup) cleanup_beam_segments() @@ -1075,6 +1092,7 @@ bullet.original = target bullet.preparePixelProjectile(target, src) bullet.fire() + return bullet diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index 7d24a6e149c..49b1ed15242 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -13,6 +13,7 @@ var/frequency = 1 hitscan = 1 invisibility = 101 //beam projectiles are invisible as they are rendered by the effect engine + color = COLOR_RED muzzle_type = /obj/effect/projectile/muzzle/laser tracer_type = /obj/effect/projectile/tracer/laser diff --git a/code/modules/psionics/abilities/hollow_purple.dm b/code/modules/psionics/abilities/hollow_purple.dm index ae019caead6..75cf907b339 100644 --- a/code/modules/psionics/abilities/hollow_purple.dm +++ b/code/modules/psionics/abilities/hollow_purple.dm @@ -29,17 +29,17 @@ user.visible_message(SPAN_NOTICE("[user] puts [user.get_pronoun("his")] palms together...")) START_PROCESSING(SSprocessing, src) user.say("Cursed Technique Amplification: Blue...") - user.set_light(7, 10, COLOR_BLUE) + user.set_light_range_power_color(7, 10, COLOR_BLUE) + user.set_light_on(TRUE) color = COLOR_BLUE if(do_after(user, 4 SECONDS)) stage = 2 color = COLOR_RED user.say("Cursed Technique Reversal: Red...") - user.set_light(0) - user.set_light(7, 10, COLOR_RED) + user.set_light_range_power_color(7, 10, COLOR_RED) if(do_after(user, 4 SECONDS)) user.say("Hollow Technique: Purple!") - user.set_light(0) + user.set_light_on(FALSE) user.visible_message(SPAN_CULT("[user] fires a gigantic purple sphere from [user.get_pronoun("his")] hand!")) . = ..() diff --git a/code/modules/rendering/plane_master.dm b/code/modules/rendering/plane_master.dm index e1b27036501..351826e2620 100644 --- a/code/modules/rendering/plane_master.dm +++ b/code/modules/rendering/plane_master.dm @@ -34,11 +34,13 @@ /atom/movable/screen/plane_master/game_world name = "game world plane master" plane = GAME_PLANE + appearance_flags = PLANE_MASTER blend_mode = BLEND_OVERLAY -/atom/movable/screen/plane_master/rendering_plate/game_world/Initialize(mapload, datum/hud/hud_owner) +/atom/movable/screen/plane_master/game_world/backdrop(mob/mymob) . = ..() - add_filter("displacer", 1, displacement_map_filter(render_source = DISPLACEMENT_PLATE_RENDER_TARGET, size = 10)) + remove_filter("AO") + add_filter("AO", 1, drop_shadow_filter(x = 0, y = -2, size = 4, color = "#04080FAA")) /atom/movable/screen/plane_master/game_world_above name = "above game world plane master" @@ -96,13 +98,18 @@ /atom/movable/screen/plane_master/lighting name = "lighting plane master" plane = LIGHTING_PLANE + blend_mode_override = BLEND_MULTIPLY mouse_opacity = MOUSE_OPACITY_TRANSPARENT - blend_mode = BLEND_MULTIPLY + +/atom/movable/screen/plane_master/lighting/backdrop(mob/mymob) + . = ..() + mymob.overlay_fullscreen("lighting_backdrop", /atom/movable/screen/fullscreen/lighting_backdrop/backplane) + mymob.overlay_fullscreen("lighting_backdrop_lit_secondary", /atom/movable/screen/fullscreen/lighting_backdrop/lit_secondary) /atom/movable/screen/plane_master/lighting/Initialize() . = ..() add_filter("emissives", 1, alpha_mask_filter(render_source = EMISSIVE_RENDER_TARGET, flags = MASK_INVERSE)) - + add_filter("object_lighting", 2, alpha_mask_filter(render_source = O_LIGHTING_VISUAL_RENDER_TARGET, flags = MASK_INVERSE)) /** * Handles emissive overlays and emissive blockers. */ @@ -120,6 +127,8 @@ /atom/movable/screen/plane_master/above_lighting name = "above lighting plane master" plane = ABOVE_LIGHTING_PLANE + appearance_flags = PLANE_MASTER //should use client color + blend_mode = BLEND_OVERLAY render_relay_plane = RENDER_PLANE_GAME /atom/movable/screen/plane_master/runechat @@ -134,6 +143,20 @@ remove_filter("AO") add_filter("AO", 1, drop_shadow_filter(x = 0, y = -2, size = 4, color = "#04080FAA")) +/atom/movable/screen/plane_master/o_light_visual + name = "overlight light visual plane master" + plane = O_LIGHTING_VISUAL_PLANE + render_target = O_LIGHTING_VISUAL_RENDER_TARGET + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + blend_mode = BLEND_MULTIPLY + blend_mode_override = BLEND_MULTIPLY + +/atom/movable/screen/plane_master/nvg_plane + name = "NVG plane" + plane = NVG_PLANE + render_relay_plane = RENDER_PLANE_GAME + blend_mode_override = BLEND_MULTIPLY + /atom/movable/screen/plane_master/fullscreen name = "fullscreen alert plane" plane = FULLSCREEN_PLANE diff --git a/code/modules/rendering/render_plate.dm b/code/modules/rendering/render_plate.dm index 15cfa96c268..24ab4484588 100644 --- a/code/modules/rendering/render_plate.dm +++ b/code/modules/rendering/render_plate.dm @@ -39,6 +39,10 @@ plane = RENDER_PLANE_GAME render_relay_plane = RENDER_PLANE_MASTER +/atom/movable/screen/plane_master/rendering_plate/game_world/Initialize(mapload, datum/hud/hud_owner) + . = ..() + add_filter("displacer", 1, displacement_map_filter(render_source = DISPLACEMENT_PLATE_RENDER_TARGET, size = 10)) + ///render plate for OOC stuff like ghosts, hud-screen effects, etc /atom/movable/screen/plane_master/rendering_plate/non_game name = "non-game rendering plate" diff --git a/code/modules/shieldgen/energy_field.dm b/code/modules/shieldgen/energy_field.dm index 8780a463905..fa9c7e64328 100644 --- a/code/modules/shieldgen/energy_field.dm +++ b/code/modules/shieldgen/energy_field.dm @@ -155,3 +155,6 @@ return TRUE return (!density || air_group) + +/obj/effect/energy_field/afterShuttleMove(obj/effect/shuttle_landmark/destination) + qdel_self() diff --git a/code/modules/shuttles/shuttle.dm b/code/modules/shuttles/shuttle.dm index 08e62ab241e..91b081360c5 100644 --- a/code/modules/shuttles/shuttle.dm +++ b/code/modules/shuttles/shuttle.dm @@ -261,16 +261,8 @@ TA.ChangeTurf(ceiling_type, TRUE, TRUE, TRUE) for(var/area/sub_area in shuttle_area) - for(var/obj/structure/shuttle_part/part in sub_area) - var/turf/target_turf = get_turf(part) - if(part.outside_part) - target_turf.ChangeTurf(destination.base_turf) - for(var/obj/structure/window/shuttle/unique/SW in sub_area) - if(SW.outside_window) - var/turf/target_turf = get_turf(SW) - target_turf.ChangeTurf(destination.base_turf) - for(var/obj/effect/energy_field/ef in sub_area) - qdel(ef) + for(var/atom/movable/movable in sub_area) + movable.afterShuttleMove(destination) // Remove all powernets that were affected, and rebuild them. var/list/cables = list() diff --git a/code/modules/shuttles/shuttle_supply.dm b/code/modules/shuttles/shuttle_supply.dm index 6d646b3f759..63b538c21df 100644 --- a/code/modules/shuttles/shuttle_supply.dm +++ b/code/modules/shuttles/shuttle_supply.dm @@ -36,6 +36,9 @@ /// Area cache of Horizon elevator bay. var/area/horizon_elevator_area + /// Underlays of the elevator saved before transit. + var/list/saved_underlays + /datum/shuttle/autodock/ferry/supply/New(var/_name, var/obj/effect/shuttle_landmark/start_waypoint) ..(_name, start_waypoint) SScargo.shuttle = src @@ -165,15 +168,42 @@ NW.forceMove(locate(target_dest_x, target_dest_y, target_dest_z)) NE.forceMove(locate(target_dest_x + SHAFT_WIDTH, target_dest_y, target_dest_z)) + for(var/area/A in shuttle_area) // we have to do this here or we turn the elevator into a white cube + for(var/obj/machinery/light/L in A) // we turn off lights to avoid having to fight the lighting plane + L.stat |= POWEROFF + L.update() + + sleep(2 SECONDS) + + elevator_animation.icon_state = "elevator_test" + for(var/area/A in shuttle_area) // an image copy of the elevator platform is prepared here for(var/turf/T in A) + LAZYADDASSOC(saved_underlays, T, T.underlays) + T.underlays.Cut() elevator_animation.vis_contents += T + for(var/atom/movable/AM in T.contents) + AM.blocks_emissive = FALSE + AM.update_emissive_blocker() if(!returning_to_CC) handle_arrival_sequence() // coming to Horizon else handle_departure_sequence() // leaving the Horizon + for(var/turf/T in elevator_animation.vis_contents) + T.underlays = LAZYACCESS(saved_underlays, T) + LAZYREMOVE(saved_underlays, T) + for(var/atom/movable/AM in T.contents) + AM.blocks_emissive = initial(AM.blocks_emissive) + AM.update_emissive_blocker() + AM.update_light() + for(var/obj/machinery/light/L in T.contents) + L.stat &= ~POWEROFF + L.update() + + elevator_animation.icon_state = null + elevator_animation.vis_contents.Cut() // animation is done, we can get rid of the elevator platform image /datum/shuttle/autodock/ferry/supply/proc/handle_arrival_sequence() diff --git a/code/modules/supermatter/supermatter.dm b/code/modules/supermatter/supermatter.dm index b8c0ee210bf..62376a44ba6 100644 --- a/code/modules/supermatter/supermatter.dm +++ b/code/modules/supermatter/supermatter.dm @@ -64,7 +64,6 @@ var/explosion_point = 1000 light_color = "#8A8A00" - uv_intensity = 255 var/warning_color = "#B8B800" var/emergency_color = "#D9D900" var/rotation_angle = 0 diff --git a/code/modules/vehicles/animal.dm b/code/modules/vehicles/animal.dm index 5b881a833e7..221fb6faa5d 100644 --- a/code/modules/vehicles/animal.dm +++ b/code/modules/vehicles/animal.dm @@ -40,6 +40,10 @@ . += "Click-drag yourself onto the animal to climb onto it." . += "Click-drag it onto yourself to access its mounted storage." +/obj/vehicle/animal/Destroy() + QDEL_NULL(storage_compartment) + return ..() + /obj/vehicle/animal/setup_vehicle() ..() on = TRUE diff --git a/code/modules/vehicles/bike.dm b/code/modules/vehicles/bike.dm index ce5d65505d6..d4452b627ea 100644 --- a/code/modules/vehicles/bike.dm +++ b/code/modules/vehicles/bike.dm @@ -71,6 +71,7 @@ /obj/vehicle/bike/Destroy() QDEL_NULL(key) QDEL_NULL(ion) + QDEL_NULL(storage_compartment) return ..() /obj/vehicle/bike/setup_vehicle() diff --git a/code/modules/vehicles/cargo_train.dm b/code/modules/vehicles/cargo_train.dm index 8cf67b3a64a..3793719f9b6 100644 --- a/code/modules/vehicles/cargo_train.dm +++ b/code/modules/vehicles/cargo_train.dm @@ -18,6 +18,10 @@ var/obj/item/key/key var/key_type = /obj/item/key/cargo_train +/obj/vehicle/train/cargo/engine/Destroy() + QDEL_NULL(key) + return ..() + /obj/vehicle/train/cargo/engine/mechanics_hints(mob/user, distance, is_adjacent) . += ..() . += "Click-drag yourself onto the truck to climb onto it." diff --git a/code/modules/vehicles/vehicle.dm b/code/modules/vehicles/vehicle.dm index f3a766e6a35..90d702a0071 100644 --- a/code/modules/vehicles/vehicle.dm +++ b/code/modules/vehicles/vehicle.dm @@ -50,6 +50,10 @@ . = ..() setup_vehicle() +/obj/vehicle/Destroy() + QDEL_NULL(cell) + return ..() + /obj/vehicle/proc/setup_vehicle() LAZYADD(can_buckle, /mob/living) @@ -198,13 +202,15 @@ if(powered && cell?.charge < charge_use && !organic) return FALSE on = TRUE - set_light(initial(light_range)) + set_light_range_power_color(initial(light_range)) + set_light_on(on) update_icon() return TRUE /obj/vehicle/proc/turn_off() on = FALSE - set_light(0) + set_light_range_power_color(0) + set_light_on(on) update_icon() /obj/vehicle/emag_act(var/remaining_charges, mob/user as mob) diff --git a/code/unit_tests/create_and_destroy.dm b/code/unit_tests/create_and_destroy.dm index 1b04e4fca50..56cae2a727d 100644 --- a/code/unit_tests/create_and_destroy.dm +++ b/code/unit_tests/create_and_destroy.dm @@ -105,7 +105,8 @@ GLOBAL_VAR_INIT(running_create_and_destroy, FALSE) /atom/movable/flick_visual, //Weather system, requires a z level - /obj/abstract/weather_system + /obj/abstract/weather_system, + /atom/movable/lighting_mask, //leave it alone ) diff --git a/code/unit_tests/equipment_tests.dm b/code/unit_tests/equipment_tests.dm deleted file mode 100644 index ea1115a271a..00000000000 --- a/code/unit_tests/equipment_tests.dm +++ /dev/null @@ -1,66 +0,0 @@ -#define SUCCESS 1 -#define FAILURE 0 - - -/datum/unit_test/vision_glasses/ - name = "EQUIPMENT: Vision Template" - groups = list("generic", "vision") - - - var/mob/living/carbon/human/H = null - var/expectation = SEE_INVISIBLE_NOLIGHTING - var/glasses_type = null - async = 1 - -/datum/unit_test/vision_glasses/start_test() - var/list/test = create_test_mob_with_mind(null, /mob/living/carbon/human) - if(isnull(test)) - TEST_FAIL("Check Runtimed in Mob creation") - - if(test["result"] == FAILURE) - TEST_FAIL(test["msg"]) - async = 0 - - return 0 - - H = locate(test["mobref"]) - - var/obj/item/clothing/glasses/G = new glasses_type() - H.glasses = G - - return 1 - - -/datum/unit_test/vision_glasses/check_result() - - if(isnull(H) || H.life_tick < 2) - return 0 - - if(isnull(H.glasses)) - TEST_FAIL("Mob doesn't have glasses on") - - H.handle_vision() // Because Life has a client check that bypasses updating vision - - if(H.see_invisible == expectation) - TEST_PASS("Mob See invisible is [H.see_invisible]") - else - TEST_FAIL("Mob See invisible is [H.see_invisible] / expected [expectation]") - - return 1 - -/datum/unit_test/vision_glasses/NVG - name = "EQUIPMENT: NVG see_invis" - glasses_type = /obj/item/clothing/glasses/night - -/datum/unit_test/vision_glasses/mesons - name = "EQUIPMENT: Mesons see_invis" - glasses_type = /obj/item/clothing/glasses/meson - -/datum/unit_test/vision_glasses/plain - name = "EQUIPMENT: Plain glasses. see_invis" - glasses_type = /obj/item/clothing/glasses/regular - expectation = SEE_INVISIBLE_LIVING - -#undef SUCCESS -#undef FAILURE - diff --git a/html/changelogs/mattatlas-fallingapart.yml b/html/changelogs/mattatlas-fallingapart.yml new file mode 100644 index 00000000000..dd427f12ddc --- /dev/null +++ b/html/changelogs/mattatlas-fallingapart.yml @@ -0,0 +1,60 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# - (fixes bugs) +# wip +# - (work in progress) +# qol +# - (quality of life) +# soundadd +# - (adds a sound) +# sounddel +# - (removes a sound) +# rscadd +# - (adds a feature) +# rscdel +# - (removes a feature) +# imageadd +# - (adds an image or sprite) +# imagedel +# - (removes an image or sprite) +# spellcheck +# - (fixes spelling or grammar) +# experiment +# - (experimental change) +# balance +# - (balance changes) +# code_imp +# - (misc internal code change) +# refactor +# - (refactors code) +# config +# - (makes a change to the config files) +# admin +# - (makes changes to administrator tools) +# server +# - (miscellaneous changes to server) +################################# + +# Your name. +author: MattAtlas (porting), CM and /tg/ coders (original code) + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. +# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. +changes: + - experiment: "Replaced our renderer system with TG and CM's planemasters." + - rscadd: "Open space now has a gaussian blur filter." + - bugfix: "Fixed esoteric smoothing behaviour that was a bug for a long time; lattices should no longer smooth with nothing." diff --git a/html/changelogs/mattatlas-returntooblivion.yml b/html/changelogs/mattatlas-returntooblivion.yml new file mode 100644 index 00000000000..d796acf2ca4 --- /dev/null +++ b/html/changelogs/mattatlas-returntooblivion.yml @@ -0,0 +1,58 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# - (fixes bugs) +# wip +# - (work in progress) +# qol +# - (quality of life) +# soundadd +# - (adds a sound) +# sounddel +# - (removes a sound) +# rscadd +# - (adds a feature) +# rscdel +# - (removes a feature) +# imageadd +# - (adds an image or sprite) +# imagedel +# - (removes an image or sprite) +# spellcheck +# - (fixes spelling or grammar) +# experiment +# - (experimental change) +# balance +# - (balance changes) +# code_imp +# - (misc internal code change) +# refactor +# - (refactors code) +# config +# - (makes a change to the config files) +# admin +# - (makes changes to administrator tools) +# server +# - (miscellaneous changes to server) +################################# + +# Your name. +author: MattAtlas (porting), TiviPlus, A-lexa, Synclt21, Azarak, harryob, MorrowWolf, Zonespace (code) + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. +# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. +changes: + - experiment: "Replaced our lighting engine with CM's. There may be bugs!" diff --git a/icons/effects/224x192.dmi b/icons/effects/224x192.dmi index 3e4d63de725..9a87187cb48 100644 Binary files a/icons/effects/224x192.dmi and b/icons/effects/224x192.dmi differ diff --git a/icons/effects/alphacolors.dmi b/icons/effects/alphacolors.dmi index 02316fbf64d..b63636c14f7 100644 Binary files a/icons/effects/alphacolors.dmi and b/icons/effects/alphacolors.dmi differ diff --git a/icons/effects/light_overlays/light_128.dmi b/icons/effects/light_overlays/light_128.dmi new file mode 100644 index 00000000000..22dc0b01087 Binary files /dev/null and b/icons/effects/light_overlays/light_128.dmi differ diff --git a/icons/effects/light_overlays/light_160.dmi b/icons/effects/light_overlays/light_160.dmi new file mode 100644 index 00000000000..26dfa453c51 Binary files /dev/null and b/icons/effects/light_overlays/light_160.dmi differ diff --git a/icons/effects/light_overlays/light_192.dmi b/icons/effects/light_overlays/light_192.dmi new file mode 100644 index 00000000000..aca94ee0caf Binary files /dev/null and b/icons/effects/light_overlays/light_192.dmi differ diff --git a/icons/effects/light_overlays/light_224.dmi b/icons/effects/light_overlays/light_224.dmi new file mode 100644 index 00000000000..9fab531d1a6 Binary files /dev/null and b/icons/effects/light_overlays/light_224.dmi differ diff --git a/icons/effects/light_overlays/light_256.dmi b/icons/effects/light_overlays/light_256.dmi new file mode 100644 index 00000000000..701562efcd8 Binary files /dev/null and b/icons/effects/light_overlays/light_256.dmi differ diff --git a/icons/effects/light_overlays/light_288.dmi b/icons/effects/light_overlays/light_288.dmi new file mode 100644 index 00000000000..b6eac180f7a Binary files /dev/null and b/icons/effects/light_overlays/light_288.dmi differ diff --git a/icons/effects/light_overlays/light_32.dmi b/icons/effects/light_overlays/light_32.dmi new file mode 100644 index 00000000000..5269b1fba36 Binary files /dev/null and b/icons/effects/light_overlays/light_32.dmi differ diff --git a/icons/effects/light_overlays/light_320.dmi b/icons/effects/light_overlays/light_320.dmi new file mode 100644 index 00000000000..bf263c4b29b Binary files /dev/null and b/icons/effects/light_overlays/light_320.dmi differ diff --git a/icons/effects/light_overlays/light_352.dmi b/icons/effects/light_overlays/light_352.dmi new file mode 100644 index 00000000000..f895792da42 Binary files /dev/null and b/icons/effects/light_overlays/light_352.dmi differ diff --git a/icons/effects/light_overlays/light_384.dmi b/icons/effects/light_overlays/light_384.dmi new file mode 100644 index 00000000000..ef2a4c97e04 Binary files /dev/null and b/icons/effects/light_overlays/light_384.dmi differ diff --git a/icons/effects/light_overlays/light_416.dmi b/icons/effects/light_overlays/light_416.dmi new file mode 100644 index 00000000000..6a32ecbda66 Binary files /dev/null and b/icons/effects/light_overlays/light_416.dmi differ diff --git a/icons/effects/light_overlays/light_64.dmi b/icons/effects/light_overlays/light_64.dmi new file mode 100644 index 00000000000..37fc5084abc Binary files /dev/null and b/icons/effects/light_overlays/light_64.dmi differ diff --git a/icons/effects/light_overlays/light_96.dmi b/icons/effects/light_overlays/light_96.dmi new file mode 100644 index 00000000000..b689a137016 Binary files /dev/null and b/icons/effects/light_overlays/light_96.dmi differ diff --git a/icons/effects/light_overlays/light_cone.dmi b/icons/effects/light_overlays/light_cone.dmi new file mode 100644 index 00000000000..75f322a9371 Binary files /dev/null and b/icons/effects/light_overlays/light_cone.dmi differ diff --git a/icons/effects/light_overlays/shockwave.dmi b/icons/effects/light_overlays/shockwave.dmi new file mode 100644 index 00000000000..c22acfa1d59 Binary files /dev/null and b/icons/effects/light_overlays/shockwave.dmi differ diff --git a/icons/effects/lighting_object.dmi b/icons/effects/lighting_object.dmi new file mode 100644 index 00000000000..d2e50395872 Binary files /dev/null and b/icons/effects/lighting_object.dmi differ diff --git a/icons/effects/lighting_object_big.dmi b/icons/effects/lighting_object_big.dmi new file mode 100644 index 00000000000..d96db059bed Binary files /dev/null and b/icons/effects/lighting_object_big.dmi differ diff --git a/maps/_common/areas/areas.dm b/maps/_common/areas/areas.dm index 82e964e7fa1..3cc8b1c1d67 100644 --- a/maps/_common/areas/areas.dm +++ b/maps/_common/areas/areas.dm @@ -30,7 +30,6 @@ Generally you don't want to put your areas in here; if the area is only used in icon_state = "space" requires_power = 1 always_unpowered = 1 - dynamic_lighting = 1 power_light = 0 power_equip = 0 power_environ = 0 diff --git a/maps/_common/areas/holodeck.dm b/maps/_common/areas/holodeck.dm index c410ac43f4f..d7f1e52b8cc 100644 --- a/maps/_common/areas/holodeck.dm +++ b/maps/_common/areas/holodeck.dm @@ -4,12 +4,10 @@ sound_environment = SOUND_AREA_LARGE_ENCLOSED no_light_control = TRUE station_area = TRUE - dynamic_lighting = FALSE area_flags = AREA_FLAG_NO_GHOST_TELEPORT_ACCESS /area/holodeck/alphadeck name = "Holodeck Alpha" - dynamic_lighting = TRUE /area/holodeck/source_plating name = "Holodeck - Off" diff --git a/maps/_common/areas/special.dm b/maps/_common/areas/special.dm index f99d05497fd..f97a58e5bcd 100644 --- a/maps/_common/areas/special.dm +++ b/maps/_common/areas/special.dm @@ -27,7 +27,7 @@ /area/centcom/start name = "New Player Spawn" - dynamic_lighting = 0 + base_lighting_alpha = 255 sound_environment = SOUND_ENVIRONMENT_OFF /area/centcom/evac @@ -96,7 +96,6 @@ name = "Merchant Station" icon_state = "merchant" requires_power = 0 - dynamic_lighting = 1 no_light_control = 1 centcomm_area = 1 area_flags = AREA_FLAG_NO_CREW_EXPECTED diff --git a/maps/away/away_site/blueriver/blueriver.dm b/maps/away/away_site/blueriver/blueriver.dm index 97ec6a04b41..6ccd3e0951e 100644 --- a/maps/away/away_site/blueriver/blueriver.dm +++ b/maps/away/away_site/blueriver/blueriver.dm @@ -93,7 +93,6 @@ icon = 'maps/away/away_site/blueriver/blueriver.dmi' icon_state = "bluespacecrystal1" opacity = 0 - dynamic_lighting = 0 /turf/unsimulated/wall/supermatter/no_spread/blueriver/Initialize() . = ..() diff --git a/maps/away/away_site/hivebot_hub/hivebot_hub.dm b/maps/away/away_site/hivebot_hub/hivebot_hub.dm index a1d509fd35f..138581c9a96 100644 --- a/maps/away/away_site/hivebot_hub/hivebot_hub.dm +++ b/maps/away/away_site/hivebot_hub/hivebot_hub.dm @@ -41,7 +41,6 @@ /area/hivebothub icon_state = "red" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/away_site/idris_wreck/idris_wreck.dm b/maps/away/away_site/idris_wreck/idris_wreck.dm index f34b7c3d7a1..7ca6d02693f 100644 --- a/maps/away/away_site/idris_wreck/idris_wreck.dm +++ b/maps/away/away_site/idris_wreck/idris_wreck.dm @@ -128,7 +128,6 @@ name = "Idris Vault Ship" icon_state = "green" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/away_site/tajara/mining_jack/mining_jack_areas.dm b/maps/away/away_site/tajara/mining_jack/mining_jack_areas.dm index 9ac76be91f1..59abb0e3b6d 100644 --- a/maps/away/away_site/tajara/mining_jack/mining_jack_areas.dm +++ b/maps/away/away_site/tajara/mining_jack/mining_jack_areas.dm @@ -2,7 +2,6 @@ name = "Mining Jack Outpost" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED | AREA_FLAG_HIDE_FROM_HOLOMAP diff --git a/maps/away/away_site/tajara/peoples_station/peoples_station_zones.dm b/maps/away/away_site/tajara/peoples_station/peoples_station_zones.dm index ed07339fa02..ca66b78683d 100644 --- a/maps/away/away_site/tajara/peoples_station/peoples_station_zones.dm +++ b/maps/away/away_site/tajara/peoples_station/peoples_station_zones.dm @@ -2,7 +2,6 @@ name = "People's Space Station" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = TRUE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/away_site/tajara/saniorios_outpost/saniorios_outpost_zones.dm b/maps/away/away_site/tajara/saniorios_outpost/saniorios_outpost_zones.dm index d674296af1a..c67f4496af3 100644 --- a/maps/away/away_site/tajara/saniorios_outpost/saniorios_outpost_zones.dm +++ b/maps/away/away_site/tajara/saniorios_outpost/saniorios_outpost_zones.dm @@ -2,7 +2,6 @@ name = "Sani'Orios Asteroid Outpost" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/away_site/tajara/scrapper/scrapper_areas.dm b/maps/away/away_site/tajara/scrapper/scrapper_areas.dm index 69b0a319f00..c7b4729a465 100644 --- a/maps/away/away_site/tajara/scrapper/scrapper_areas.dm +++ b/maps/away/away_site/tajara/scrapper/scrapper_areas.dm @@ -2,7 +2,6 @@ name = "Scrapper Outpost" icon_state = "bluenew" requires_power = 1 - dynamic_lighting = 1 no_light_control = 0 base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED | AREA_FLAG_HIDE_FROM_HOLOMAP diff --git a/maps/away/away_site/uueoaesa/omgolo/omgolo_smuggler.dm b/maps/away/away_site/uueoaesa/omgolo/omgolo_smuggler.dm index 5a7dca07ebd..38effc4b88c 100644 --- a/maps/away/away_site/uueoaesa/omgolo/omgolo_smuggler.dm +++ b/maps/away/away_site/uueoaesa/omgolo/omgolo_smuggler.dm @@ -47,7 +47,6 @@ name = "Abandoned Smuggler's Base" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/away_site/uueoaesa/omgolo/omgolo_tourist.dm b/maps/away/away_site/uueoaesa/omgolo/omgolo_tourist.dm index 48d0253fafa..368676655b1 100644 --- a/maps/away/away_site/uueoaesa/omgolo/omgolo_tourist.dm +++ b/maps/away/away_site/uueoaesa/omgolo/omgolo_tourist.dm @@ -54,7 +54,6 @@ name = "Abandoned Tourism Platform" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/away_site/uueoaesa/reclamation/ihss_reclamation_areas.dm b/maps/away/away_site/uueoaesa/reclamation/ihss_reclamation_areas.dm index 1c0fbf48b2e..83c79b025c4 100644 --- a/maps/away/away_site/uueoaesa/reclamation/ihss_reclamation_areas.dm +++ b/maps/away/away_site/uueoaesa/reclamation/ihss_reclamation_areas.dm @@ -2,7 +2,6 @@ name = "IHSS Reclamation" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = TRUE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/away_site/uueoaesa/tret/tret_industrial_complex_areas.dm b/maps/away/away_site/uueoaesa/tret/tret_industrial_complex_areas.dm index 3b7ef1d8012..abfba962265 100644 --- a/maps/away/away_site/uueoaesa/tret/tret_industrial_complex_areas.dm +++ b/maps/away/away_site/uueoaesa/tret/tret_industrial_complex_areas.dm @@ -4,7 +4,6 @@ name = "Tret Industrial Complex - Base/Parent" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/basalt/tret area_flags = AREA_FLAG_RAD_SHIELDED | AREA_FLAG_HIDE_FROM_HOLOMAP //| AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/away/scenarios/cryo_outpost/cryo_outpost_areas.dm b/maps/away/scenarios/cryo_outpost/cryo_outpost_areas.dm index 555443a5c1c..0fcc8031b73 100644 --- a/maps/away/scenarios/cryo_outpost/cryo_outpost_areas.dm +++ b/maps/away/scenarios/cryo_outpost/cryo_outpost_areas.dm @@ -4,7 +4,6 @@ name = "Outpost" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/barren area_flags = AREA_FLAG_RAD_SHIELDED | AREA_FLAG_INDESTRUCTIBLE_TURFS | AREA_FLAG_IS_BACKGROUND diff --git a/maps/away/scenarios/enviro_testing_facility/enviro_testing_facility_areas.dm b/maps/away/scenarios/enviro_testing_facility/enviro_testing_facility_areas.dm index b99dc02f0a3..705a6ee6f54 100644 --- a/maps/away/scenarios/enviro_testing_facility/enviro_testing_facility_areas.dm +++ b/maps/away/scenarios/enviro_testing_facility/enviro_testing_facility_areas.dm @@ -5,7 +5,6 @@ name = "Base/Parent Area" icon_state = "white128a" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/barren area_flags = AREA_FLAG_RAD_SHIELDED | AREA_FLAG_INDESTRUCTIBLE_TURFS | AREA_FLAG_IS_BACKGROUND diff --git a/maps/away/scenarios/nuclear_silo/nuclear_silo_areas.dm b/maps/away/scenarios/nuclear_silo/nuclear_silo_areas.dm index be40e69771f..6484acbc1b6 100644 --- a/maps/away/scenarios/nuclear_silo/nuclear_silo_areas.dm +++ b/maps/away/scenarios/nuclear_silo/nuclear_silo_areas.dm @@ -2,7 +2,6 @@ name = "Nuclear Silo" icon_state = "exterior" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/snow area_flags = AREA_FLAG_RAD_SHIELDED | AREA_FLAG_INDESTRUCTIBLE_TURFS | AREA_FLAG_IS_BACKGROUND diff --git a/maps/away/ships/biesel/tcaf_corvette/tcaf_corvette_areas.dm b/maps/away/ships/biesel/tcaf_corvette/tcaf_corvette_areas.dm index b7b99725b2f..2499bf8ecff 100644 --- a/maps/away/ships/biesel/tcaf_corvette/tcaf_corvette_areas.dm +++ b/maps/away/ships/biesel/tcaf_corvette/tcaf_corvette_areas.dm @@ -2,7 +2,6 @@ name = "Republican Fleet Corvette - Central Hall" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/coc/coc_scarab/coc_scarab_areas.dm b/maps/away/ships/coc/coc_scarab/coc_scarab_areas.dm index 1fa4bb4c93a..23c010b724a 100644 --- a/maps/away/ships/coc/coc_scarab/coc_scarab_areas.dm +++ b/maps/away/ships/coc/coc_scarab/coc_scarab_areas.dm @@ -2,7 +2,6 @@ name = "Scarab Salvage Vessel" icon_state = "blue" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/coc/coc_surveyor/coc_surveyor_areas.dm b/maps/away/ships/coc/coc_surveyor/coc_surveyor_areas.dm index a2a34056752..4ce64ac7cd2 100644 --- a/maps/away/ships/coc/coc_surveyor/coc_surveyor_areas.dm +++ b/maps/away/ships/coc/coc_surveyor/coc_surveyor_areas.dm @@ -2,7 +2,6 @@ name = "Coalition Survey Ship" icon_state = "blue" requires_power = 1 - dynamic_lighting = 1 no_light_control = 1 base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/coc/gadpathur_patrol/gadpathur_patrol_areas.dm b/maps/away/ships/coc/gadpathur_patrol/gadpathur_patrol_areas.dm index d81489c836b..9fe2b47eb9a 100644 --- a/maps/away/ships/coc/gadpathur_patrol/gadpathur_patrol_areas.dm +++ b/maps/away/ships/coc/gadpathur_patrol/gadpathur_patrol_areas.dm @@ -2,7 +2,6 @@ name = "Gadpathurian Corvette" icon_state = "yellow" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/dominia/dominian_corvette/dominian_corvette_areas.dm b/maps/away/ships/dominia/dominian_corvette/dominian_corvette_areas.dm index e4da39ea432..ff19e0178eb 100644 --- a/maps/away/ships/dominia/dominian_corvette/dominian_corvette_areas.dm +++ b/maps/away/ships/dominia/dominian_corvette/dominian_corvette_areas.dm @@ -2,7 +2,6 @@ name = "Dominian Corvette" icon_state = "red" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/dpra/hailstorm/hailstorm_areas.dm b/maps/away/ships/dpra/hailstorm/hailstorm_areas.dm index 4127390f65a..809f66295db 100644 --- a/maps/away/ships/dpra/hailstorm/hailstorm_areas.dm +++ b/maps/away/ships/dpra/hailstorm/hailstorm_areas.dm @@ -2,7 +2,6 @@ name = "Hailstorm Ship" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/elyra/elyra_corvette/elyra_corvette_areas.dm b/maps/away/ships/elyra/elyra_corvette/elyra_corvette_areas.dm index 9bdba8cc97b..ee1955dda3b 100644 --- a/maps/away/ships/elyra/elyra_corvette/elyra_corvette_areas.dm +++ b/maps/away/ships/elyra/elyra_corvette/elyra_corvette_areas.dm @@ -1,7 +1,6 @@ /area/ship/elyran_corvette name = "Elyran Corvette" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/freebooter/freebooter_salvager/freebooter_salvager_areas.dm b/maps/away/ships/freebooter/freebooter_salvager/freebooter_salvager_areas.dm index 6fb045da5c7..293f42915d5 100644 --- a/maps/away/ships/freebooter/freebooter_salvager/freebooter_salvager_areas.dm +++ b/maps/away/ships/freebooter/freebooter_salvager/freebooter_salvager_areas.dm @@ -2,7 +2,6 @@ name = "Freebooter Salvager Ship" icon_state = "purple" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/golden_deep/golden_deep_areas.dm b/maps/away/ships/golden_deep/golden_deep_areas.dm index 25352c1220a..bfd1c9565cd 100644 --- a/maps/away/ships/golden_deep/golden_deep_areas.dm +++ b/maps/away/ships/golden_deep/golden_deep_areas.dm @@ -1,7 +1,6 @@ /area/golden_deep icon_state = "yellow" requires_power = 1 - dynamic_lighting = 1 no_light_control = 0 base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/hegemony/fishing_trawler/fishing_league_trawler_areas.dm b/maps/away/ships/hegemony/fishing_trawler/fishing_league_trawler_areas.dm index 30e349f9bc2..235a0bbe0fc 100644 --- a/maps/away/ships/hegemony/fishing_trawler/fishing_league_trawler_areas.dm +++ b/maps/away/ships/hegemony/fishing_trawler/fishing_league_trawler_areas.dm @@ -88,7 +88,6 @@ icon_state = "exterior" base_turf = /turf/space requires_power = FALSE - dynamic_lighting = TRUE has_gravity = FALSE no_light_control = TRUE allow_nightmode = FALSE diff --git a/maps/away/ships/hegemony/hegemony_corvette/hegemony_corvette_areas.dm b/maps/away/ships/hegemony/hegemony_corvette/hegemony_corvette_areas.dm index 4350a49cfbf..53a463e0b78 100644 --- a/maps/away/ships/hegemony/hegemony_corvette/hegemony_corvette_areas.dm +++ b/maps/away/ships/hegemony/hegemony_corvette/hegemony_corvette_areas.dm @@ -2,7 +2,6 @@ name = "Hegemony Corvette" icon_state = "yellow" requires_power = 1 - dynamic_lighting = 1 no_light_control = 1 base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/hegemony/merchants_guild/merchant_freighter_areas.dm b/maps/away/ships/hegemony/merchants_guild/merchant_freighter_areas.dm index 33e3dc36333..0d44531bc93 100644 --- a/maps/away/ships/hegemony/merchants_guild/merchant_freighter_areas.dm +++ b/maps/away/ships/hegemony/merchants_guild/merchant_freighter_areas.dm @@ -2,7 +2,6 @@ name = "Merchants' Guild - Freighter" icon_state = "yellow" requires_power = 1 - dynamic_lighting = 1 no_light_control = 0 base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/hegemony/miners_guild/miners_guild_areas.dm b/maps/away/ships/hegemony/miners_guild/miners_guild_areas.dm index 5f7c0ac62f9..19a2c81d053 100644 --- a/maps/away/ships/hegemony/miners_guild/miners_guild_areas.dm +++ b/maps/away/ships/hegemony/miners_guild/miners_guild_areas.dm @@ -2,7 +2,6 @@ name = "Miners' Guild Outpost" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED | AREA_FLAG_HIDE_FROM_HOLOMAP diff --git a/maps/away/ships/heph/cyclops/cyclops_mining_areas.dm b/maps/away/ships/heph/cyclops/cyclops_mining_areas.dm index c2b4038dc89..44dae7552ef 100644 --- a/maps/away/ships/heph/cyclops/cyclops_mining_areas.dm +++ b/maps/away/ships/heph/cyclops/cyclops_mining_areas.dm @@ -2,7 +2,6 @@ name = "Cyclops Mining Vessel" icon_state = "bluenew" requires_power = 1 - dynamic_lighting = 1 no_light_control = 0 base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/heph/heph_security/heph_security_areas.dm b/maps/away/ships/heph/heph_security/heph_security_areas.dm index 92dc2773b69..ea3766c3872 100644 --- a/maps/away/ships/heph/heph_security/heph_security_areas.dm +++ b/maps/away/ships/heph/heph_security/heph_security_areas.dm @@ -2,7 +2,6 @@ name = "Hephaestus Security Vessel - Central Hallway" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/himeo/himeo_patrol_ship_areas.dm b/maps/away/ships/himeo/himeo_patrol_ship_areas.dm index 2acad8ecc9b..6318cdedb3f 100644 --- a/maps/away/ships/himeo/himeo_patrol_ship_areas.dm +++ b/maps/away/ships/himeo/himeo_patrol_ship_areas.dm @@ -2,7 +2,6 @@ name = "Himean Patrol Vessel - Central Hallway" icon_state = "hallC" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE area_flags = AREA_FLAG_RAD_SHIELDED ambience = AMBIENCE_ENGINEERING diff --git a/maps/away/ships/kataphracts/kataphract_areas.dm b/maps/away/ships/kataphracts/kataphract_areas.dm index 2eb835c4b57..9f559494eb6 100644 --- a/maps/away/ships/kataphracts/kataphract_areas.dm +++ b/maps/away/ships/kataphracts/kataphract_areas.dm @@ -2,7 +2,6 @@ name = "Kataphract Chapter" icon_state = "yellow" requires_power = 1 - dynamic_lighting = 1 no_light_control = 0 base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/konyang/air_konyang/air_konyang_areas.dm b/maps/away/ships/konyang/air_konyang/air_konyang_areas.dm index c554b927597..625efc29a65 100644 --- a/maps/away/ships/konyang/air_konyang/air_konyang_areas.dm +++ b/maps/away/ships/konyang/air_konyang/air_konyang_areas.dm @@ -1,7 +1,6 @@ /area/shuttle/air_konyang name = "Air Konyang Liner" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/konyang/einstein_shuttle/einstein_shuttle.dm b/maps/away/ships/konyang/einstein_shuttle/einstein_shuttle.dm index 4f8f8a12e24..3dfb58108e6 100644 --- a/maps/away/ships/konyang/einstein_shuttle/einstein_shuttle.dm +++ b/maps/away/ships/konyang/einstein_shuttle/einstein_shuttle.dm @@ -22,7 +22,6 @@ name = "Einstein Engines Transport Shuttle" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/konyang/ipc_refugee/ipc_refugee_ship_areas.dm b/maps/away/ships/konyang/ipc_refugee/ipc_refugee_ship_areas.dm index cf4bb735178..f421355dc84 100644 --- a/maps/away/ships/konyang/ipc_refugee/ipc_refugee_ship_areas.dm +++ b/maps/away/ships/konyang/ipc_refugee/ipc_refugee_ship_areas.dm @@ -1,7 +1,6 @@ /area/ship/ipc_refugee name = "Decrepit Freighter" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/konyang/kasf_ship/kasf_ship_areas.dm b/maps/away/ships/konyang/kasf_ship/kasf_ship_areas.dm index 05892e6597a..41fae20bc44 100644 --- a/maps/away/ships/konyang/kasf_ship/kasf_ship_areas.dm +++ b/maps/away/ships/konyang/kasf_ship/kasf_ship_areas.dm @@ -1,7 +1,6 @@ /area/ship/kasf_corvette name = "KASF Corvette" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/konyang/konyang_wreck/konyang_wreck_areas.dm b/maps/away/ships/konyang/konyang_wreck/konyang_wreck_areas.dm index 5f9a911842d..f70c7b9c0a9 100644 --- a/maps/away/ships/konyang/konyang_wreck/konyang_wreck_areas.dm +++ b/maps/away/ships/konyang/konyang_wreck/konyang_wreck_areas.dm @@ -2,7 +2,6 @@ name = "Orion Express Cargo Vessel - Main Hall" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/konyang/water_barge/water_barge_areas.dm b/maps/away/ships/konyang/water_barge/water_barge_areas.dm index aca0fb5f382..7d73fcaabbd 100644 --- a/maps/away/ships/konyang/water_barge/water_barge_areas.dm +++ b/maps/away/ships/konyang/water_barge/water_barge_areas.dm @@ -2,7 +2,6 @@ name = "Water Barge - Main Hold" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/nka/nka_merchant/nka_merchant_areas.dm b/maps/away/ships/nka/nka_merchant/nka_merchant_areas.dm index 2518d8dbc17..78abf5cd252 100644 --- a/maps/away/ships/nka/nka_merchant/nka_merchant_areas.dm +++ b/maps/away/ships/nka/nka_merchant/nka_merchant_areas.dm @@ -2,7 +2,6 @@ name = "Her Majesty's Mercantile Flotilla Ship" icon_state = "bluenew" requires_power = 1 - dynamic_lighting = 1 no_light_control = 0 base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/orion/orion_express_ship.dm b/maps/away/ships/orion/orion_express_ship.dm index 00c83e133b5..2dc6207a1f5 100644 --- a/maps/away/ships/orion/orion_express_ship.dm +++ b/maps/away/ships/orion/orion_express_ship.dm @@ -20,7 +20,6 @@ /area/ship/orion name = "Orion Express Courier Ship (parent type, do not use!)" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/pra/database_freighter/database_freighter_areas.dm b/maps/away/ships/pra/database_freighter/database_freighter_areas.dm index ee8b431f4e1..9b68e43c3bf 100644 --- a/maps/away/ships/pra/database_freighter/database_freighter_areas.dm +++ b/maps/away/ships/pra/database_freighter/database_freighter_areas.dm @@ -2,7 +2,6 @@ name = "Database Freighter" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/pra/headmaster/headmaster_areas.dm b/maps/away/ships/pra/headmaster/headmaster_areas.dm index 76f65957843..c98bfdd82a9 100644 --- a/maps/away/ships/pra/headmaster/headmaster_areas.dm +++ b/maps/away/ships/pra/headmaster/headmaster_areas.dm @@ -2,7 +2,6 @@ name = "Headmaster Ship" icon_state = "red" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/sadar_scout/sadar_scout_areas.dm b/maps/away/ships/sadar_scout/sadar_scout_areas.dm index bbf17dd5add..65ff25ac626 100644 --- a/maps/away/ships/sadar_scout/sadar_scout_areas.dm +++ b/maps/away/ships/sadar_scout/sadar_scout_areas.dm @@ -1,7 +1,6 @@ /area/ship/sadar_scout name = "Ancient Expeditionary Vessel" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/sol/sol_merc/fsf_patrol_ship_areas.dm b/maps/away/ships/sol/sol_merc/fsf_patrol_ship_areas.dm index 9b0c4288537..d33c58deae1 100644 --- a/maps/away/ships/sol/sol_merc/fsf_patrol_ship_areas.dm +++ b/maps/away/ships/sol/sol_merc/fsf_patrol_ship_areas.dm @@ -1,7 +1,6 @@ /area/ship/fsf_patrol_ship name = "FSF Corvette" requires_power = TRUE - dynamic_lighting = TRUE /area/ship/fsf_patrol_ship/bridge name = "FSF Corvette - Bridge" diff --git a/maps/away/ships/sol/sol_splf/splf_raider_areas.dm b/maps/away/ships/sol/sol_splf/splf_raider_areas.dm index 7d9f8662156..39e27efa81a 100644 --- a/maps/away/ships/sol/sol_splf/splf_raider_areas.dm +++ b/maps/away/ships/sol/sol_splf/splf_raider_areas.dm @@ -2,7 +2,6 @@ name = "Independent Hauler" icon_state = "green" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/sol/sol_ssrm/ssrm_ship_areas.dm b/maps/away/ships/sol/sol_ssrm/ssrm_ship_areas.dm index bcc6e15cd20..cdb3151eb5d 100644 --- a/maps/away/ships/sol/sol_ssrm/ssrm_ship_areas.dm +++ b/maps/away/ships/sol/sol_ssrm/ssrm_ship_areas.dm @@ -1,7 +1,6 @@ /area/ship/ssrm_corvette name = "Sol Recon Corvette" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/tajara/circus/adhomian_circus_areas.dm b/maps/away/ships/tajara/circus/adhomian_circus_areas.dm index 152180adece..afa6e131a24 100644 --- a/maps/away/ships/tajara/circus/adhomian_circus_areas.dm +++ b/maps/away/ships/tajara/circus/adhomian_circus_areas.dm @@ -3,7 +3,6 @@ name = "Adhomian Traveling Circus" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/tajara/taj_smuggler/tajaran_smuggler_areas.dm b/maps/away/ships/tajara/taj_smuggler/tajaran_smuggler_areas.dm index e1347f23dfb..941962aa414 100644 --- a/maps/away/ships/tajara/taj_smuggler/tajaran_smuggler_areas.dm +++ b/maps/away/ships/tajara/taj_smuggler/tajaran_smuggler_areas.dm @@ -2,7 +2,6 @@ name = "Adhomian Freighter" icon_state = "bluenew" requires_power = 1 - dynamic_lighting = 1 no_light_control = 0 base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/tirakqi_smuggler/tirakqi_smuggler.dm b/maps/away/ships/tirakqi_smuggler/tirakqi_smuggler.dm index 247e99c6306..e2583dfa3ac 100644 --- a/maps/away/ships/tirakqi_smuggler/tirakqi_smuggler.dm +++ b/maps/away/ships/tirakqi_smuggler/tirakqi_smuggler.dm @@ -202,7 +202,6 @@ icon_state = "void" footstep_sound = null plane = SPACE_PLANE - dynamic_lighting = 0 /turf/simulated/floor/holofloor/tirakqi_cosmocage/update_dirt() return // Space doesn't become dirty diff --git a/maps/away/ships/tirakqi_smuggler/tirakqi_smuggler_areas.dm b/maps/away/ships/tirakqi_smuggler/tirakqi_smuggler_areas.dm index dd7c64bb11e..2fe1e8e4373 100644 --- a/maps/away/ships/tirakqi_smuggler/tirakqi_smuggler_areas.dm +++ b/maps/away/ships/tirakqi_smuggler/tirakqi_smuggler_areas.dm @@ -1,7 +1,6 @@ /area/ship/tirakqi_smuggler name = "Ti'Rakqi Freighter" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/tramp_freighter/tramp_freighter_areas.dm b/maps/away/ships/tramp_freighter/tramp_freighter_areas.dm index 028e7470f2b..d38614700c1 100644 --- a/maps/away/ships/tramp_freighter/tramp_freighter_areas.dm +++ b/maps/away/ships/tramp_freighter/tramp_freighter_areas.dm @@ -2,7 +2,6 @@ name = "Tramp Freighter" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED @@ -111,5 +110,4 @@ name = "Freight Shuttle" icon_state = "shuttle2" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE diff --git a/maps/away/ships/unathi_pirate/hiskyn/unathi_pirate_hiskyn_areas.dm b/maps/away/ships/unathi_pirate/hiskyn/unathi_pirate_hiskyn_areas.dm index e8b13cd54fd..ffc59770d57 100644 --- a/maps/away/ships/unathi_pirate/hiskyn/unathi_pirate_hiskyn_areas.dm +++ b/maps/away/ships/unathi_pirate/hiskyn/unathi_pirate_hiskyn_areas.dm @@ -2,7 +2,6 @@ name = "Revanchist Ship" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/away/ships/unathi_pirate/tarwa/unathi_pirate_tarwa_areas.dm b/maps/away/ships/unathi_pirate/tarwa/unathi_pirate_tarwa_areas.dm index 4708ffa75c9..eea91f2cb44 100644 --- a/maps/away/ships/unathi_pirate/tarwa/unathi_pirate_tarwa_areas.dm +++ b/maps/away/ships/unathi_pirate/tarwa/unathi_pirate_tarwa_areas.dm @@ -2,7 +2,6 @@ name = "Tarwa Conglomerate Freighter" icon_state = "green" requires_power = 1 - dynamic_lighting = 1 no_light_control = 0 base_turf = /turf/space area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/event/generic_dock/code/generic_dock_areas.dm b/maps/event/generic_dock/code/generic_dock_areas.dm index 8712e5a1dc2..60e47e67af8 100644 --- a/maps/event/generic_dock/code/generic_dock_areas.dm +++ b/maps/event/generic_dock/code/generic_dock_areas.dm @@ -2,14 +2,12 @@ name = "Generic Dock" luminosity = 0 requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE /area/odin_departure/away name = "Generic Dock - Away" luminosity = 0 requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE /area/shuttle/administration diff --git a/maps/event/halloween/halloweenareas.dm b/maps/event/halloween/halloweenareas.dm index f5b43689153..87b6c3d101b 100644 --- a/maps/event/halloween/halloweenareas.dm +++ b/maps/event/halloween/halloweenareas.dm @@ -3,7 +3,6 @@ icon = 'icons/turf/areas.dmi' icon_state = "blue" luminosity = 0 - dynamic_lighting = 1 requires_power = 0 no_light_control = 1 @@ -11,7 +10,6 @@ name = "Cityscape" icon_state = "red" luminosity = 0 - dynamic_lighting = 1 requires_power = 0 no_light_control = 1 @@ -19,7 +17,6 @@ name = "Haunted House" icon_state = "toilet" luminosity = 0 - dynamic_lighting = 1 requires_power = 0 no_light_control = 1 ambience = AMBIENCE_TENSION @@ -28,7 +25,6 @@ name = "City Bar" icon_state = "bar" luminosity = 0 - dynamic_lighting = 1 requires_power = 0 no_light_control = 1 @@ -36,7 +32,6 @@ name = "City Kitchen" icon_state = "cafeteria" luminosity = 0 - dynamic_lighting = 1 requires_power = 0 no_light_control = 1 @@ -44,7 +39,6 @@ name = "Hotel Dining Room" icon_state = "lounge" luminosity = 0 - dynamic_lighting = 1 requires_power = 0 no_light_control = 1 @@ -52,7 +46,6 @@ name = "Spooky Park" icon_state = "green" luminosity = 0 - dynamic_lighting = 1 requires_power = 0 no_light_control = 1 @@ -60,7 +53,6 @@ name = "Tower Medical" icon_state = "medbay" luminosity = 0 - dynamic_lighting = 1 requires_power = 0 no_light_control = 1 @@ -68,7 +60,6 @@ name = "Tower Spawn" icon_state = "start" luminosity = 0 - dynamic_lighting = 1 requires_power = 0 no_light_control = 1 @@ -76,7 +67,6 @@ name = "Community Garden" icon_state = "purple" luminosity = 0 - dynamic_lighting = 1 requires_power = 0 no_light_control = 1 @@ -84,7 +74,6 @@ name = "Hotel Security" icon_state = "security" luminosity = 0 - dynamic_lighting = 1 requires_power = 0 no_light_control = 1 @@ -92,7 +81,6 @@ name = "Hotel Costumes" icon_state = "library" luminosity = 0 - dynamic_lighting = 1 requires_power = 0 no_light_control = 1 @@ -100,7 +88,6 @@ name = "Hotel Halls" icon_state = "hallC1" luminosity = 0 - dynamic_lighting = 1 requires_power = 0 no_light_control = 1 @@ -108,6 +95,5 @@ name = "Hotel Pool" icon_state = "fitness_pool" luminosity = 0 - dynamic_lighting = 1 requires_power = 0 no_light_control = 1 diff --git a/maps/event/idris_cruise/code/idris_cruise_areas.dm b/maps/event/idris_cruise/code/idris_cruise_areas.dm index 1bacf64852e..09fb15ce365 100644 --- a/maps/event/idris_cruise/code/idris_cruise_areas.dm +++ b/maps/event/idris_cruise/code/idris_cruise_areas.dm @@ -3,25 +3,24 @@ icon_state = "blue" luminosity = 0 requires_power = 0 - dynamic_lighting = 1 no_light_control = 0 /area/cruise/virtual_reality name = "Virtual Reality" icon_state = "start" - dynamic_lighting = 0 + base_lighting_alpha = 255 luminosity = 1 /area/cruise/escort name = "Conglomerate Escort" icon_state = "purple" - dynamic_lighting = 0 + base_lighting_alpha = 255 luminosity = 1 /area/cruise/tcomms_sat name = "Telecommunications Buddy Satellite" icon_state = "red" - dynamic_lighting = 0 + base_lighting_alpha = 255 luminosity = 1 /area/cruise/aft @@ -99,7 +98,7 @@ /area/cruise/beach name = "Beach Dome" icon_state = "red2" - dynamic_lighting = 0 + base_lighting_alpha = 255 luminosity = 1 /area/cruise/beach_bar diff --git a/maps/event/rooftop/code/rooftop_areas.dm b/maps/event/rooftop/code/rooftop_areas.dm index 220295db534..b74ba530246 100644 --- a/maps/event/rooftop/code/rooftop_areas.dm +++ b/maps/event/rooftop/code/rooftop_areas.dm @@ -2,7 +2,7 @@ name = "City" icon_state = "blue" luminosity = 1 - dynamic_lighting = 0 + base_lighting_alpha = 255 requires_power = 0 no_light_control = 1 @@ -13,13 +13,12 @@ name = "Mendell City Interior" luminosity = 0 requires_power = 0 - dynamic_lighting = 1 no_light_control = 0 /area/shuttle/city name = "City Transit Shuttle" base_turf = /turf/unsimulated/floor/plating luminosity = 1 - dynamic_lighting = 0 + base_lighting_alpha = 255 requires_power = 0 no_light_control = 1 diff --git a/maps/helpers/event_shuttles/eventshuttles_areas_readme.dm b/maps/helpers/event_shuttles/eventshuttles_areas_readme.dm index 5e8418cf76f..876c6272109 100644 --- a/maps/helpers/event_shuttles/eventshuttles_areas_readme.dm +++ b/maps/helpers/event_shuttles/eventshuttles_areas_readme.dm @@ -29,7 +29,6 @@ name = "SCC Transport Shuttle" icon_state = "shuttle" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE area_flags = AREA_FLAG_RAD_SHIELDED is_outside = OUTSIDE_NO diff --git a/maps/random_ruins/exoplanets/adhomai/adhomai_archeology.dm b/maps/random_ruins/exoplanets/adhomai/adhomai_archeology.dm index dce38cb30c2..4721aa3eb5d 100644 --- a/maps/random_ruins/exoplanets/adhomai/adhomai_archeology.dm +++ b/maps/random_ruins/exoplanets/adhomai/adhomai_archeology.dm @@ -17,7 +17,6 @@ name = "Adhomian Archeology Camp" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/mineral/adhomai area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/random_ruins/exoplanets/adhomai/adhomai_bar.dm b/maps/random_ruins/exoplanets/adhomai/adhomai_bar.dm index cd264b86b67..ca9c68e15b1 100644 --- a/maps/random_ruins/exoplanets/adhomai/adhomai_bar.dm +++ b/maps/random_ruins/exoplanets/adhomai/adhomai_bar.dm @@ -17,7 +17,6 @@ name = "Adhomian Inn" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/mineral/adhomai area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/random_ruins/exoplanets/adhomai/adhomai_fallout_bunker.dm b/maps/random_ruins/exoplanets/adhomai/adhomai_fallout_bunker.dm index e5d9708eab6..c217cd5ea83 100644 --- a/maps/random_ruins/exoplanets/adhomai/adhomai_fallout_bunker.dm +++ b/maps/random_ruins/exoplanets/adhomai/adhomai_fallout_bunker.dm @@ -14,7 +14,6 @@ name = "Fallout Bunker" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/mineral/adhomai area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/random_ruins/exoplanets/adhomai/adhomai_hunting.dm b/maps/random_ruins/exoplanets/adhomai/adhomai_hunting.dm index b86db631482..709c2c89766 100644 --- a/maps/random_ruins/exoplanets/adhomai/adhomai_hunting.dm +++ b/maps/random_ruins/exoplanets/adhomai/adhomai_hunting.dm @@ -17,7 +17,6 @@ name = "Adhomai Hunting Lodge" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/mineral/adhomai area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/random_ruins/exoplanets/adhomai/adhomai_nuclear_waste.dm b/maps/random_ruins/exoplanets/adhomai/adhomai_nuclear_waste.dm index cb37ddc1a67..427d8c09813 100644 --- a/maps/random_ruins/exoplanets/adhomai/adhomai_nuclear_waste.dm +++ b/maps/random_ruins/exoplanets/adhomai/adhomai_nuclear_waste.dm @@ -15,7 +15,6 @@ name = "Radioactive Waste Disposal Site" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/mineral/adhomai area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/random_ruins/exoplanets/adhomai/adhomai_nuclear_waste_makeshift.dm b/maps/random_ruins/exoplanets/adhomai/adhomai_nuclear_waste_makeshift.dm index b36beb072b7..b841ab13b7f 100644 --- a/maps/random_ruins/exoplanets/adhomai/adhomai_nuclear_waste_makeshift.dm +++ b/maps/random_ruins/exoplanets/adhomai/adhomai_nuclear_waste_makeshift.dm @@ -15,7 +15,6 @@ name = "Makeshift Radioactive Waste Disposal Site" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/mineral/adhomai area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/random_ruins/exoplanets/adhomai/adhomai_raskariim_hideout.dm b/maps/random_ruins/exoplanets/adhomai/adhomai_raskariim_hideout.dm index fc3ab33c975..a9b36bc06a0 100644 --- a/maps/random_ruins/exoplanets/adhomai/adhomai_raskariim_hideout.dm +++ b/maps/random_ruins/exoplanets/adhomai/adhomai_raskariim_hideout.dm @@ -17,7 +17,6 @@ name = "Abandoned House" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/mineral/adhomai area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/random_ruins/exoplanets/adhomai/adhomai_schlorrgo_cage.dm b/maps/random_ruins/exoplanets/adhomai/adhomai_schlorrgo_cage.dm index f2dceb5a35e..7e82e98940b 100644 --- a/maps/random_ruins/exoplanets/adhomai/adhomai_schlorrgo_cage.dm +++ b/maps/random_ruins/exoplanets/adhomai/adhomai_schlorrgo_cage.dm @@ -15,7 +15,6 @@ name = "Adhomian Schlorrgo Testing Site" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/mineral/adhomai area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/random_ruins/exoplanets/adhomai/adhomai_silo.dm b/maps/random_ruins/exoplanets/adhomai/adhomai_silo.dm index 37af37935a1..e5764de9d30 100644 --- a/maps/random_ruins/exoplanets/adhomai/adhomai_silo.dm +++ b/maps/random_ruins/exoplanets/adhomai/adhomai_silo.dm @@ -16,7 +16,6 @@ name = "Adhomian Missile Silo" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/mineral/adhomai area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/random_ruins/exoplanets/adhomai/adhomai_village.dm b/maps/random_ruins/exoplanets/adhomai/adhomai_village.dm index ba97f620e08..e7438be2e04 100644 --- a/maps/random_ruins/exoplanets/adhomai/adhomai_village.dm +++ b/maps/random_ruins/exoplanets/adhomai/adhomai_village.dm @@ -17,7 +17,6 @@ name = "Adhomian Village" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/mineral/adhomai area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/random_ruins/exoplanets/adhomai/ala_base.dm b/maps/random_ruins/exoplanets/adhomai/ala_base.dm index edbf3f7cb72..b5e16c68ddd 100644 --- a/maps/random_ruins/exoplanets/adhomai/ala_base.dm +++ b/maps/random_ruins/exoplanets/adhomai/ala_base.dm @@ -17,7 +17,6 @@ name = "ALA Military Outpost" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/mineral/adhomai area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/random_ruins/exoplanets/adhomai/nka_base.dm b/maps/random_ruins/exoplanets/adhomai/nka_base.dm index 55fd53aede2..97eb5577c0f 100644 --- a/maps/random_ruins/exoplanets/adhomai/nka_base.dm +++ b/maps/random_ruins/exoplanets/adhomai/nka_base.dm @@ -17,7 +17,6 @@ name = "NKA Military Outpost" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/mineral/adhomai area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/random_ruins/exoplanets/adhomai/pra_base.dm b/maps/random_ruins/exoplanets/adhomai/pra_base.dm index 021f8e71f96..f1a0da63194 100644 --- a/maps/random_ruins/exoplanets/adhomai/pra_base.dm +++ b/maps/random_ruins/exoplanets/adhomai/pra_base.dm @@ -17,7 +17,6 @@ name = "PRA Military Outpost" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/mineral/adhomai area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/random_ruins/exoplanets/adhomai/pra_mining_camp.dm b/maps/random_ruins/exoplanets/adhomai/pra_mining_camp.dm index fb08a0a2194..a45db16ef4b 100644 --- a/maps/random_ruins/exoplanets/adhomai/pra_mining_camp.dm +++ b/maps/random_ruins/exoplanets/adhomai/pra_mining_camp.dm @@ -17,7 +17,6 @@ name = "People's Republic Mining Camp" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/mineral/adhomai area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/random_ruins/exoplanets/adhomai/psis_outpost.dm b/maps/random_ruins/exoplanets/adhomai/psis_outpost.dm index 76a6be05a22..c194edad644 100644 --- a/maps/random_ruins/exoplanets/adhomai/psis_outpost.dm +++ b/maps/random_ruins/exoplanets/adhomai/psis_outpost.dm @@ -17,7 +17,6 @@ name = "PSIS Outpost" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/mineral/adhomai area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/random_ruins/exoplanets/asteroid/abandoned_prison/abandoned_prison.dm b/maps/random_ruins/exoplanets/asteroid/abandoned_prison/abandoned_prison.dm index 60e49c497e5..5abdb360a8b 100644 --- a/maps/random_ruins/exoplanets/asteroid/abandoned_prison/abandoned_prison.dm +++ b/maps/random_ruins/exoplanets/asteroid/abandoned_prison/abandoned_prison.dm @@ -18,7 +18,6 @@ name = "abandoned prison" icon_state = "unknown" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = TRUE is_outside = OUTSIDE_NO diff --git a/maps/random_ruins/exoplanets/asteroid/coalition_base/coalition_base.dm b/maps/random_ruins/exoplanets/asteroid/coalition_base/coalition_base.dm index 6cde1e5b80c..652972b816f 100644 --- a/maps/random_ruins/exoplanets/asteroid/coalition_base/coalition_base.dm +++ b/maps/random_ruins/exoplanets/asteroid/coalition_base/coalition_base.dm @@ -17,7 +17,6 @@ name = "coalition base" icon_state = "unknown" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = TRUE is_outside = OUTSIDE_NO diff --git a/maps/random_ruins/exoplanets/asteroid/listening_post/listening_post_unique.dm b/maps/random_ruins/exoplanets/asteroid/listening_post/listening_post_unique.dm index 4bf0f585350..4ab4698b274 100644 --- a/maps/random_ruins/exoplanets/asteroid/listening_post/listening_post_unique.dm +++ b/maps/random_ruins/exoplanets/asteroid/listening_post/listening_post_unique.dm @@ -20,7 +20,6 @@ name = "Listening Post Installation" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = TRUE is_outside = OUTSIDE_NO diff --git a/maps/random_ruins/exoplanets/biesel/biesel_camp_site.dm b/maps/random_ruins/exoplanets/biesel/biesel_camp_site.dm index 82007433ebe..8971d3a6959 100644 --- a/maps/random_ruins/exoplanets/biesel/biesel_camp_site.dm +++ b/maps/random_ruins/exoplanets/biesel/biesel_camp_site.dm @@ -15,7 +15,6 @@ name = "Biesel Camp Site" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE ambience = list('sound/effects/wind/wind_2_1.ogg','sound/effects/wind/wind_2_2.ogg','sound/effects/wind/wind_3_1.ogg','sound/effects/wind/wind_4_1.ogg') diff --git a/maps/random_ruins/exoplanets/burzsia/burzsia_mining.dm b/maps/random_ruins/exoplanets/burzsia/burzsia_mining.dm index 7f850654355..5dda6393dca 100644 --- a/maps/random_ruins/exoplanets/burzsia/burzsia_mining.dm +++ b/maps/random_ruins/exoplanets/burzsia/burzsia_mining.dm @@ -17,7 +17,6 @@ name = "Hephaestus Burzsia Mining Outpost" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/barren area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/random_ruins/exoplanets/desert/desert.dm b/maps/random_ruins/exoplanets/desert/desert.dm index a962e5e3cf6..682d79079dd 100644 --- a/maps/random_ruins/exoplanets/desert/desert.dm +++ b/maps/random_ruins/exoplanets/desert/desert.dm @@ -70,5 +70,4 @@ name = "Abandoned Solarian Relay Station" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE diff --git a/maps/random_ruins/exoplanets/grove/grove.dm b/maps/random_ruins/exoplanets/grove/grove.dm index 713f3cec9fc..03feb4f5d6f 100644 --- a/maps/random_ruins/exoplanets/grove/grove.dm +++ b/maps/random_ruins/exoplanets/grove/grove.dm @@ -53,7 +53,6 @@ name = "System Defence Force Outpost" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE area_flags = AREA_FLAG_HIDE_FROM_HOLOMAP | AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/haneunim/haneunim_mining.dm b/maps/random_ruins/exoplanets/haneunim/haneunim_mining.dm index fc2db02f867..11f5de918af 100644 --- a/maps/random_ruins/exoplanets/haneunim/haneunim_mining.dm +++ b/maps/random_ruins/exoplanets/haneunim/haneunim_mining.dm @@ -15,6 +15,5 @@ name = "Haneunim Mining Outpost" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE area_flags = AREA_FLAG_RAD_SHIELDED | AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/konyang/fireoutpost.dm b/maps/random_ruins/exoplanets/konyang/fireoutpost.dm index cde66db6147..24844489cb7 100644 --- a/maps/random_ruins/exoplanets/konyang/fireoutpost.dm +++ b/maps/random_ruins/exoplanets/konyang/fireoutpost.dm @@ -15,7 +15,6 @@ name = "Konyang Firewatch Post" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE ambience = list('sound/effects/wind/wind_2_1.ogg','sound/effects/wind/wind_2_2.ogg','sound/effects/wind/wind_3_1.ogg','sound/effects/wind/wind_4_1.ogg','sound/ambience/eeriejungle2.ogg','sound/ambience/eeriejungle1.ogg') diff --git a/maps/random_ruins/exoplanets/konyang/hivebot_burrows_1.dm b/maps/random_ruins/exoplanets/konyang/hivebot_burrows_1.dm index 2d34d137ef7..5cc33d27eb4 100644 --- a/maps/random_ruins/exoplanets/konyang/hivebot_burrows_1.dm +++ b/maps/random_ruins/exoplanets/konyang/hivebot_burrows_1.dm @@ -17,7 +17,6 @@ name = "Abandoned Mineshaft" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE base_turf = /turf/simulated/floor/exoplanet/basalt/cave area_flags = AREA_FLAG_HIDE_FROM_HOLOMAP | AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/konyang/hivebot_burrows_2.dm b/maps/random_ruins/exoplanets/konyang/hivebot_burrows_2.dm index 970092b36f0..45fca4fa863 100644 --- a/maps/random_ruins/exoplanets/konyang/hivebot_burrows_2.dm +++ b/maps/random_ruins/exoplanets/konyang/hivebot_burrows_2.dm @@ -17,7 +17,6 @@ name = "Derelict Archaelogy Outpost" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE base_turf = /turf/simulated/floor/exoplanet/basalt/cave area_flags = AREA_FLAG_HIDE_FROM_HOLOMAP | AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/konyang/homestead.dm b/maps/random_ruins/exoplanets/konyang/homestead.dm index a2f4bb808ce..c0ecda0a35e 100644 --- a/maps/random_ruins/exoplanets/konyang/homestead.dm +++ b/maps/random_ruins/exoplanets/konyang/homestead.dm @@ -15,7 +15,6 @@ name = "Konyang Homestead" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE ambience = list('sound/effects/wind/wind_2_1.ogg','sound/effects/wind/wind_2_2.ogg','sound/effects/wind/wind_3_1.ogg','sound/effects/wind/wind_4_1.ogg','sound/ambience/eeriejungle2.ogg','sound/ambience/eeriejungle1.ogg') diff --git a/maps/random_ruins/exoplanets/konyang/landing_zone.dm b/maps/random_ruins/exoplanets/konyang/landing_zone.dm index 19fcaa2babd..2132afdcde0 100644 --- a/maps/random_ruins/exoplanets/konyang/landing_zone.dm +++ b/maps/random_ruins/exoplanets/konyang/landing_zone.dm @@ -15,7 +15,6 @@ name = "SCC Expedition Command Center" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/mineral area_flags = AREA_FLAG_HIDE_FROM_HOLOMAP | AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/konyang/pirate_moonshine.dm b/maps/random_ruins/exoplanets/konyang/pirate_moonshine.dm index 82072c1d5b6..bb9a742f1d1 100644 --- a/maps/random_ruins/exoplanets/konyang/pirate_moonshine.dm +++ b/maps/random_ruins/exoplanets/konyang/pirate_moonshine.dm @@ -18,7 +18,6 @@ name = "Konyang Moonshiner Den" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/mineral area_flags = AREA_FLAG_HIDE_FROM_HOLOMAP | AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/konyang/pirate_outpost.dm b/maps/random_ruins/exoplanets/konyang/pirate_outpost.dm index 804b877654f..e7a16337caf 100644 --- a/maps/random_ruins/exoplanets/konyang/pirate_outpost.dm +++ b/maps/random_ruins/exoplanets/konyang/pirate_outpost.dm @@ -19,7 +19,6 @@ name = "Konyang Pirate Outpost" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/mineral area_flags = AREA_FLAG_HIDE_FROM_HOLOMAP | AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/konyang/swamp_4.dm b/maps/random_ruins/exoplanets/konyang/swamp_4.dm index 3c28cf08a03..7228911366f 100644 --- a/maps/random_ruins/exoplanets/konyang/swamp_4.dm +++ b/maps/random_ruins/exoplanets/konyang/swamp_4.dm @@ -15,7 +15,6 @@ name = "Swamp Grill" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE ambience = list('sound/effects/wind/wind_2_1.ogg','sound/effects/wind/wind_2_2.ogg','sound/effects/wind/wind_3_1.ogg','sound/effects/wind/wind_4_1.ogg','sound/ambience/eeriejungle2.ogg','sound/ambience/eeriejungle1.ogg') diff --git a/maps/random_ruins/exoplanets/konyang/telecomms_outpost.dm b/maps/random_ruins/exoplanets/konyang/telecomms_outpost.dm index eb8f42710dd..4565e787e2e 100644 --- a/maps/random_ruins/exoplanets/konyang/telecomms_outpost.dm +++ b/maps/random_ruins/exoplanets/konyang/telecomms_outpost.dm @@ -19,7 +19,6 @@ name = "Konyang Telecomms Outpost" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/mineral area_flags = AREA_FLAG_HIDE_FROM_HOLOMAP | AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/konyang/village.dm b/maps/random_ruins/exoplanets/konyang/village.dm index 3dc5653df75..1b60f436091 100644 --- a/maps/random_ruins/exoplanets/konyang/village.dm +++ b/maps/random_ruins/exoplanets/konyang/village.dm @@ -19,7 +19,6 @@ name = "Konyang Village" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/mineral area_flags = AREA_FLAG_HIDE_FROM_HOLOMAP | AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/moghes/moghes_bar.dm b/maps/random_ruins/exoplanets/moghes/moghes_bar.dm index f57a0fd10fc..165b62e611d 100644 --- a/maps/random_ruins/exoplanets/moghes/moghes_bar.dm +++ b/maps/random_ruins/exoplanets/moghes/moghes_bar.dm @@ -16,7 +16,6 @@ name = "Moghes Bar" icon_state = "bar" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE is_outside = OUTSIDE_NO base_turf = /turf/simulated/floor/exoplanet/grass/moghes/dirt diff --git a/maps/random_ruins/exoplanets/moghes/moghes_diona_traders.dm b/maps/random_ruins/exoplanets/moghes/moghes_diona_traders.dm index b22c2fe5bd7..93b67f03c34 100644 --- a/maps/random_ruins/exoplanets/moghes/moghes_diona_traders.dm +++ b/maps/random_ruins/exoplanets/moghes/moghes_diona_traders.dm @@ -16,7 +16,6 @@ name = "Diona Trader Office" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/grass/moghes/dirt area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/moghes/moghes_gawgaryn_bikers.dm b/maps/random_ruins/exoplanets/moghes/moghes_gawgaryn_bikers.dm index b40a369f5d2..dfea08cc1cc 100644 --- a/maps/random_ruins/exoplanets/moghes/moghes_gawgaryn_bikers.dm +++ b/maps/random_ruins/exoplanets/moghes/moghes_gawgaryn_bikers.dm @@ -16,7 +16,6 @@ name = "Gawgaryn Raider Camp" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/desert area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/moghes/moghes_guild_mining.dm b/maps/random_ruins/exoplanets/moghes/moghes_guild_mining.dm index 8da49fd7742..b485a8b9954 100644 --- a/maps/random_ruins/exoplanets/moghes/moghes_guild_mining.dm +++ b/maps/random_ruins/exoplanets/moghes/moghes_guild_mining.dm @@ -14,7 +14,6 @@ name = "Miners' Guild Camp" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/grass/moghes/dirt area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/moghes/moghes_hegemony_base.dm b/maps/random_ruins/exoplanets/moghes/moghes_hegemony_base.dm index 46c4e6aa34d..4be429e0feb 100644 --- a/maps/random_ruins/exoplanets/moghes/moghes_hegemony_base.dm +++ b/maps/random_ruins/exoplanets/moghes/moghes_hegemony_base.dm @@ -15,7 +15,6 @@ name = "Hegemony Base" icon_state = "red" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE is_outside = OUTSIDE_NO base_turf = /turf/simulated/floor/exoplanet/grass/moghes/dirt diff --git a/maps/random_ruins/exoplanets/moghes/moghes_heph_mining.dm b/maps/random_ruins/exoplanets/moghes/moghes_heph_mining.dm index 8cb014e35ba..1232813bc61 100644 --- a/maps/random_ruins/exoplanets/moghes/moghes_heph_mining.dm +++ b/maps/random_ruins/exoplanets/moghes/moghes_heph_mining.dm @@ -16,7 +16,6 @@ name = "Hephaestus Mining Camp" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/grass/moghes/dirt area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/moghes/moghes_kataphract_wasteland.dm b/maps/random_ruins/exoplanets/moghes/moghes_kataphract_wasteland.dm index 36d3b319ebb..6e8b53225ae 100644 --- a/maps/random_ruins/exoplanets/moghes/moghes_kataphract_wasteland.dm +++ b/maps/random_ruins/exoplanets/moghes/moghes_kataphract_wasteland.dm @@ -15,7 +15,6 @@ name = "Kataphract Campsite" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/desert area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/moghes/moghes_skakh.dm b/maps/random_ruins/exoplanets/moghes/moghes_skakh.dm index ee45e51a13d..4be2415825b 100644 --- a/maps/random_ruins/exoplanets/moghes/moghes_skakh.dm +++ b/maps/random_ruins/exoplanets/moghes/moghes_skakh.dm @@ -16,7 +16,6 @@ name = "Moghes - Sk'akh Chapel" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/grass/moghes/dirt area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/moghes/moghes_thakh.dm b/maps/random_ruins/exoplanets/moghes/moghes_thakh.dm index 2a32bb3818f..99ead7c75de 100644 --- a/maps/random_ruins/exoplanets/moghes/moghes_thakh.dm +++ b/maps/random_ruins/exoplanets/moghes/moghes_thakh.dm @@ -16,7 +16,6 @@ name = "Moghes - Th'akh Shrine" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/grass/moghes/dirt area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/moghes/moghes_untouched_village.dm b/maps/random_ruins/exoplanets/moghes/moghes_untouched_village.dm index 87c2ec43c7a..07d6699f4c7 100644 --- a/maps/random_ruins/exoplanets/moghes/moghes_untouched_village.dm +++ b/maps/random_ruins/exoplanets/moghes/moghes_untouched_village.dm @@ -17,7 +17,6 @@ name = "Moghes Village" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/grass/moghes/dirt area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/moghes/moghes_wasteland_dorviza.dm b/maps/random_ruins/exoplanets/moghes/moghes_wasteland_dorviza.dm index e85cc08d105..ea6892f304d 100644 --- a/maps/random_ruins/exoplanets/moghes/moghes_wasteland_dorviza.dm +++ b/maps/random_ruins/exoplanets/moghes/moghes_wasteland_dorviza.dm @@ -15,7 +15,6 @@ name = "Clan Dorviza Camp" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/desert area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/moghes/moghes_wasteland_izwesk.dm b/maps/random_ruins/exoplanets/moghes/moghes_wasteland_izwesk.dm index 01cf4a957fd..a2d725a0c63 100644 --- a/maps/random_ruins/exoplanets/moghes/moghes_wasteland_izwesk.dm +++ b/maps/random_ruins/exoplanets/moghes/moghes_wasteland_izwesk.dm @@ -15,7 +15,6 @@ name = "Hegemony Wasteland Outpost" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE is_outside = OUTSIDE_NO base_turf = /turf/simulated/floor/exoplanet/desert diff --git a/maps/random_ruins/exoplanets/moghes/moghes_wasteland_klax.dm b/maps/random_ruins/exoplanets/moghes/moghes_wasteland_klax.dm index 4b2763526f1..60e1e9af6b1 100644 --- a/maps/random_ruins/exoplanets/moghes/moghes_wasteland_klax.dm +++ b/maps/random_ruins/exoplanets/moghes/moghes_wasteland_klax.dm @@ -15,7 +15,6 @@ name = "K'laxan Research Outpost" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE is_outside = OUTSIDE_NO base_turf = /turf/simulated/floor/exoplanet/desert diff --git a/maps/random_ruins/exoplanets/moghes/moghes_wasteland_mikuetz.dm b/maps/random_ruins/exoplanets/moghes/moghes_wasteland_mikuetz.dm index 9a5869603ad..35471259dd5 100644 --- a/maps/random_ruins/exoplanets/moghes/moghes_wasteland_mikuetz.dm +++ b/maps/random_ruins/exoplanets/moghes/moghes_wasteland_mikuetz.dm @@ -14,7 +14,6 @@ name = "Mi'kuetz Camp" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/desert area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/moghes/moghes_wasteland_ozeuoi.dm b/maps/random_ruins/exoplanets/moghes/moghes_wasteland_ozeuoi.dm index 8bfc0c4ebc4..a9ccfa9d7fb 100644 --- a/maps/random_ruins/exoplanets/moghes/moghes_wasteland_ozeuoi.dm +++ b/maps/random_ruins/exoplanets/moghes/moghes_wasteland_ozeuoi.dm @@ -15,7 +15,6 @@ name = "Clan Ozeuoi Outpost" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/desert area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/moghes/moghes_wasteland_priests.dm b/maps/random_ruins/exoplanets/moghes/moghes_wasteland_priests.dm index 293eea947ab..63f75766d5d 100644 --- a/maps/random_ruins/exoplanets/moghes/moghes_wasteland_priests.dm +++ b/maps/random_ruins/exoplanets/moghes/moghes_wasteland_priests.dm @@ -15,7 +15,6 @@ name = "Moghes - Sk'akh Wasteland Outpost" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/desert area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/moghes/moghes_wasteland_queendom.dm b/maps/random_ruins/exoplanets/moghes/moghes_wasteland_queendom.dm index cf6fb7090e8..87daff3c7da 100644 --- a/maps/random_ruins/exoplanets/moghes/moghes_wasteland_queendom.dm +++ b/maps/random_ruins/exoplanets/moghes/moghes_wasteland_queendom.dm @@ -15,7 +15,6 @@ name = "Queendom Patrol Camp" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE is_outside = OUTSIDE_NO base_turf = /turf/simulated/floor/exoplanet/desert diff --git a/maps/random_ruins/exoplanets/moghes/moghes_wasteland_reclaimer.dm b/maps/random_ruins/exoplanets/moghes/moghes_wasteland_reclaimer.dm index 6ea8d04eca5..aeafedc949f 100644 --- a/maps/random_ruins/exoplanets/moghes/moghes_wasteland_reclaimer.dm +++ b/maps/random_ruins/exoplanets/moghes/moghes_wasteland_reclaimer.dm @@ -15,7 +15,6 @@ name = "Reclaimer Salvage Camp" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/desert area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/moghes/moghes_wasteland_tomb.dm b/maps/random_ruins/exoplanets/moghes/moghes_wasteland_tomb.dm index abf4549cc3b..8515ade19ce 100644 --- a/maps/random_ruins/exoplanets/moghes/moghes_wasteland_tomb.dm +++ b/maps/random_ruins/exoplanets/moghes/moghes_wasteland_tomb.dm @@ -13,7 +13,6 @@ icon_state = "bluenew" requires_power = FALSE ambience = AMBIENCE_RUINS - dynamic_lighting = TRUE no_light_control = FALSE is_outside = OUTSIDE_NO area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/moghes/moghes_wasteland_vihnmes.dm b/maps/random_ruins/exoplanets/moghes/moghes_wasteland_vihnmes.dm index 0c22079e16b..1d9b1f5e1a5 100644 --- a/maps/random_ruins/exoplanets/moghes/moghes_wasteland_vihnmes.dm +++ b/maps/random_ruins/exoplanets/moghes/moghes_wasteland_vihnmes.dm @@ -16,7 +16,6 @@ name = "Clan Vihnmes Waystation" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE is_outside = OUTSIDE_NO base_turf = /turf/simulated/floor/exoplanet/desert diff --git a/maps/random_ruins/exoplanets/new_gibson/gibson_resupply.dm b/maps/random_ruins/exoplanets/new_gibson/gibson_resupply.dm index 174995b92cf..dcab0ba041b 100644 --- a/maps/random_ruins/exoplanets/new_gibson/gibson_resupply.dm +++ b/maps/random_ruins/exoplanets/new_gibson/gibson_resupply.dm @@ -15,6 +15,5 @@ name = "New Gibson Supply Outpost" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/snow diff --git a/maps/random_ruins/exoplanets/ouerea/ouerea_autakh.dm b/maps/random_ruins/exoplanets/ouerea/ouerea_autakh.dm index 87d39cc6618..1f9a9af5e35 100644 --- a/maps/random_ruins/exoplanets/ouerea/ouerea_autakh.dm +++ b/maps/random_ruins/exoplanets/ouerea/ouerea_autakh.dm @@ -13,7 +13,6 @@ name = "Aut'akh Compound" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/barren area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/ouerea/ouerea_bar.dm b/maps/random_ruins/exoplanets/ouerea/ouerea_bar.dm index 0d1a77c9425..6eb1a708131 100644 --- a/maps/random_ruins/exoplanets/ouerea/ouerea_bar.dm +++ b/maps/random_ruins/exoplanets/ouerea/ouerea_bar.dm @@ -14,7 +14,6 @@ name = "Ouerea Bar" icon_state = "bar" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/barren area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/ouerea/ouerea_farm.dm b/maps/random_ruins/exoplanets/ouerea/ouerea_farm.dm index e17c5202a09..e555a5f77bf 100644 --- a/maps/random_ruins/exoplanets/ouerea/ouerea_farm.dm +++ b/maps/random_ruins/exoplanets/ouerea/ouerea_farm.dm @@ -14,7 +14,6 @@ name = "Ouerea Farm" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/barren area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/ouerea/ouerea_freewater.dm b/maps/random_ruins/exoplanets/ouerea/ouerea_freewater.dm index 50dcd5c0695..ee1b7a55167 100644 --- a/maps/random_ruins/exoplanets/ouerea/ouerea_freewater.dm +++ b/maps/random_ruins/exoplanets/ouerea/ouerea_freewater.dm @@ -13,7 +13,6 @@ name = "Freewater Camp" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/barren area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/ouerea/ouerea_guild_mining.dm b/maps/random_ruins/exoplanets/ouerea/ouerea_guild_mining.dm index 2022d0dd6f7..2bb15fcab3b 100644 --- a/maps/random_ruins/exoplanets/ouerea/ouerea_guild_mining.dm +++ b/maps/random_ruins/exoplanets/ouerea/ouerea_guild_mining.dm @@ -15,7 +15,6 @@ name = "Miners' Guild Camp" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/barren area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/ouerea/ouerea_hegemony_base.dm b/maps/random_ruins/exoplanets/ouerea/ouerea_hegemony_base.dm index c5e70d37257..4fe92bdd2f3 100644 --- a/maps/random_ruins/exoplanets/ouerea/ouerea_hegemony_base.dm +++ b/maps/random_ruins/exoplanets/ouerea/ouerea_hegemony_base.dm @@ -14,7 +14,6 @@ name = "Hegemony Base" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE is_outside = OUTSIDE_NO base_turf = /turf/simulated/floor/exoplanet/barren diff --git a/maps/random_ruins/exoplanets/ouerea/ouerea_heph_mining.dm b/maps/random_ruins/exoplanets/ouerea/ouerea_heph_mining.dm index 1dd28b90298..cc349a95876 100644 --- a/maps/random_ruins/exoplanets/ouerea/ouerea_heph_mining.dm +++ b/maps/random_ruins/exoplanets/ouerea/ouerea_heph_mining.dm @@ -15,7 +15,6 @@ name = "Hephaestus Mining Camp" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/barren area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/ouerea/ouerea_nt_ruin.dm b/maps/random_ruins/exoplanets/ouerea/ouerea_nt_ruin.dm index 1af48875362..fd3762b3579 100644 --- a/maps/random_ruins/exoplanets/ouerea/ouerea_nt_ruin.dm +++ b/maps/random_ruins/exoplanets/ouerea/ouerea_nt_ruin.dm @@ -12,7 +12,6 @@ name = "NanoTrasen Facility" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/barren area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/ouerea/ouerea_skrell_base.dm b/maps/random_ruins/exoplanets/ouerea/ouerea_skrell_base.dm index 1ae9a94cd1c..3b83e8502aa 100644 --- a/maps/random_ruins/exoplanets/ouerea/ouerea_skrell_base.dm +++ b/maps/random_ruins/exoplanets/ouerea/ouerea_skrell_base.dm @@ -12,7 +12,6 @@ name = "Nralakk Research Base" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/barren area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/ouerea/ouerea_sol_base.dm b/maps/random_ruins/exoplanets/ouerea/ouerea_sol_base.dm index 395af54cfca..89828bf4baa 100644 --- a/maps/random_ruins/exoplanets/ouerea/ouerea_sol_base.dm +++ b/maps/random_ruins/exoplanets/ouerea/ouerea_sol_base.dm @@ -12,7 +12,6 @@ name = "Solarian Shuttle Port" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/barren area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/ouerea/ouerea_village.dm b/maps/random_ruins/exoplanets/ouerea/ouerea_village.dm index 45141a68700..4e3f1484cf3 100644 --- a/maps/random_ruins/exoplanets/ouerea/ouerea_village.dm +++ b/maps/random_ruins/exoplanets/ouerea/ouerea_village.dm @@ -14,7 +14,6 @@ name = "Ouerea Village" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/barren area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/raskara/raskara_okon.dm b/maps/random_ruins/exoplanets/raskara/raskara_okon.dm index 341627fcbbe..cc1275a6b0c 100644 --- a/maps/random_ruins/exoplanets/raskara/raskara_okon.dm +++ b/maps/random_ruins/exoplanets/raskara/raskara_okon.dm @@ -15,7 +15,6 @@ name = "Okon 001" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/barren/raskara area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/random_ruins/exoplanets/uueoaesa/heph_mining_station.dm b/maps/random_ruins/exoplanets/uueoaesa/heph_mining_station.dm index b440d11ca57..07c7a22f7ae 100644 --- a/maps/random_ruins/exoplanets/uueoaesa/heph_mining_station.dm +++ b/maps/random_ruins/exoplanets/uueoaesa/heph_mining_station.dm @@ -15,7 +15,6 @@ name = "Hephaestus Mining Station" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/barren area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/uueoaesa/heph_survey_post.dm b/maps/random_ruins/exoplanets/uueoaesa/heph_survey_post.dm index be4aa0824cb..f7ab5b95f10 100644 --- a/maps/random_ruins/exoplanets/uueoaesa/heph_survey_post.dm +++ b/maps/random_ruins/exoplanets/uueoaesa/heph_survey_post.dm @@ -13,7 +13,6 @@ name = "Hephaestus Survey Post" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/plating area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/uueoaesa/miners_guild_outpost.dm b/maps/random_ruins/exoplanets/uueoaesa/miners_guild_outpost.dm index 8357216b96e..419fed381e3 100644 --- a/maps/random_ruins/exoplanets/uueoaesa/miners_guild_outpost.dm +++ b/maps/random_ruins/exoplanets/uueoaesa/miners_guild_outpost.dm @@ -15,7 +15,6 @@ name = "Miners' Guild Outpost" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/barren area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/random_ruins/exoplanets/uueoaesa/pid_kois_farm.dm b/maps/random_ruins/exoplanets/uueoaesa/pid_kois_farm.dm index dd364268a2c..80371545753 100644 --- a/maps/random_ruins/exoplanets/uueoaesa/pid_kois_farm.dm +++ b/maps/random_ruins/exoplanets/uueoaesa/pid_kois_farm.dm @@ -13,7 +13,6 @@ name = "K'lax Farm" icon_state = "bluenew" requires_power = FALSE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/barren area_flags = AREA_FLAG_RAD_SHIELDED diff --git a/maps/random_ruins/exoplanets/uueoaesa/sol_listening_post.dm b/maps/random_ruins/exoplanets/uueoaesa/sol_listening_post.dm index 770131c418a..6170a53226a 100644 --- a/maps/random_ruins/exoplanets/uueoaesa/sol_listening_post.dm +++ b/maps/random_ruins/exoplanets/uueoaesa/sol_listening_post.dm @@ -13,7 +13,6 @@ name = "Solarian Listening Post" icon_state = "bluenew" requires_power = TRUE - dynamic_lighting = TRUE no_light_control = FALSE base_turf = /turf/simulated/floor/exoplanet/barren area_flags = AREA_FLAG_RAD_SHIELDED|AREA_FLAG_INDESTRUCTIBLE_TURFS diff --git a/maps/sccv_horizon/areas/_horizon_areas.dm b/maps/sccv_horizon/areas/_horizon_areas.dm index 1cd665e77f0..3d470a50a63 100644 --- a/maps/sccv_horizon/areas/_horizon_areas.dm +++ b/maps/sccv_horizon/areas/_horizon_areas.dm @@ -37,7 +37,6 @@ name = "Horizon - Exterior" icon_state = "exterior" base_turf = /turf/space - dynamic_lighting = TRUE requires_power = FALSE // This area will place starlight on any turf it's put on! needs_starlight = TRUE diff --git a/maps/sccv_horizon/areas/horizon_areas_holodeck.dm b/maps/sccv_horizon/areas/horizon_areas_holodeck.dm index c9cd888fd9a..61e4704c461 100644 --- a/maps/sccv_horizon/areas/horizon_areas_holodeck.dm +++ b/maps/sccv_horizon/areas/horizon_areas_holodeck.dm @@ -15,7 +15,7 @@ icon_state = "Holodeck" sound_environment = SOUND_AREA_LARGE_ENCLOSED no_light_control = TRUE - dynamic_lighting = FALSE + base_lighting_alpha = 255 area_flags = AREA_FLAG_RAD_SHIELDED | AREA_FLAG_NO_GHOST_TELEPORT_ACCESS holomap_color = HOLOMAP_AREACOLOR_CIVILIAN horizon_deck = 3 @@ -24,11 +24,11 @@ /area/horizon/holodeck/alphadeck name = "Holodeck Alpha" - dynamic_lighting = TRUE + base_lighting_alpha = 0 /area/horizon/holodeck/betadeck name = "Holodeck Beta" - dynamic_lighting = TRUE + base_lighting_alpha = 0 /area/horizon/holodeck/source_plating name = "Holodeck - Off" diff --git a/maps/sccv_horizon/sccv_horizon.dmm b/maps/sccv_horizon/sccv_horizon.dmm index 6d7db5ac968..a0ec6ebf51f 100644 --- a/maps/sccv_horizon/sccv_horizon.dmm +++ b/maps/sccv_horizon/sccv_horizon.dmm @@ -18776,7 +18776,6 @@ icon_state = "door_locked"; name = "external airlock"; opacity = 0; - permit_ao = 0; pixel_x = -16; pixel_y = -16 }, @@ -38085,7 +38084,6 @@ icon_state = "door_locked"; name = "external airlock"; opacity = 0; - permit_ao = 0; dir = 4; pixel_x = -16; pixel_y = -16 @@ -51277,8 +51275,7 @@ /turf/unsimulated/wall/fakepdoor{ icon_state = "shutter1"; name = "shutter"; - opacity = 0; - permit_ao = 0 + opacity = 0 }, /area/antag/raider) "gTb" = ( @@ -52036,7 +52033,6 @@ "gYM" = ( /obj/machinery/light/small{ brightness_power = 0.5; - brightness_range = 4; dir = 8; name = "adjusted light fixture" }, diff --git a/tools/ci/check_grep.sh b/tools/ci/check_grep.sh index 93dda77e233..f50fd048a99 100755 --- a/tools/ci/check_grep.sh +++ b/tools/ci/check_grep.sh @@ -200,7 +200,7 @@ echo "Verifying no new unmanaged globals are being added" >> code_error.log UNMANAGED_GLOBAL_VARS_REGEXP='^/*var/' UNMANAGED_GLOBAL_VARS_COUNT=`grep -r -o --include \*.dm -P --regexp=$UNMANAGED_GLOBAL_VARS_REGEXP | wc -l` -if [[ $UNMANAGED_GLOBAL_VARS_COUNT -ne 180 ]]; then # THE COUNT CAN ONLY BE DECREASED, NEVER INCREASED +if [[ $UNMANAGED_GLOBAL_VARS_COUNT -ne 176 ]]; then # THE COUNT CAN ONLY BE DECREASED, NEVER INCREASED ERROR_COUNT=$(($ERROR_COUNT+1)) echo "FAIL: New unmanaged global vars, found $UNMANAGED_GLOBAL_VARS_COUNT of them! Use GLOB or update the count ONLY IF YOU ARE REMOVING THEM!" >> code_error.log grep -r --include \*.dm -P --regexp=$UNMANAGED_GLOBAL_VARS_REGEXP >> code_error.log