diff --git a/code/__defines/lighting.dm b/code/__defines/lighting.dm index 56c95535fe..f311ea4aa2 100644 --- a/code/__defines/lighting.dm +++ b/code/__defines/lighting.dm @@ -4,3 +4,48 @@ for(type in view(range, dview_mob)) #define END_FOR_DVIEW dview_mob.loc = null + +#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_LAYER 10 // drawing layer for lighting overlays +#define LIGHTING_ICON 'icons/effects/lighting_overlay.dmi' // icon used for lighting shading effects +#define LIGHTING_ICON_STATE_DARK "soft_dark" // Change between "soft_dark" and "dark" to swap soft darkvision + +#define LIGHTING_ROUND_VALUE (1 / 64) // Value used to round lumcounts, values smaller than 1/69 don't matter (if they do, thanks sinking points), greater values will make lighting less precise, but in turn increase performance, VERY SLIGHTLY. + +#define LIGHTING_SOFT_THRESHOLD 0.05 // If the max of the lighting lumcounts of each spectrum drops below this, disable luminosity on the lighting overlays. This also should be the transparancy of the "soft_dark" icon state. + +// If I were you I'd leave this alone. +#define LIGHTING_BASE_MATRIX \ + list \ + ( \ + LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \ + LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \ + LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \ + LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \ + 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 diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index b30d7551d5..6fa9d4ec0c 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -952,7 +952,7 @@ proc/DuplicateObject(obj/original, var/perfectcopy = 0 , var/sameloc = 0) // var/area/AR = X.loc -// if(AR.lighting_use_dynamic) +// if(AR.dynamic_lighting) // X.opacity = !X.opacity // X.sd_SetOpacity(!X.opacity) //TODO: rewrite this code so it's not messed by lighting ~Carn diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 3f6758c6ad..e55323fb3a 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -162,6 +162,12 @@ update_icon() return 1 +/obj/screen/zone_sel/proc/set_selected_zone(bodypart) + var/old_selecting = selecting + selecting = bodypart + if(old_selecting != selecting) + update_icon() + /obj/screen/zone_sel/update_icon() overlays.Cut() overlays += image('icons/mob/zone_sel.dmi', "[selecting]") diff --git a/code/controllers/Processes/lighting.dm b/code/controllers/Processes/lighting.dm new file mode 100644 index 0000000000..d46cab1d19 --- /dev/null +++ b/code/controllers/Processes/lighting.dm @@ -0,0 +1,98 @@ +/var/lighting_overlays_initialised = FALSE + +/var/list/lighting_update_lights = list() // List of lighting sources queued for update. +/var/list/lighting_update_corners = list() // List of lighting corners queued for update. +/var/list/lighting_update_overlays = list() // List of lighting overlays queued for update. + +/var/list/lighting_update_lights_old = list() // List of lighting sources currently being updated. +/var/list/lighting_update_corners_old = list() // List of lighting corners currently being updated. +/var/list/lighting_update_overlays_old = list() // List of lighting overlays currently being updated. + + +/datum/controller/process/lighting + // Queues of update counts, waiting to be rolled into stats lists + var/list/stats_queues = list( + "Source" = list(), "Corner" = list(), "Overlay" = list()) + // Stats lists + var/list/stats_lists = list( + "Source" = list(), "Corner" = list(), "Overlay" = list()) + var/update_stats_every = (1 SECONDS) + var/next_stats_update = 0 + var/stat_updates_to_keep = 5 + +/datum/controller/process/lighting/setup() + name = "lighting" + + schedule_interval = 0 // run as fast as you possibly can + sleep_interval = 10 // Yield every 10% of a tick + defer_usage = 80 // Defer at 80% of a tick + create_all_lighting_overlays() + lighting_overlays_initialised = TRUE + + // Pre-process lighting once before the round starts. Wait 30 seconds so the away mission has time to load. + spawn(300) + doWork(1) + +/datum/controller/process/lighting/doWork(roundstart) + + lighting_update_lights_old = lighting_update_lights //We use a different list so any additions to the update lists during a delay from scheck() don't cause things to be cut from the list without being updated. + lighting_update_lights = list() + for(var/datum/light_source/L in lighting_update_lights_old) + + if(L.check() || L.destroyed || L.force_update) + L.remove_lum() + if(!L.destroyed) + L.apply_lum() + + else if(L.vis_update) //We smartly update only tiles that became (in) visible to use. + L.smart_vis_update() + + L.vis_update = FALSE + L.force_update = FALSE + L.needs_update = FALSE + + SCHECK + + lighting_update_corners_old = lighting_update_corners //Same as above. + lighting_update_corners = list() + for(var/A in lighting_update_corners_old) + var/datum/lighting_corner/C = A + + C.update_overlays() + + C.needs_update = FALSE + + SCHECK + + lighting_update_overlays_old = lighting_update_overlays //Same as above. + lighting_update_overlays = list() + + for(var/A in lighting_update_overlays_old) + var/atom/movable/lighting_overlay/O = A + O.update_overlay() + O.needs_update = 0 + SCHECK + + stats_queues["Source"] += lighting_update_lights_old.len + stats_queues["Corner"] += lighting_update_corners_old.len + stats_queues["Overlay"] += lighting_update_overlays_old.len + + if(next_stats_update <= world.time) + next_stats_update = world.time + update_stats_every + for(var/stat_name in stats_queues) + var/stat_sum = 0 + var/list/stats_queue = stats_queues[stat_name] + for(var/count in stats_queue) + stat_sum += count + stats_queue.Cut() + + var/list/stats_list = stats_lists[stat_name] + stats_list.Insert(1, stat_sum) + if(stats_list.len > stat_updates_to_keep) + stats_list.Cut(stats_list.len) + +/datum/controller/process/lighting/statProcess() + ..() + stat(null, "[total_lighting_sources] sources, [total_lighting_corners] corners, [total_lighting_overlays] overlays") + for(var/stat_type in stats_lists) + stat(null, "[stat_type] updates: [jointext(stats_lists[stat_type], " | ")]") diff --git a/code/controllers/Processes/planet.dm b/code/controllers/Processes/planet.dm index 31406e92a0..b3b556d7bd 100644 --- a/code/controllers/Processes/planet.dm +++ b/code/controllers/Processes/planet.dm @@ -1,11 +1,16 @@ +var/datum/controller/process/planet/planet_controller = null + /datum/controller/process/planet var/list/planets = list() /datum/controller/process/planet/setup() name = "planet" + planet_controller = src schedule_interval = 600 // every minute - planet_sif = new() - planets.Add(planet_sif) + var/list/planet_datums = typesof(/datum/planet) - /datum/planet + for(var/P in planet_datums) + var/datum/planet/NP = new P() + planets.Add(NP) /datum/controller/process/planet/doWork() for(var/datum/planet/P in planets) diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 0c8d6ee052..01e95e5716 100755 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -100,7 +100,7 @@ var/list/ghostteleportlocs = list() icon_state = "space" requires_power = 1 always_unpowered = 1 - lighting_use_dynamic = 1 + dynamic_lighting = 1 power_light = 0 power_equip = 0 power_environ = 0 @@ -293,7 +293,7 @@ area/space/atmosalert() /area/shuttle/mining name = "\improper Mining Elevator" music = "music/escape.ogg" - lighting_use_dynamic = 0 + dynamic_lighting = 0 base_turf = /turf/simulated/mineral/floor/ignore_mapgen /area/shuttle/mining/station @@ -392,7 +392,7 @@ area/space/atmosalert() /area/shuttle/research name = "\improper Research Elevator" music = "music/escape.ogg" - lighting_use_dynamic = 0 + dynamic_lighting = 0 base_turf = /turf/simulated/mineral/floor/ignore_mapgen /area/shuttle/research/station @@ -418,7 +418,7 @@ area/space/atmosalert() name = "\improper CentCom" icon_state = "centcom" requires_power = 0 - lighting_use_dynamic = 0 + dynamic_lighting = 0 /area/centcom/control name = "\improper CentCom Control" @@ -491,7 +491,7 @@ area/space/atmosalert() name = "\improper Mercenary Base" icon_state = "syndie-ship" requires_power = 0 - lighting_use_dynamic = 0 + dynamic_lighting = 0 /area/syndicate_mothership/control name = "\improper Mercenary Control Room" @@ -543,7 +543,7 @@ area/space/atmosalert() name = "\improper Thunderdome" icon_state = "thunder" requires_power = 0 - lighting_use_dynamic = 0 + dynamic_lighting = 0 sound_env = ARENA /area/tdome/tdome1 @@ -624,7 +624,7 @@ area/space/atmosalert() name = "\improper Wizard's Den" icon_state = "yellow" requires_power = 0 - lighting_use_dynamic = 0 + dynamic_lighting = 0 /area/skipjack_station name = "\improper Skipjack" @@ -1485,7 +1485,7 @@ area/space/atmosalert() /area/holodeck name = "\improper Holodeck" icon_state = "Holodeck" - lighting_use_dynamic = 0 + dynamic_lighting = 0 sound_env = LARGE_ENCLOSED /area/holodeck/alphadeck @@ -1638,7 +1638,7 @@ area/space/atmosalert() /area/solar requires_power = 1 always_unpowered = 1 - lighting_use_dynamic = 0 + dynamic_lighting = 0 base_turf = /turf/space auxport @@ -2336,7 +2336,7 @@ area/space/atmosalert() /area/shuttle/constructionsite name = "\improper Construction Site Shuttle" icon_state = "yellow" - lighting_use_dynamic = 0 + dynamic_lighting = 0 base_turf = /turf/simulated/mineral/floor/ignore_mapgen /area/shuttle/constructionsite/station @@ -2493,25 +2493,25 @@ area/space/atmosalert() name = "\improper AI Sat Ext" icon_state = "storage" luminosity = 1 - lighting_use_dynamic = 0 + dynamic_lighting = 0 /area/AIsatextFS name = "\improper AI Sat Ext" icon_state = "storage" luminosity = 1 - lighting_use_dynamic = 0 + dynamic_lighting = 0 /area/AIsatextAS name = "\improper AI Sat Ext" icon_state = "storage" luminosity = 1 - lighting_use_dynamic = 0 + dynamic_lighting = 0 /area/AIsatextAP name = "\improper AI Sat Ext" icon_state = "storage" luminosity = 1 - lighting_use_dynamic = 0 + dynamic_lighting = 0 /area/NewAIMain name = "\improper AI Main New" @@ -2685,7 +2685,7 @@ area/space/atmosalert() name = "Beach" icon_state = "null" luminosity = 1 - lighting_use_dynamic = 0 + dynamic_lighting = 0 requires_power = 0 ambience = list() var/sound/mysound = null @@ -2807,7 +2807,7 @@ var/list/the_station_areas = list ( name = "Keelin's private beach" icon_state = "null" luminosity = 1 - lighting_use_dynamic = 0 + dynamic_lighting = 0 requires_power = 0 var/sound/mysound = null /* diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index e118e6fa4d..f152050990 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -18,7 +18,7 @@ power_equip = 0 power_environ = 0 - if(lighting_use_dynamic) + if(dynamic_lighting) luminosity = 0 else luminosity = 1 diff --git a/code/game/area/asteroid_areas.dm b/code/game/area/asteroid_areas.dm index 68f9807ead..66a7e86913 100644 --- a/code/game/area/asteroid_areas.dm +++ b/code/game/area/asteroid_areas.dm @@ -126,7 +126,7 @@ /area/outpost/engineering/solarsoutside requires_power = 1 always_unpowered = 1 - lighting_use_dynamic = 0 + dynamic_lighting = 0 aft name = "\improper Engineering Outpost Solar Array" diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index b76620fa95..b511c9befd 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -40,7 +40,13 @@ reagents = null for(var/atom/movable/AM in contents) qdel(AM) + var/turf/un_opaque + if(opacity && isturf(loc)) + un_opaque = loc + loc = null + if(un_opaque) + un_opaque.recalc_atom_opacity() if (pulledby) if (pulledby.pulling == src) pulledby.pulling = null diff --git a/code/game/gamemodes/cult/hell_universe.dm b/code/game/gamemodes/cult/hell_universe.dm index 496af98ef8..75c97d5cee 100644 --- a/code/game/gamemodes/cult/hell_universe.dm +++ b/code/game/gamemodes/cult/hell_universe.dm @@ -62,7 +62,7 @@ In short: /datum/universal_state/hell/OverlayAndAmbientSet() spawn(0) - for(var/atom/movable/lighting_overlay/L in world) + for(var/datum/lighting_corner/L in world) L.update_lumcount(1, 0, 0) for(var/turf/space/T in turfs) diff --git a/code/game/gamemodes/endgame/supermatter_cascade/universe.dm b/code/game/gamemodes/endgame/supermatter_cascade/universe.dm index 11c61cfed6..6f549d15f4 100644 --- a/code/game/gamemodes/endgame/supermatter_cascade/universe.dm +++ b/code/game/gamemodes/endgame/supermatter_cascade/universe.dm @@ -93,7 +93,7 @@ The access requirements on the Asteroid Shuttles' consoles have now been revoked /datum/universal_state/supermatter_cascade/OverlayAndAmbientSet() spawn(0) - for(var/atom/movable/lighting_overlay/L in world) + for(var/datum/lighting_corner/L in world) if(L.z in using_map.admin_levels) L.update_lumcount(1,1,1) else diff --git a/code/game/gamemodes/technomancer/spells/summon/summon_ward.dm b/code/game/gamemodes/technomancer/spells/summon/summon_ward.dm index 5bb032b9c7..c6e5a2804d 100644 --- a/code/game/gamemodes/technomancer/spells/summon/summon_ward.dm +++ b/code/game/gamemodes/technomancer/spells/summon/summon_ward.dm @@ -83,11 +83,8 @@ continue if(!true_sight) - var/atom/movable/lighting_overlay/light = locate(/atom/movable/lighting_overlay) in get_turf(L) - var/light_amount = 1 // Unsimulated tiles are pretend-lit, so we need to be pretend too if that somehow happens. - if(light) - light_amount = (light.lum_r + light.lum_g + light.lum_b) / 3 - + var/turf/T = get_turf(L) + var/light_amount = T.get_lumcount() if(light_amount <= 0.5) continue // Too dark to see. diff --git a/code/game/objects/effects/chem/chemsmoke.dm b/code/game/objects/effects/chem/chemsmoke.dm index 3fa93e7e46..3f077116e9 100644 --- a/code/game/objects/effects/chem/chemsmoke.dm +++ b/code/game/objects/effects/chem/chemsmoke.dm @@ -162,9 +162,9 @@ smoke.pixel_x = -32 + rand(-8, 8) smoke.pixel_y = -32 + rand(-8, 8) walk_to(smoke, T) - smoke.opacity = 1 //switching opacity on after the smoke has spawned, and then + smoke.set_opacity(1) //switching opacity on after the smoke has spawned, and then sleep(150+rand(0,20)) // turning it off before it is deleted results in cleaner - smoke.opacity = 0 // lighting and view range updates + smoke.set_opacity(0) // lighting and view range updates fadeOut(smoke) qdel(src) diff --git a/code/game/objects/items/weapons/manuals.dm b/code/game/objects/items/weapons/manuals.dm index c89f41056f..6ea812ad3a 100644 --- a/code/game/objects/items/weapons/manuals.dm +++ b/code/game/objects/items/weapons/manuals.dm @@ -1113,10 +1113,10 @@ "} /obj/item/weapon/book/manual/evaguide - name = "EVA Gear and You: Not Spending All Day Inside" + name = "EVA Gear and You: Not Spending All Day Inside, 2nd Edition" icon_state = "evabook" author = "Maria Crash, Senior Atmospherics Technician" - title = "EVA Gear and You: Not Spending All Day Inside" + title = "EVA Gear and You: Not Spending All Day Inside, 2nd Edition" dat = {"