mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-23 04:51:32 +01:00
Replaces our lighting system with CM's. (#21465)
Depends on #21458. Ports https://github.com/cmss13-devs/cmss13/pull/4229, with the original authors as: - https://github.com/tgstation/TerraGov-Marine-Corps/pull/1964 for the lighting controller (A-lexa) - https://github.com/tgstation/TerraGov-Marine-Corps/pull/4747 and https://github.com/tgstation/TerraGov-Marine-Corps/pull/7263 for the lighting (TiviPlus) - https://github.com/tgstation/tgstation/pull/54520 for the dir lighting component - https://github.com/tgstation/tgstation/pull/75018 for the out of bounds fix in lighting - https://github.com/tgstation/TerraGov-Marine-Corps/pull/6678 for the emissives (TiviPlus) The main driving reason behind this is that current lighting consumes way too much processing power, especially for things like odysseys/away sites where a billion light sources are processing/moving at once and the game slows down to a crawl. Hopefully this improves the situation by a good margin, but we will need some testmerging to confirm that. <img width="1349" height="1349" alt="image" src="https://github.com/user-attachments/assets/1059ba2b-c0c5-495a-9c76-2d75d0c42bf2" /> <img width="1349" height="1349" alt="image" src="https://github.com/user-attachments/assets/9704b0f6-4cf6-4dfd-a6cb-5702ad07d677" /> - [x] Resolve todos - [x] Look into open space fuckery (border objects) --------- Co-authored-by: Matt Atlas <liermattia@gmail.com> Co-authored-by: JohnWildkins <john.wildkins@gmail.com>
This commit is contained in:
co-authored by
Matt Atlas
JohnWildkins
parent
8ebd7c9ad5
commit
94d92803b4
+14
-16
@@ -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"
|
||||
|
||||
+3
-3
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
+29
-12
@@ -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)
|
||||
|
||||
|
||||
+114
-94
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<X2)
|
||||
b+=m
|
||||
while(X1 != X2 || Y1 != Y2)
|
||||
if(round(m*X1+b-Y1))
|
||||
while(X1!=X2 || Y1!=Y2)
|
||||
if(floor(m*X1+b-Y1))
|
||||
Y1+=signY //Line exits tile vertically
|
||||
else
|
||||
X1+=signX //Line exits tile horizontally
|
||||
T=locate(X1,Y1,Z)
|
||||
if(IS_OPAQUE_TURF(T))
|
||||
return FALSE
|
||||
if(T.opacity)
|
||||
return 0
|
||||
return TRUE
|
||||
|
||||
|
||||
/proc/is_in_sight(atom/first_atom, atom/second_atom)
|
||||
var/turf/first_turf = get_turf(first_atom)
|
||||
var/turf/second_turf = get_turf(second_atom)
|
||||
|
||||
@@ -160,6 +160,7 @@
|
||||
source.change_area(source.loc, base_area)
|
||||
else
|
||||
. += transport_turf_contents(source, target, ignore_background)
|
||||
|
||||
//change the old turfs
|
||||
for(var/turf/source in translation)
|
||||
if(ignore_background && (source.turf_flags & TURF_FLAG_BACKGROUND))
|
||||
|
||||
@@ -1206,3 +1206,35 @@ GLOBAL_LIST_INIT(wall_items, typecacheof(list(
|
||||
c_dist++
|
||||
|
||||
return L
|
||||
|
||||
/proc/get_turf_pixel(atom/AM)
|
||||
if(!istype(AM))
|
||||
return
|
||||
|
||||
//Find AM's matrix so we can use it's X/Y pixel shifts
|
||||
var/matrix/M = matrix(AM.transform)
|
||||
|
||||
var/pixel_x_offset = AM.pixel_x + M.get_x_shift()
|
||||
var/pixel_y_offset = AM.pixel_y + M.get_y_shift()
|
||||
|
||||
//Irregular objects
|
||||
var/icon/AMicon = icon(AM.icon, AM.icon_state)
|
||||
var/AMiconheight = AMicon.Height()
|
||||
var/AMiconwidth = AMicon.Width()
|
||||
if(AMiconheight != world.icon_size || AMiconwidth != world.icon_size)
|
||||
pixel_x_offset += ((AMiconwidth/world.icon_size)-1)*(world.icon_size*0.5)
|
||||
pixel_y_offset += ((AMiconheight/world.icon_size)-1)*(world.icon_size*0.5)
|
||||
|
||||
//DY and DX
|
||||
var/rough_x = floor(round(pixel_x_offset,world.icon_size)/world.icon_size)
|
||||
var/rough_y = floor(round(pixel_y_offset,world.icon_size)/world.icon_size)
|
||||
|
||||
//Find coordinates
|
||||
var/turf/T = get_turf(AM) //use AM's turfs, as it's coords are the same as AM's AND AM's coords are lost if it is inside another atom
|
||||
if(!T)
|
||||
return null
|
||||
var/final_x = T.x + rough_x
|
||||
var/final_y = T.y + rough_y
|
||||
|
||||
if(final_x || final_y)
|
||||
return locate(final_x, final_y, T.z)
|
||||
|
||||
@@ -21,7 +21,6 @@ Nothing should ever be included before this file.
|
||||
#define MANUAL_UNIT_TEST
|
||||
#define AMAP
|
||||
#define ENABLE_SUNLIGHT
|
||||
#define AO_USE_LIGHTING_OPACITY
|
||||
|
||||
#endif //SPACEMAN_DMM
|
||||
|
||||
@@ -44,6 +43,5 @@ Nothing should ever be included before this file.
|
||||
#define MANUAL_UNIT_TEST
|
||||
#define AMAP
|
||||
#define ENABLE_SUNLIGHT
|
||||
#define AO_USE_LIGHTING_OPACITY
|
||||
|
||||
#endif //OPENDREAM
|
||||
|
||||
@@ -158,3 +158,30 @@
|
||||
icon_state = "base"
|
||||
screen_loc = ui_entire_screen
|
||||
alpha = 100
|
||||
|
||||
/atom/movable/screen/fullscreen/lighting_backdrop
|
||||
icon = 'icons/mob/screen/white.dmi'
|
||||
icon_state = "flash"
|
||||
transform = matrix(200, 0, 0, 0, 200, 0)
|
||||
plane = LIGHTING_PLANE
|
||||
blend_mode = BLEND_OVERLAY
|
||||
|
||||
//Provides darkness to the back of the lighting plane
|
||||
/atom/movable/screen/fullscreen/lighting_backdrop/lit_secondary
|
||||
invisibility = INVISIBILITY_LIGHTING
|
||||
layer = BACKGROUND_LAYER + LIGHTING_PRIMARY_DIMMER_LAYER
|
||||
color = "#000"
|
||||
alpha = 60
|
||||
|
||||
/atom/movable/screen/fullscreen/lighting_backdrop/backplane
|
||||
invisibility = INVISIBILITY_LIGHTING
|
||||
layer = LIGHTING_BACKPLANE_LAYER
|
||||
color = "#000"
|
||||
blend_mode = BLEND_ADD
|
||||
//show_when_dead = TRUE
|
||||
|
||||
/atom/movable/screen/fullscreen/see_through_darkness
|
||||
icon_state = "nightvision"
|
||||
plane = LIGHTING_PLANE
|
||||
layer = LIGHTING_PRIMARY_LAYER
|
||||
blend_mode = BLEND_ADD
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
SUBSYSTEM_DEF(ao)
|
||||
name = "Ambient Occlusion"
|
||||
init_order = SS_INIT_AO
|
||||
wait = 1
|
||||
priority = SS_PRIORITY_LIGHTING
|
||||
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
|
||||
|
||||
var/list/queue = list()
|
||||
|
||||
/datum/controller/subsystem/ao/stat_entry(msg)
|
||||
msg = "P:[queue.len]"
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/ao/Initialize()
|
||||
fire(FALSE, TRUE)
|
||||
|
||||
return SS_INIT_SUCCESS
|
||||
|
||||
/datum/controller/subsystem/ao/fire(resumed = 0, no_mc_tick = FALSE)
|
||||
var/list/curr = queue
|
||||
while (curr.len)
|
||||
var/turf/target = curr[curr.len]
|
||||
curr.len--
|
||||
|
||||
if (!QDELETED(target))
|
||||
if (target.ao_queued == AO_UPDATE_REBUILD)
|
||||
var/old_n = target.ao_neighbors
|
||||
var/old_z = target.ao_neighbors_mimic
|
||||
target.calculate_ao_neighbors()
|
||||
if (old_n != target.ao_neighbors || old_z != target.ao_neighbors_mimic)
|
||||
target.update_ao()
|
||||
else
|
||||
target.update_ao()
|
||||
target.ao_queued = AO_UPDATE_NONE
|
||||
|
||||
if (no_mc_tick)
|
||||
CHECK_TICK
|
||||
else if (MC_TICK_CHECK)
|
||||
return
|
||||
|
||||
/datum/controller/subsystem/ao/ExplosionStart()
|
||||
can_fire = FALSE
|
||||
|
||||
/datum/controller/subsystem/ao/ExplosionEnd()
|
||||
can_fire = TRUE
|
||||
@@ -305,13 +305,6 @@ SUBSYSTEM_DEF(explosives)
|
||||
act_turfs[current_turf] = current_power
|
||||
current_power -= current_turf.explosion_resistance
|
||||
|
||||
// Attempt to shortcut on empty tiles: if a turf only has a LO on it, we don't need to check object resistance. Some turfs might not have LOs, so we need to check it actually has one.
|
||||
if (current_turf.contents.len > !!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)
|
||||
|
||||
@@ -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 ..()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 || "<unknown file>"] 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.
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
+30
-3
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
+2
-7
@@ -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
|
||||
|
||||
+63
-28
@@ -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()
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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].")
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
. = ..()
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
. = ..()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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].")
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
. = ..()
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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."))
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -201,6 +201,7 @@
|
||||
spark_system = null
|
||||
if(fast_processing)
|
||||
STOP_PROCESSING(SSfast_process, src)
|
||||
QDEL_NULL(installation)
|
||||
|
||||
clear_from_target_grid()
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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."))
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
..()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <b>\the [T]</b>.<br>"
|
||||
reading += "Visible light: <b>[visible_reading]</b> lx<br>"
|
||||
reading += "Ultraviolet light: <b>[uv_reading]</b> lx ([uv_reading * 5.5 - 1.5] adlx)"
|
||||
|
||||
to_chat(usr, SPAN_NOTICE(reading))
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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("<b>[user]</b> 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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user