Glorious /vg/ Lighting Port (#66)

* fuck

* [CANT WAKE UP]

* AAAAAAAAAHHHHHHHHHHHH

* SAAAAVE MEEEEEEEEEEEEEEEE

* this is so bad how can i even call myself a coder

* thanks fam

* hello darkness my old friend

i've come to talk with you again

* ugh go away

* OH

* much less broken

* ayy

* aaaaa

* OH YEAAAAAAAAHHHHHHHHHHH

* aaaa

* k

* dfgjtxkytkjyd

* debug

* dangerously cheesy

* mm

* OH YEAAAAAAAAAAAAAAAAAAAAAAAAAA

* oH YEAH

* Some final touches and cleanup of the lighting port.

* One more

* More fixes.

* varedit hack for easy modification

* fixed

* C O L O R

* slym

* fffff

* oh great what the fuck is wrong now

* Revert "oh great what the fuck is wrong now"

This reverts commit e589ad51facb5464e107ca515317d41136dd1e5e.

* fu

* will it blend

* aaaaaaaaaaaaaaaaaaaa

* this is why im bad at porting

falalalala, lala la la

* k

* yeh

* can't forget majestic fire
This commit is contained in:
L.E.D
2016-11-06 09:51:16 -05:00
committed by TalkingCactus
parent 9b07cb4798
commit e1956df149
141 changed files with 1508 additions and 958 deletions
+1 -1
View File
@@ -302,7 +302,7 @@ var/list/admin_verbs_hideable = list(
/client/proc/count_objects_all,
/client/proc/cmd_assume_direct_control,
/client/proc/startSinglo,
/client/proc/fps,
/client/proc/set_fps,
/client/proc/cmd_admin_grantfullaccess,
/client/proc/cmd_admin_areatest,
/client/proc/readmin
+2 -2
View File
@@ -1,5 +1,5 @@
//replaces the old Ticklag verb, fps is easier to understand
/client/proc/fps()
/client/proc/set_fps()
set category = "Debug"
set name = "Set fps"
set desc = "Sets game speed in frames-per-second. Can potentially break the game"
@@ -21,4 +21,4 @@
message_admins(msg, 0)
feedback_add_details("admin_verb","TICKLAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
world.fps = fps
world.fps = fps
+1 -1
View File
@@ -33,7 +33,7 @@ var/list/admin_verbs_debug_mapping = list(
/client/proc/count_objects_all,
/client/proc/cmd_assume_direct_control, //-errorage
/client/proc/startSinglo,
/client/proc/fps, //allows you to set the ticklag.
/client/proc/set_fps, //allows you to set the ticklag.
/client/proc/cmd_admin_grantfullaccess,
/client/proc/cmd_admin_areatest,
/client/proc/cmd_admin_rejuvenate,
+7 -7
View File
@@ -308,7 +308,7 @@
if(new_value == null) return
if(variable=="luminosity")
O.SetLuminosity(new_value)
O.set_light(new_value)
else
O.vars[variable] = new_value
@@ -317,7 +317,7 @@
for(var/mob/M in mob_list)
if ( istype(M , O.type) )
if(variable=="luminosity")
M.SetLuminosity(new_value)
M.set_light(new_value)
else
M.vars[variable] = O.vars[variable]
CHECK_TICK
@@ -326,7 +326,7 @@
for(var/obj/A in world)
if ( istype(A , O.type) )
if(variable=="luminosity")
A.SetLuminosity(new_value)
A.set_light(new_value)
else
A.vars[variable] = O.vars[variable]
CHECK_TICK
@@ -335,7 +335,7 @@
for(var/turf/A in world)
if ( istype(A , O.type) )
if(variable=="luminosity")
A.SetLuminosity(new_value)
A.set_light(new_value)
else
A.vars[variable] = O.vars[variable]
CHECK_TICK
@@ -345,7 +345,7 @@
for(var/mob/M in mob_list)
if (M.type == O.type)
if(variable=="luminosity")
M.SetLuminosity(new_value)
M.set_light(new_value)
else
M.vars[variable] = O.vars[variable]
CHECK_TICK
@@ -354,7 +354,7 @@
for(var/obj/A in world)
if (A.type == O.type)
if(variable=="luminosity")
A.SetLuminosity(new_value)
A.set_light(new_value)
else
A.vars[variable] = O.vars[variable]
CHECK_TICK
@@ -363,7 +363,7 @@
for(var/turf/A in world)
if (A.type == O.type)
if(variable=="luminosity")
A.SetLuminosity(new_value)
A.set_light(new_value)
else
A.vars[variable] = O.vars[variable]
CHECK_TICK
+16 -3
View File
@@ -607,6 +607,11 @@ var/list/VVckey_edit = list("key", "ckey")
var/var_new = input("Enter new text:","Text",O.vars[variable]) as null|message
if(var_new==null) return
if(variable == "light_color")
O.set_light(l_color = var_new)
else
O.vars[variable] = var_new
if(findtext(var_new,"\["))
var/process_vars = alert(usr,"\[] detected in string, process as variables?","Process Variables?","Yes","No")
if(process_vars == "Yes")
@@ -617,10 +622,18 @@ var/list/VVckey_edit = list("key", "ckey")
O.vars[variable] = var_new
if("num")
if(variable=="luminosity")
if(variable=="light_range")
var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num
if(var_new == null) return
O.SetLuminosity(var_new)
if(var_new == null)
return
O.set_light(var_new)
else if(variable=="light_power")
var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num
if(var_new == null)
return
O.set_light(l_power = var_new)
else if(variable=="stat")
var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num
if(var_new == null) return
@@ -59,6 +59,7 @@
/obj/effect/hotspot/New()
..()
set_light(3,1,LIGHT_COLOR_FIRE)
SSair.hotspots += src
perform_exposure()
setDir(pick(cardinal))
@@ -146,7 +147,6 @@
return 1
/obj/effect/hotspot/Destroy()
SetLuminosity(0)
SSair.hotspots -= src
DestroyTurf()
if(istype(loc, /turf))
@@ -4,14 +4,14 @@
icon_state = "away"
requires_power = 0
luminosity = 1
lighting_use_dynamic = DYNAMIC_LIGHTING_ENABLED
dynamic_lighting = DYNAMIC_LIGHTING_ENABLED
/area/awaymission/cabin
name = "Cabin"
icon_state = "away2"
requires_power = 1
luminosity = 0
lighting_use_dynamic = DYNAMIC_LIGHTING_ENABLED
dynamic_lighting = DYNAMIC_LIGHTING_ENABLED
/area/awaymission/snowforest/lumbermill
name = "Lumbermill"
@@ -54,10 +54,10 @@
/obj/structure/fireplace/proc/toggleFireplace()
if(active)
SetLuminosity(8)
set_light(8)
icon_state = "fireplace-active"
else
SetLuminosity(0)
set_light(0)
icon_state = "fireplace"
/obj/structure/fireplace/extinguish()
@@ -4,7 +4,7 @@
name = "Research Outpost"
icon_state = "away"
luminosity = 0
lighting_use_dynamic = DYNAMIC_LIGHTING_ENABLED
dynamic_lighting = DYNAMIC_LIGHTING_ENABLED
/area/awaymission/research/interior
name = "Research Inside"
@@ -5,7 +5,7 @@
icon_state = "away"
requires_power = 0
luminosity = 1
lighting_use_dynamic = DYNAMIC_LIGHTING_ENABLED
dynamic_lighting = DYNAMIC_LIGHTING_ENABLED
/area/awaymission/snowdin/post
name = "Snowdin Outpost"
+1 -1
View File
@@ -9,7 +9,7 @@
/obj/structure/signpost/New()
. = ..()
SetLuminosity(2)
set_light(2)
/obj/structure/signpost/attackby(obj/item/weapon/W, mob/user, params)
return attack_hand(user)
+1 -1
View File
@@ -8,6 +8,7 @@
var/safety_warning = "For safety reasons the automated supply shuttle \
cannot transport live organisms, classified nuclear weaponry or \
homing beacons."
light_color = LIGHT_COLOR_BROWN
/obj/machinery/computer/cargo/request
name = "supply request console"
@@ -197,4 +198,3 @@
status_signal.data["command"] = command
frequency.post_signal(src, status_signal)
+2 -17
View File
@@ -14,9 +14,6 @@
dog_fashion = /datum/dog_fashion/head
/obj/item/clothing/head/hardhat/attack_self(mob/user)
if(!isturf(user.loc))
user << "<span class='warning'>You cannot turn the light on while in this [user.loc]!</span>" //To prevent some lighting anomalities.
return
on = !on
icon_state = "hardhat[on]_[item_color]"
item_state = "hardhat[on]_[item_color]"
@@ -30,23 +27,11 @@
var/datum/action/A = X
A.UpdateButtonIcon()
/obj/item/clothing/head/hardhat/pickup(mob/user)
..()
if(on)
user.AddLuminosity(brightness_on)
SetLuminosity(0)
/obj/item/clothing/head/hardhat/dropped(mob/user)
..()
if(on)
user.AddLuminosity(-brightness_on)
SetLuminosity(brightness_on)
/obj/item/clothing/head/hardhat/proc/turn_on(mob/user)
user.AddLuminosity(brightness_on)
set_light(brightness_on)
/obj/item/clothing/head/hardhat/proc/turn_off(mob/user)
user.AddLuminosity(-brightness_on)
set_light(0)
/obj/item/clothing/head/hardhat/orange
icon_state = "hardhat0_orange"
+4 -28
View File
@@ -247,7 +247,7 @@
return
user << "<span class='notice'>You click [S] into place on [src].</span>"
if(S.on)
SetLuminosity(0)
set_light(0)
F = S
S.loc = src
update_icon()
@@ -298,37 +298,13 @@
/obj/item/clothing/head/helmet/proc/update_helmlight(mob/user = null)
if(F)
if(F.on)
if(loc == user)
user.AddLuminosity(F.brightness_on)
else if(isturf(loc))
SetLuminosity(F.brightness_on)
set_light(F.brightness_on)
else
if(loc == user)
user.AddLuminosity(-F.brightness_on)
else if(isturf(loc))
SetLuminosity(0)
set_light(0)
update_icon()
else
if(loc == user)
user.AddLuminosity(-5)
else if(isturf(loc))
SetLuminosity(0)
set_light(0)
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
/obj/item/clothing/head/helmet/pickup(mob/user)
..()
if(F)
if(F.on)
user.AddLuminosity(F.brightness_on)
SetLuminosity(0)
/obj/item/clothing/head/helmet/dropped(mob/user)
..()
if(F)
if(F.on)
user.AddLuminosity(-F.brightness_on)
SetLuminosity(F.brightness_on)
+5 -17
View File
@@ -14,33 +14,21 @@
/obj/item/clothing/head/helmet/space/hardsuit/attack_self(mob/user)
if(!isturf(user.loc))
user << "<span class='warning'>You cannot turn the light on while in this [user.loc]!</span>" //To prevent some lighting anomalities.
return
on = !on
icon_state = "[basestate][on]-[item_color]"
user.update_inv_head() //so our mob-overlays update
if(on)
user.AddLuminosity(brightness_on)
set_light(brightness_on)
else
user.AddLuminosity(-brightness_on)
set_light(0)
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
/obj/item/clothing/head/helmet/space/hardsuit/pickup(mob/user)
..()
if(on)
user.AddLuminosity(brightness_on)
SetLuminosity(0)
/obj/item/clothing/head/helmet/space/hardsuit/dropped(mob/user)
..()
if(on)
user.AddLuminosity(-brightness_on)
SetLuminosity(brightness_on)
if(suit)
suit.RemoveHelmet()
@@ -228,7 +216,7 @@
user << "<span class='notice'>You switch your hardsuit to EVA mode, sacrificing speed for space protection.</span>"
name = initial(name)
desc = initial(desc)
user.AddLuminosity(brightness_on)
set_light(brightness_on)
flags |= visor_flags
flags_cover |= HEADCOVERSEYES | HEADCOVERSMOUTH
flags_inv |= visor_flags_inv
@@ -237,7 +225,7 @@
user << "<span class='notice'>You switch your hardsuit to combat mode and can now run at full speed.</span>"
name += " (combat)"
desc = alt_desc
user.AddLuminosity(-brightness_on)
set_light(0)
flags &= ~visor_flags
flags_cover &= ~(HEADCOVERSEYES | HEADCOVERSMOUTH)
flags_inv &= ~visor_flags_inv
+5 -5
View File
@@ -110,7 +110,7 @@
for(var/obj/effect/spacevine/SV in src)
qdel(SV)
..()
UpdateAffectingLights()
reconsider_lights()
/datum/spacevine_mutation/space_covering/on_grow(obj/effect/spacevine/holder)
if(istype(holder.loc, /turf/open/space))
@@ -144,7 +144,7 @@
/datum/spacevine_mutation/light/on_grow(obj/effect/spacevine/holder)
if(holder.energy)
holder.SetLuminosity(severity, 3)
holder.set_light(severity, 3)
/datum/spacevine_mutation/toxicity
name = "toxic"
@@ -219,7 +219,7 @@
quality = POSITIVE
/datum/spacevine_mutation/transparency/on_grow(obj/effect/spacevine/holder)
holder.SetOpacity(0)
holder.set_opacity(0)
holder.alpha = 125
/datum/spacevine_mutation/oxy_eater
@@ -359,7 +359,7 @@
KZ.potency = min(100, master.mutativness * 10)
KZ.production = (master.spread_cap / initial(master.spread_cap)) * 50
mutations = list()
SetOpacity(0)
set_opacity(0)
if(has_buckled_mobs())
unbuckle_all_mobs(force=1)
return ..()
@@ -519,7 +519,7 @@
if(!energy)
src.icon_state = pick("Med1", "Med2", "Med3")
energy = 1
SetOpacity(1)
set_opacity(1)
else
src.icon_state = pick("Hvy1", "Hvy2", "Hvy3")
energy = 2
+2 -2
View File
@@ -2,7 +2,7 @@
name = "Holodeck"
icon_state = "Holodeck"
luminosity = 1
lighting_use_dynamic = 0
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
var/obj/machinery/computer/holodeck/linked
var/restricted = 0 // if true, program goes on emag list
@@ -99,4 +99,4 @@
/area/holodeck/rec_center/anthophila
name = "Holodeck - Anthophila"
restricted = 1
restricted = 1
+2 -1
View File
@@ -25,6 +25,7 @@
var/area/holodeck/program
var/area/holodeck/last_program
var/area/offline_program = /area/holodeck/rec_center/offline
light_color = LIGHT_COLOR_CYAN
var/list/program_cache = list()
var/list/emag_programs = list()
@@ -206,4 +207,4 @@
/obj/machinery/computer/holodeck/blob_act(obj/effect/blob/B)
emergency_shutdown()
..()
..()
+4
View File
@@ -7,6 +7,10 @@
anchored = 1
use_power = 1
idle_power_usage = 40
use_auto_lights = 1
light_power_on = 2
light_range_on = 3
light_color = LIGHT_COLOR_BLUE
var/processing = 0
var/obj/item/weapon/reagent_containers/glass/beaker = null
var/points = 0
+3 -27
View File
@@ -38,6 +38,9 @@
seed.prepare_result(src)
transform *= TransformUsingVariable(seed.potency, 100, 0.5) //Makes the resulting produce's sprite larger or smaller based on potency!
add_juice()
var/datum/plant_gene/trait/glow/G = seed.get_gene(/datum/plant_gene/trait/glow)
if(G)
set_light(G.get_lum(seed))
@@ -134,33 +137,6 @@
T.on_cross(src, AM)
..()
// Glow gene procs
/obj/item/weapon/reagent_containers/food/snacks/grown/Destroy()
if(seed)
var/datum/plant_gene/trait/glow/G = seed.get_gene(/datum/plant_gene/trait/glow)
if(G && ismob(loc))
loc.AddLuminosity(-G.get_lum(seed))
return ..()
/obj/item/weapon/reagent_containers/food/snacks/grown/pickup(mob/user)
..()
if(seed)
var/datum/plant_gene/trait/glow/G = seed.get_gene(/datum/plant_gene/trait/glow)
if(G)
SetLuminosity(0)
user.AddLuminosity(G.get_lum(seed))
/obj/item/weapon/reagent_containers/food/snacks/grown/dropped(mob/user)
..()
if(seed)
var/datum/plant_gene/trait/glow/G = seed.get_gene(/datum/plant_gene/trait/glow)
if(G)
user.AddLuminosity(-G.get_lum(seed))
SetLuminosity(G.get_lum(seed))
// For item-containing growns such as eggy or gatfruit
/obj/item/weapon/reagent_containers/food/snacks/grown/shell/attack_self(mob/user as mob)
user.unEquip(src)
+3 -25
View File
@@ -30,6 +30,9 @@
seed.prepare_result(src)
transform *= TransformUsingVariable(seed.potency, 100, 0.5)
add_juice()
var/datum/plant_gene/trait/glow/G = seed.get_gene(/datum/plant_gene/trait/glow)
if(G)
set_light(G.get_lum(seed))
/obj/item/weapon/grown/attackby(obj/item/O, mob/user, params)
@@ -53,28 +56,3 @@
for(var/datum/plant_gene/trait/T in seed.genes)
T.on_cross(src, AM)
..()
// Glow gene procs
/obj/item/weapon/grown/Destroy()
if(seed)
var/datum/plant_gene/trait/glow/G = seed.get_gene(/datum/plant_gene/trait/glow)
if(G && ismob(loc))
loc.AddLuminosity(-G.get_lum(seed))
return ..()
/obj/item/weapon/grown/pickup(mob/user)
..()
if(seed)
var/datum/plant_gene/trait/glow/G = seed.get_gene(/datum/plant_gene/trait/glow)
if(G)
SetLuminosity(0)
user.AddLuminosity(G.get_lum(seed))
/obj/item/weapon/grown/dropped(mob/user)
..()
if(seed)
var/datum/plant_gene/trait/glow/G = seed.get_gene(/datum/plant_gene/trait/glow)
if(G)
user.AddLuminosity(-G.get_lum(seed))
SetLuminosity(G.get_lum(seed))
+4 -4
View File
@@ -150,7 +150,7 @@
// Lack of light hurts non-mushrooms
if(isturf(loc))
var/turf/currentTurf = loc
var/lightAmt = currentTurf.lighting_lumcount
var/lightAmt = currentTurf.get_lumcount()
if(myseed.plant_type == PLANT_MUSHROOM)
if(lightAmt < 2)
adjustHealth(-1 / rating)
@@ -259,7 +259,7 @@
color = rgb(255, 175, 0)
else
overlays += image('icons/obj/hydroponics/equipment.dmi', icon_state = "gaia_blessing")
SetLuminosity(3)
set_light(3)
update_icon_hoses()
@@ -270,9 +270,9 @@
if(!self_sustaining)
if(myseed && myseed.get_gene(/datum/plant_gene/trait/glow))
var/datum/plant_gene/trait/glow/G = myseed.get_gene(/datum/plant_gene/trait/glow)
SetLuminosity(G.get_lum(myseed))
set_light(G.get_lum(myseed))
else
SetLuminosity(0)
set_light(0)
return
+1 -1
View File
@@ -258,7 +258,7 @@
if(ismob(newloc))
G.pickup(newloc)//adjusts the lighting on the mob
else
G.SetLuminosity(get_lum(G.seed))
G.set_light(get_lum(G.seed))
/datum/plant_gene/trait/glow/berry
name = "Strong Bioluminescence"
@@ -47,6 +47,10 @@
var/piles = list()
var/max_seeds = 1000
var/seed_multiplier = 1
use_auto_lights = 1
light_power_on = 1
light_range_on = 3
light_color = LIGHT_COLOR_BLUE
/obj/machinery/seed_extractor/New()
..()
+74
View File
@@ -0,0 +1,74 @@
/*
BS12 object based lighting system from VG, ported to TG by Unusual Crow with plenty of help from PJB.
*/
/*
Changes from TG DAL:
- Lighting is done using objects instead of subareas.
- Animated transitions. (newer TG DAL has this)
- Full colours with mixing.
- Support for lights on shuttles.
- Code:
- Instead of one flat luminosity var, light is represented by 3 atom vars:
- light_range; range in tiles of the light, used for calculating falloff,
- light_power; multiplier for the brightness of lights,
- light_color; hex string representing the RGB colour of the light.
- SetLuminosity() is now set_light() and takes the three variables above.
- Variables can be left as null to not update them.
- SetOpacity() is now set_opacity().
- Areas have luminosity set to 1 permanently, no hard-lighting.
- Objects inside other objects can have lights and they properly affect the turf. (flashlights)
- area/master and area/list/related have been eviscerated since subareas aren't needed.
*/
/*
Relevant vars/procs:
global: (uh, I placed the only one in lighting_system.dm)
- var/list/all_lighting_overlays; Just a list of ALL of the lighting overlays.
atom: (lighting_atom.dm)
- var/light_range; range in tiles of the light, used for calculating falloff
- var/light_power; multiplier for the brightness of lights
- var/light_color; hex string representing the RGB colour of the light
- var/datum/light_source/light; light source datum for this atom, only present if light_range && light_power
- var/list/light_sources; light sources in contents that are shining through this object, including this object
- proc/set_light(l_range, l_power, l_color):
- Sets light_range/power/color to non-null args and calls update_light()
- proc/set_opacity(new_opacity):
- Sets opacity to new_opacity.
- If opacity has changed, call turf.reconsider_lights() to fix light occlusion
- proc/update_light():
- Updates the light var on this atom, deleting or creating as needed and calling .update()
turf: (lighting_turf.dm)
- var/list/affecting_lights; list of light sources that are shining onto this turf
- var/list/lighting_overlays; list of lighting overlays in the turf. (only used if higher resolutions
- var/lighting_overlay; ref to the lighting overlay (only used if resolution is 1)
- proc/reconsider_lights():
- Force all light sources shining onto this turf to update
- proc/lighting_clear_overlays():
- Delete (manual GC) all light overlays on this turf, used when changing turf to space
- proc/lighting_build_overlays():
- Create lighting overlays for this turf
- proc/get_lumcount(var/minlum = 0, var/maxlum = 1)
- Returns a decimal according to the amount of lums on a turf's overlay (also averages them)
- With default arguments (based on the fact that 0 = pitch black and 1 = full bright), it will return .5 for a 50% lit tile.
atom/movable/lighting_overlay: (lighting_overlay.dm)
- var/lum_r, var/lum_g, var/lum_b; lumcounts of each colour
- var/needs_update; set on update_lumcount, checked by lighting process
- var/xoffset, var/yoffset; (only present when using sub-tile overlays) fractional offset of this overlay in the tile
- proc/update_lumcount(delta_r, delta_g, delta_b):
- Change the lumcount vars and queue the overlay for update
- proc/update_overlay()
- Called by the lighting process to update the color of the overlay
*/
+30
View File
@@ -0,0 +1,30 @@
/area
luminosity = TRUE
var/dynamic_lighting = DYNAMIC_LIGHTING_ENABLED
/area/New()
. = ..()
// Moved to the subsystem.
/*
if (dynamic_lighting)
luminosity = FALSE
*/
/area/proc/set_dynamic_lighting(var/new_dynamic_lighting = DYNAMIC_LIGHTING_ENABLED)
if (new_dynamic_lighting == dynamic_lighting)
return FALSE
dynamic_lighting = new_dynamic_lighting
if (IS_DYNAMIC_LIGHTING(src))
for (var/turf/T in (area_contents()))
if (IS_DYNAMIC_LIGHTING(T))
T.lighting_build_overlay()
else
for (var/turf/T in (area_contents()))
if (T.lighting_overlay)
T.lighting_clear_overlay()
return TRUE
+105
View File
@@ -0,0 +1,105 @@
#define MINIMUM_USEFUL_LIGHT_RANGE 1.4
/atom
var/light_power = 1 // Intensity of the light.
var/light_range = 0 // Range in tiles of the light.
var/light_color // Hexadecimal RGB string representing the colour of the light.
var/tmp/datum/light_source/light // Our light source. Don't fuck with this directly unless you have a good reason!
var/tmp/list/light_sources // Any light sources that are "inside" of us, for example, if src here was a mob that's carrying a flashlight, that flashlight's light source would be part of this list.
// The proc you should always use to set the light of this atom.
// Nonesensical value for l_color default, so we can detect if it gets set to null.
#define NONSENSICAL_VALUE -99999
/atom/proc/set_light(var/l_range, var/l_power, var/l_color = NONSENSICAL_VALUE)
if(l_range > 0 && l_range < MINIMUM_USEFUL_LIGHT_RANGE)
l_range = MINIMUM_USEFUL_LIGHT_RANGE //Brings the range up to 1.4, which is just barely brighter than the soft lighting that surrounds players.
if (l_power != null)
light_power = l_power
if (l_range != null)
light_range = l_range
if (l_color != NONSENSICAL_VALUE)
light_color = l_color
update_light()
#undef NONSENSICAL_VALUE
// Will update the light (duh).
// Creates or destroys it if needed, makes it update values, makes sure it's got the correct source turf...
/atom/proc/update_light()
set waitfor = FALSE
if (qdeleted(src))
return
if (!light_power || !light_range) // We won't emit light anyways, destroy the light source.
if(light)
light.destroy()
light = null
else
if (!istype(loc, /atom/movable)) // We choose what atom should be the top atom of the light here.
. = src
else
. = loc
if (light) // Update the light or create it if it does not exist.
light.update(.)
else
light = new/datum/light_source(src, .)
// Incase any lighting vars are on in the typepath we turn the light on in New().
/atom/New()
. = ..()
if (light_power && light_range)
update_light()
if (opacity && isturf(loc))
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.
// Destroy our light source so we GC correctly.
/atom/Destroy()
if (light)
light.destroy()
light = null
. = ..()
// If we have opacity, make sure to tell (potentially) affected light sources.
/atom/movable/Destroy()
var/turf/T = loc
if (opacity && istype(T))
T.reconsider_lights()
. = ..()
// Should always be used to change the opacity of an atom.
// It notifies (potentially) affected light sources so they can update (if needed).
/atom/proc/set_opacity(var/new_opacity)
if (new_opacity == opacity)
return
opacity = new_opacity
var/turf/T = loc
if (!isturf(T))
return
if (new_opacity == TRUE)
T.has_opaque_atom = TRUE
T.reconsider_lights()
else
var/old_has_opaque_atom = T.has_opaque_atom
T.recalc_atom_opacity()
if (old_has_opaque_atom != T.has_opaque_atom)
T.reconsider_lights()
// This code makes the light be queued for update when it is moved.
// Entered() should handle it, however Exited() can do it if it is being moved to nullspace (as there would be no Entered() call in that situation).
/atom/movable/Moved(atom/OldLoc, Dir) //Implemented here because forceMove() doesn't call Move()
. = ..()
for (var/datum/light_source/L in src.light_sources) // Cycle through the light sources on this atom and tell them to update.
L.source_atom.update_light()
+137
View File
@@ -0,0 +1,137 @@
/var/list/datum/lighting_corner/all_lighting_corners = list()
/var/datum/lighting_corner/dummy/dummy_lighting_corner = new
// Because we can control each corner of every lighting overlay.
// And corners get shared between multiple turfs (unless you're on the corners of the map, then 1 corner doesn't).
// For the record: these should never ever ever be deleted, even if the turf doesn't have dynamic lighting.
// This list is what the code that assigns corners listens to, the order in this list is the order in which corners are added to the /turf/corners list.
/var/list/LIGHTING_CORNER_DIAGONAL = list(NORTHEAST, SOUTHEAST, SOUTHWEST, NORTHWEST)
/datum/lighting_corner
var/list/turf/masters = list()
var/list/datum/light_source/affecting = list() // Light sources affecting us.
var/active = FALSE // TRUE if one of our masters has dynamic lighting.
var/x = 0
var/y = 0
var/z = 0
var/lum_r = 0
var/lum_g = 0
var/lum_b = 0
var/needs_update = FALSE
var/cache_r = 0
var/cache_g = 0
var/cache_b = 0
var/cache_mx = 0
var/update_gen = 0
/datum/lighting_corner/New(var/turf/new_turf, var/diagonal)
. = ..()
all_lighting_corners += src
masters[new_turf] = turn(diagonal, 180)
z = new_turf.z
var/vertical = diagonal & ~(diagonal - 1) // The horizontal directions (4 and 8) are bigger than the vertical ones (1 and 2), so we can reliably say the lsb is the horizontal direction.
var/horizontal = diagonal & ~vertical // Now that we know the horizontal one we can get the vertical one.
x = new_turf.x + (horizontal == EAST ? 0.5 : -0.5)
y = new_turf.y + (vertical == NORTH ? 0.5 : -0.5)
// My initial plan was to make this loop through a list of all the dirs (horizontal, vertical, diagonal).
// Issue being that the only way I could think of doing it was very messy, slow and honestly overengineered.
// So we'll have this hardcode instead.
var/turf/T
var/i
// Diagonal one is easy.
T = get_step(new_turf, diagonal)
if (T) // In case we're on the map's border.
if (!T.corners)
T.corners = list(null, null, null, null)
masters[T] = diagonal
i = LIGHTING_CORNER_DIAGONAL.Find(turn(diagonal, 180))
T.corners[i] = src
// Now the horizontal one.
T = get_step(new_turf, horizontal)
if (T) // Ditto.
if (!T.corners)
T.corners = list(null, null, null, null)
masters[T] = ((T.x > x) ? EAST : WEST) | ((T.y > y) ? NORTH : SOUTH) // Get the dir based on coordinates.
i = LIGHTING_CORNER_DIAGONAL.Find(turn(masters[T], 180))
T.corners[i] = src
// And finally the vertical one.
T = get_step(new_turf, vertical)
if (T)
if (!T.corners)
T.corners = list(null, null, null, null)
masters[T] = ((T.x > x) ? EAST : WEST) | ((T.y > y) ? NORTH : SOUTH) // Get the dir based on coordinates.
i = LIGHTING_CORNER_DIAGONAL.Find(turn(masters[T], 180))
T.corners[i] = src
update_active()
/datum/lighting_corner/proc/update_active()
active = FALSE
for (var/turf/T in masters)
if (T.lighting_overlay)
active = TRUE
// God that was a mess, now to do the rest of the corner code! Hooray!
/datum/lighting_corner/proc/update_lumcount(var/delta_r, var/delta_g, var/delta_b)
lum_r += delta_r
lum_g += delta_g
lum_b += delta_b
#ifndef LIGHTING_INSTANT_UPDATES
if (!needs_update)
needs_update = TRUE
lighting_update_corners += src
/datum/lighting_corner/proc/update_overlays()
#endif
// Cache these values a head of time so 4 individual lighting overlays don't all calculate them individually.
var/mx = max(lum_r, lum_g, lum_b) // Scale it so 1 is the strongest lum, if it is above 1.
. = 1 // factor
if (mx > 1)
. = 1 / mx
else if (mx < LIGHTING_SOFT_THRESHOLD)
. = 0 // 0 means soft lighting.
cache_r = lum_r * . || LIGHTING_SOFT_THRESHOLD
cache_g = lum_g * . || LIGHTING_SOFT_THRESHOLD
cache_b = lum_b * . || LIGHTING_SOFT_THRESHOLD
cache_mx = mx
for (var/TT in masters)
var/turf/T = TT
if (T.lighting_overlay)
#ifdef LIGHTING_INSTANT_UPDATES
T.lighting_overlay.update_overlay()
#else
if (!T.lighting_overlay.needs_update)
T.lighting_overlay.needs_update = TRUE
lighting_update_overlays += T.lighting_overlay
#endif
/datum/lighting_corner/dummy/New()
return
/datum/lighting_corner/Destroy(var/force)
if(force)
CRASH("Nope you're not deleting me!")
return QDEL_HINT_LETMELIVE
+112
View File
@@ -0,0 +1,112 @@
/var/list/all_lighting_overlays = list() // Global list of lighting overlays.
/atom/movable/lighting_overlay
name = ""
anchored = TRUE
icon = LIGHTING_ICON
color = LIGHTING_BASE_MATRIX
mouse_opacity = 0
layer = LIGHTING_LAYER
invisibility = INVISIBILITY_LIGHTING
blend_mode = BLEND_MULTIPLY
var/needs_update = FALSE
/atom/movable/lighting_overlay/New(var/atom/loc, var/no_update = FALSE)
. = ..()
verbs.Cut()
global.all_lighting_overlays += src
var/turf/T = loc // If this runtimes atleast we'll know what's creating overlays in things that aren't turfs.
T.lighting_overlay = src
T.luminosity = 0
for(var/turf/open/space/S in RANGE_TURFS(1,src)) //RANGE_TURFS is in code\__HELPERS\game.dm
S.update_starlight()
if (no_update)
return
update_overlay()
/atom/movable/lighting_overlay/Destroy(var/force)
global.all_lighting_overlays -= src
global.lighting_update_overlays -= src
global.lighting_update_overlays_old -= src
var/turf/T = loc
if (istype(T))
T.lighting_overlay = null
T.luminosity = 1
if (force)
..()
return QDEL_HINT_PUTINPOOL
else
return QDEL_HINT_LETMELIVE
/atom/movable/lighting_overlay/proc/update_overlay()
var/turf/T = loc
if (!istype(T)) // Erm...
if (loc)
warning("A lighting overlay realised its loc was NOT a turf (actual loc: [loc], [loc.type]) in update_overlay() and got pooled!")
else
warning("A lighting overlay realised it was in nullspace in update_overlay() and got pooled!")
qdel(src, TRUE)
return
// To the future coder who sees this and thinks
// "Why didn't he just use a loop?"
// Well my man, it's because the loop performed like shit.
// And there's no way to improve it because
// without a loop you can make the list all at once which is the fastest you're gonna get.
// Oh it's also shorter line wise.
// Including with these comments.
// See LIGHTING_CORNER_DIAGONAL in lighting_corner.dm for why these values are what they are.
// No I seriously cannot think of a more efficient method, fuck off Comic.
var/datum/lighting_corner/cr = T.corners[3] || dummy_lighting_corner
var/datum/lighting_corner/cg = T.corners[2] || dummy_lighting_corner
var/datum/lighting_corner/cb = T.corners[4] || dummy_lighting_corner
var/datum/lighting_corner/ca = T.corners[1] || dummy_lighting_corner
var/max = max(cr.cache_mx, cg.cache_mx, cb.cache_mx, ca.cache_mx)
color = list(
cr.cache_r, cr.cache_g, cr.cache_b, 0,
cg.cache_r, cg.cache_g, cg.cache_b, 0,
cb.cache_r, cb.cache_g, cb.cache_b, 0,
ca.cache_r, ca.cache_g, ca.cache_b, 0,
0, 0, 0, 1
)
luminosity = max > LIGHTING_SOFT_THRESHOLD
// Variety of overrides so the overlays don't get affected by weird things.
/atom/movable/lighting_overlay/ex_act(severity)
return 0
/atom/movable/lighting_overlay/singularity_act()
return
/atom/movable/lighting_overlay/singularity_pull()
return
/atom/movable/lighting_overlay/blob_act()
return
// Override here to prevent things accidentally moving around overlays.
/atom/movable/lighting_overlay/forceMove(atom/destination, var/no_tp=FALSE, var/harderforce = FALSE)
if(harderforce)
. = ..()
/atom/movable/lighting_overlay/ResetVars()
color = LIGHTING_BASE_MATRIX
..("color")
+17
View File
@@ -0,0 +1,17 @@
/proc/create_all_lighting_overlays()
for (var/zlevel = 1 to world.maxz)
create_lighting_overlays_zlevel(zlevel)
/proc/create_lighting_overlays_zlevel(var/zlevel)
ASSERT(zlevel)
for (var/turf/T in block(locate(1, 1, zlevel), locate(world.maxx, world.maxy, zlevel)))
if (!IS_DYNAMIC_LIGHTING(T))
continue
var/area/A = T.loc
if (!IS_DYNAMIC_LIGHTING(A))
continue
PoolOrNew(/atom/movable/lighting_overlay, list(T, TRUE))
+305
View File
@@ -0,0 +1,305 @@
// This is where the fun begins.
// These are the main datums that emit light.
/datum/light_source
var/atom/top_atom // The atom we're emitting light from (for example a mob if we're from a flashlight that's being held).
var/atom/source_atom // The atom that we belong to.
var/turf/source_turf // The turf under the above.
var/light_power // Intensity of the emitter light.
var/light_range // The range of the emitted light.
var/light_color // The colour of the light, string, decomposed by parse_light_color()
// Variables for keeping track of the colour.
var/lum_r
var/lum_g
var/lum_b
// The lumcount values used to apply the light.
var/tmp/applied_lum_r
var/tmp/applied_lum_g
var/tmp/applied_lum_b
var/list/datum/lighting_corner/effect_str // List used to store how much we're affecting corners.
var/list/turf/affecting_turfs
var/applied = FALSE // Whether we have applied our light yet or not.
var/vis_update // Whether we should smartly recalculate visibility. and then only update tiles that became (in)visible to us.
var/needs_update // Whether we are queued for an update.
var/destroyed // Whether we are destroyed and need to stop emitting light.
var/force_update
/datum/light_source/New(var/atom/owner, var/atom/top)
source_atom = owner // Set our new owner.
if (!source_atom.light_sources)
source_atom.light_sources = list()
source_atom.light_sources += src // Add us to the lights of our owner.
top_atom = top
if (top_atom != source_atom)
if (!top.light_sources)
top.light_sources = list()
top_atom.light_sources += src
source_turf = top_atom
light_power = source_atom.light_power
light_range = source_atom.light_range
light_color = source_atom.light_color
parse_light_color()
effect_str = list()
affecting_turfs = list()
update()
return ..()
// Kill ourselves.
/datum/light_source/proc/destroy()
destroyed = TRUE
force_update()
if (source_atom)
if (source_atom.light == src)
source_atom.light = null
source_atom.light_sources -= src
if (top_atom)
top_atom.light_sources -= src
// Fuck supporting force.
/datum/light_source/Destroy(var/force)
destroy()
return QDEL_HINT_IWILLGC
#ifdef LIGHTING_INSTANT_UPDATES
/datum/light_source/proc/effect_update()
if (check() || destroyed || force_update)
remove_lum()
if (!destroyed)
apply_lum()
else if (vis_update) // We smartly update only tiles that became (in) visible to use.
smart_vis_update()
vis_update = FALSE
force_update = FALSE
needs_update = FALSE
#else
// Call it dirty, I don't care.
// This is here so there's no performance loss on non-instant updates from the fact that the engine can also do instant updates.
// If you're wondering what's with the "BYOND" argument: BYOND won't let me have a () macro that has no arguments :|.
#define effect_update(BYOND) \
if (!needs_update) \
{ \
lighting_update_lights += src; \
needs_update = TRUE; \
}
#endif
// This proc will cause the light source to update the top atom, and add itself to the update queue.
/datum/light_source/proc/update(var/atom/new_top_atom)
// This top atom is different.
if (new_top_atom && new_top_atom != top_atom)
if(top_atom != source_atom) // Remove ourselves from the light sources of that top atom.
top_atom.light_sources -= src
top_atom = new_top_atom
if (top_atom != source_atom)
if(!top_atom.light_sources)
top_atom.light_sources = list()
top_atom.light_sources += src // Add ourselves to the light sources of our new top atom.
effect_update(null)
// Will force an update without checking if it's actually needed.
/datum/light_source/proc/force_update()
force_update = 1
effect_update(null)
// Will cause the light source to recalculate turfs that were removed or added to visibility only.
/datum/light_source/proc/vis_update()
vis_update = 1
effect_update(null)
// Will check if we actually need to update, and update any variables that may need to be updated.
/datum/light_source/proc/check()
if (!source_atom || !light_range || !light_power)
destroy()
return 1
if (!top_atom)
top_atom = source_atom
. = 1
if (istype(top_atom, /turf))
if (source_turf != top_atom)
source_turf = top_atom
. = 1
else if (top_atom.loc != source_turf)
source_turf = top_atom.loc
. = 1
if (source_atom.light_power != light_power)
light_power = source_atom.light_power
. = 1
if (source_atom.light_range != light_range)
light_range = source_atom.light_range
. = 1
if (light_range && light_power && !applied)
. = 1
if (source_atom.light_color != light_color)
light_color = source_atom.light_color
parse_light_color()
. = 1
// Decompile the hexadecimal colour into lumcounts of each perspective.
/datum/light_source/proc/parse_light_color()
if (light_color)
lum_r = GetRedPart (light_color) / 255
lum_g = GetGreenPart (light_color) / 255
lum_b = GetBluePart (light_color) / 255
else
lum_r = 1
lum_g = 1
lum_b = 1
// Macro that applies light to a new corner.
// It is a macro in the interest of speed, yet not having to copy paste it.
// If you're wondering what's with the backslashes, the backslashes cause BYOND to not automatically end the line.
// As such this all gets counted as a single line.
// The braces and semicolons are there to be able to do this on a single line.
#define APPLY_CORNER(C) \
. = LUM_FALLOFF(C, source_turf); \
\
. *= light_power; \
\
effect_str[C] = .; \
\
C.update_lumcount \
( \
. * applied_lum_r, \
. * applied_lum_g, \
. * applied_lum_b \
);
// I don't need to explain what this does, do I?
#define REMOVE_CORNER(C) \
. = -effect_str[C]; \
C.update_lumcount \
( \
. * applied_lum_r, \
. * applied_lum_g, \
. * applied_lum_b \
);
// This is the define used to calculate falloff.
#define LUM_FALLOFF(C, T) (1 - CLAMP01(sqrt((C.x - T.x) ** 2 + (C.y - T.y) ** 2 + LIGHTING_HEIGHT) / max(1, light_range)))
/datum/light_source/proc/apply_lum()
var/static/update_gen = 1
applied = 1
// Keep track of the last applied lum values so that the lighting can be reversed
applied_lum_r = lum_r
applied_lum_g = lum_g
applied_lum_b = lum_b
FOR_DVIEW(var/turf/T, light_range, source_turf, INVISIBILITY_LIGHTING)
if (!T.lighting_corners_initialised)
T.generate_missing_corners()
for (var/datum/lighting_corner/C in T.get_corners())
if (C.update_gen == update_gen)
continue
C.update_gen = update_gen
C.affecting += src
if (!C.active)
continue
APPLY_CORNER(C)
if (!T.affecting_lights)
T.affecting_lights = list()
T.affecting_lights += src
affecting_turfs += T
update_gen++
/datum/light_source/proc/remove_lum()
applied = FALSE
for (var/turf/T in affecting_turfs)
if (!T.affecting_lights)
T.affecting_lights = list()
else
T.affecting_lights -= src
affecting_turfs.Cut()
for (var/datum/lighting_corner/C in effect_str)
REMOVE_CORNER(C)
C.affecting -= src
effect_str.Cut()
/datum/light_source/proc/recalc_corner(var/datum/lighting_corner/C)
if (effect_str.Find(C)) // Already have one.
REMOVE_CORNER(C)
APPLY_CORNER(C)
/datum/light_source/proc/smart_vis_update()
var/list/datum/lighting_corner/corners = list()
var/list/turf/turfs = list()
FOR_DVIEW(var/turf/T, light_range, source_turf, 0)
if (!T.lighting_corners_initialised)
T.generate_missing_corners()
corners |= T.get_corners()
turfs += T
var/list/L = turfs - affecting_turfs // New turfs, add us to the affecting lights of them.
affecting_turfs += L
for (var/turf/T in L)
if (!T.affecting_lights)
T.affecting_lights = list(src)
else
T.affecting_lights += src
L = affecting_turfs - turfs // Now-gone turfs, remove us from the affecting lights.
affecting_turfs -= L
for (var/turf/T in L)
T.affecting_lights -= src
for (var/datum/lighting_corner/C in corners - effect_str) // New corners
C.affecting += src
if (!C.active)
continue
APPLY_CORNER(C)
for (var/datum/lighting_corner/C in effect_str - corners) // Old, now gone, corners.
REMOVE_CORNER(C)
C.affecting -= src
effect_str -= C
#undef effect_update
#undef LUM_FALLOFF
#undef REMOVE_CORNER
#undef APPLY_CORNER
-428
View File
@@ -1,428 +0,0 @@
/*
This is /tg/'s 'newer' lighting system. It's basically a combination of Forum_Account's and ShadowDarke's
respective lighting libraries heavily modified by Carnwennan for /tg/station with further edits by
MrPerson. Credits, where due, to them.
Originally, like all other lighting libraries on BYOND, we used areas to render different hard-coded light levels.
The idea was that this was cheaper than using objects. Well as it turns out, the cost of the system is primarily from the
massive loops the system has to run, not from the areas or objects actually doing any work. Thus the newer system uses objects
so we can have more lighting states and smooth transitions between them.
This is a queueing system. Everytime we call a change to opacity or luminosity throwgh SetOpacity() or SetLuminosity(),
we are simply updating variables and scheduling certain lights/turfs for an update. Actual updates are handled
periodically by the SSlighting subsystem. Specifically, it runs check() on every light datum that ran changed().
Then it runs redraw_lighting() on every turf that ran update_lumcount().
Unlike our older system, there are hardcoded maximum luminosities (different for certain atoms).
This is to cap the cost of creating lighting effects.
(without this, an atom with luminosity of 20 would have to update 41^2 turfs!) :s
Each light remembers the effect it casts on each turf. It reduces cost of removing lighting effects by a lot!
Known Issues/TODO:
Shuttles still do not have support for dynamic lighting (I hope to fix this at some point) -probably trivial now
No directional lighting support. (prototype looked ugly)
Allow lights to be weaker than 'cap' radius
Colored lights
*/
#define LIGHTING_CIRCULAR 1 //Comment this out to use old square lighting effects.
//#define LIGHTING_LAYER 15 //Drawing layer for lighting, moved to layers.dm
#define LIGHTING_CAP 10 //The lumcount level at which alpha is 0 and we're fully lit.
#define LIGHTING_CAP_FRAC (255/LIGHTING_CAP) //A precal'd variable we'll use in turf/redraw_lighting()
#define LIGHTING_ICON 'icons/effects/alphacolors.dmi'
#define LIGHTING_ICON_STATE "white"
#define LIGHTING_TIME 2 //Time to do any lighting change. Actual number pulled out of my ass
#define LIGHTING_DARKEST_VISIBLE_ALPHA 250 //Anything darker than this is so dark, we'll just consider the whole tile unlit
#define LIGHTING_LUM_FOR_FULL_BRIGHT 6 //Anything who's lum is lower then this starts off less bright.
#define LIGHTING_MIN_RADIUS 4 //Lowest radius a light source can effect.
/datum/light_source
var/atom/owner
var/radius = 0
var/luminosity = 0
var/cap = 0
var/changed = 0
var/list/effect = list()
var/__x = 0 //x coordinate at last update
var/__y = 0 //y coordinate at last update
/datum/light_source/New(atom/A)
if(!istype(A))
CRASH("The first argument to the light object's constructor must be the atom that is the light source. Expected atom, received '[A]' instead.")
..()
owner = A
UpdateLuminosity(A.luminosity)
/datum/light_source/Destroy()
if(owner && owner.light == src)
remove_effect()
owner.light = null
owner.luminosity = 0
owner = null
if(changed)
SSlighting.changed_lights -= src
return ..()
/datum/light_source/proc/UpdateLuminosity(new_luminosity, new_cap)
if(new_luminosity < 0)
new_luminosity = 0
if(luminosity == new_luminosity && (new_cap == null || cap == new_cap))
return
radius = max(LIGHTING_MIN_RADIUS, new_luminosity)
luminosity = new_luminosity
if (new_cap != null)
cap = new_cap
changed()
//Check a light to see if its effect needs reprocessing. If it does, remove any old effect and create a new one
/datum/light_source/proc/check()
if(!owner)
remove_effect()
return 0
if(changed)
changed = 0
remove_effect()
return add_effect()
return 1
//Tell the lighting subsystem to check() next fire
/datum/light_source/proc/changed()
if(owner)
__x = owner.x
__y = owner.y
if(!changed)
changed = 1
SSlighting.changed_lights |= src
//Remove current effect
/datum/light_source/proc/remove_effect().
for(var/turf/T in effect)
T.update_lumcount(-effect[T])
if(T.affecting_lights && T.affecting_lights.len)
T.affecting_lights -= src
effect.Cut()
//Apply a new effect.
/datum/light_source/proc/add_effect()
// only do this if the light is turned on and is on the map
if(!owner || !owner.loc)
return 0
var/range = owner.get_light_range(radius)
if(range <= 0 || luminosity <= 0)
owner.luminosity = 0
return 0
effect = list()
var/turf/To = get_turf(owner)
for(var/atom/movable/AM in To)
if(AM == owner)
continue
if(AM.opacity)
range = 1
break
owner.luminosity = range
var/center_strength = 0
if (cap <= 0)
center_strength = LIGHTING_CAP/LIGHTING_LUM_FOR_FULL_BRIGHT*(luminosity)
else
center_strength = cap
for(var/turf/T in view(range+1, To))
#ifdef LIGHTING_CIRCULAR
var/distance = cheap_hypotenuse(T.x, T.y, __x, __y)
#else
var/distance = max(abs(T,x - __x), abs(T.y - __y))
#endif
var/delta_lumcount = Clamp(center_strength * (range - distance) / range, 0, LIGHTING_CAP)
if(delta_lumcount > 0)
effect[T] = delta_lumcount
T.update_lumcount(delta_lumcount)
if(!T.affecting_lights)
T.affecting_lights = list()
T.affecting_lights |= src
return 1
/atom
var/datum/light_source/light
//Turfs with opacity when they are constructed will trigger nearby lights to update
//Turfs and atoms with luminosity when they are constructed will create a light_source automatically
/turf/New()
..()
if(luminosity)
light = new(src)
//Movable atoms with opacity when they are constructed will trigger nearby lights to update
//Movable atoms with luminosity when they are constructed will create a light_source automatically
/atom/movable/New()
..()
if(opacity && isturf(loc))
loc.UpdateAffectingLights()
if(luminosity)
light = new(src)
//Objects with opacity will trigger nearby lights to update at next SSlighting fire
/atom/movable/Destroy()
qdel(light)
if(opacity && isturf(loc))
loc.UpdateAffectingLights()
return ..()
//Objects with opacity will trigger nearby lights of the old location to update at next SSlighting fire
/atom/movable/Moved(atom/OldLoc, Dir)
if(opacity)
if (isturf(OldLoc))
OldLoc.UpdateAffectingLights()
if (isturf(loc))
loc.UpdateAffectingLights()
else
if(light)
light.changed()
return ..()
//Sets our luminosity.
//If we have no light it will create one.
//If we are setting luminosity to 0 the light will be cleaned up by the controller and garbage collected once all its
//queues are complete.
//if we have a light already it is merely updated, rather than making a new one.
//The second arg allows you to scale the light cap for calculating falloff.
/atom/proc/SetLuminosity(new_luminosity, new_cap)
if (!light)
if (new_luminosity <= 0)
return
light = new(src)
light.UpdateLuminosity(new_luminosity, new_cap)
/atom/proc/AddLuminosity(delta_luminosity)
if(light)
SetLuminosity(light.luminosity + delta_luminosity)
else
SetLuminosity(delta_luminosity)
/area/SetLuminosity(new_luminosity) //we don't want dynamic lighting for areas
luminosity = !!new_luminosity
//change our opacity (defaults to toggle), and then update all lights that affect us.
/atom/proc/SetOpacity(new_opacity)
if(new_opacity == null)
new_opacity = !opacity //default = toggle opacity
else if(opacity == new_opacity)
return 0 //opacity hasn't changed! don't bother doing anything
opacity = new_opacity //update opacity, the below procs now call light updates.
UpdateAffectingLights()
return 1
/atom/movable/light
icon = LIGHTING_ICON
icon_state = LIGHTING_ICON_STATE
layer = LIGHTING_LAYER
mouse_opacity = 0
blend_mode = BLEND_OVERLAY
invisibility = INVISIBILITY_LIGHTING
color = "#000"
luminosity = 0
infra_luminosity = 1
anchored = 1
/atom/movable/light/Destroy(force)
if(force)
. = ..()
else
return QDEL_HINT_LETMELIVE
/atom/movable/light/Move()
return 0
/turf
var/lighting_lumcount = 0
var/lighting_changed = 0
var/atom/movable/light/lighting_object //Will be null for space turfs and anything in a static lighting area
var/list/affecting_lights //not initialised until used (even empty lists reserve a fair bit of memory)
/turf/ChangeTurf(path)
if(!path || (!use_preloader && path == type)) //Sucks this is here but it would cause problems otherwise.
return ..()
for(var/obj/effect/decal/cleanable/decal in src.contents)
qdel(decal)
if(light)
qdel(light)
var/old_lumcount = lighting_lumcount - initial(lighting_lumcount)
var/oldbaseturf = baseturf
var/list/our_lights //reset affecting_lights if needed
if(opacity != initial(path:opacity) && old_lumcount)
UpdateAffectingLights()
if(affecting_lights)
our_lights = affecting_lights.Copy()
. = ..() //At this point the turf has changed
affecting_lights = our_lights
lighting_changed = 1 //Don't add ourself to SSlighting.changed_turfs
update_lumcount(old_lumcount)
baseturf = oldbaseturf
lighting_object = locate() in src
init_lighting()
for(var/turf/open/space/S in RANGE_TURFS(1,src)) //RANGE_TURFS is in code\__HELPERS\game.dm
S.update_starlight()
/turf/proc/update_lumcount(amount)
lighting_lumcount += amount
if(!lighting_changed)
SSlighting.changed_turfs += src
lighting_changed = 1
/turf/open/space/update_lumcount(amount) //Keep track in case the turf becomes a floor at some point, but don't process.
lighting_lumcount += amount
/turf/proc/init_lighting()
var/area/A = loc
if(!IS_DYNAMIC_LIGHTING(A))
if(lighting_changed)
lighting_changed = 0
if(lighting_object)
lighting_object.alpha = 0
lighting_object = null
else
if(!lighting_object)
lighting_object = new (src)
redraw_lighting(1)
for(var/turf/open/space/T in RANGE_TURFS(1,src))
T.update_starlight()
/turf/open/space/init_lighting()
if(lighting_changed)
lighting_changed = 0
if(lighting_object)
lighting_object.alpha = 0
lighting_object = null
/turf/proc/redraw_lighting(instantly = 0)
if(lighting_object)
var/newalpha
if(lighting_lumcount <= 0)
newalpha = 255
else
if(lighting_lumcount < LIGHTING_CAP)
var/num = Clamp(lighting_lumcount * LIGHTING_CAP_FRAC, 0, 255)
newalpha = 255-num
else //if(lighting_lumcount >= LIGHTING_CAP)
newalpha = 0
if(newalpha >= LIGHTING_DARKEST_VISIBLE_ALPHA)
newalpha = 255
if(lighting_object.alpha != newalpha)
if(instantly)
lighting_object.alpha = newalpha
else
animate(lighting_object, alpha = newalpha, time = LIGHTING_TIME)
if(newalpha >= LIGHTING_DARKEST_VISIBLE_ALPHA)
luminosity = 0
lighting_object.luminosity = 0
else
luminosity = 1
lighting_object.luminosity = 1
lighting_changed = 0
/turf/proc/get_lumcount()
. = LIGHTING_CAP
var/area/A = src.loc
if(IS_DYNAMIC_LIGHTING(A))
. = src.lighting_lumcount
/area
var/lighting_use_dynamic = DYNAMIC_LIGHTING_ENABLED //Turn this flag off to make the area fullbright
/area/New()
. = ..()
if(lighting_use_dynamic != DYNAMIC_LIGHTING_ENABLED)
luminosity = 1
/area/proc/SetDynamicLighting()
if (lighting_use_dynamic == DYNAMIC_LIGHTING_DISABLED)
lighting_use_dynamic = DYNAMIC_LIGHTING_ENABLED
luminosity = 0
for(var/turf/T in src.contents)
T.init_lighting()
T.update_lumcount(0)
#undef LIGHTING_CIRCULAR
#undef LIGHTING_ICON
#undef LIGHTING_ICON_STATE
#undef LIGHTING_TIME
#undef LIGHTING_CAP
#undef LIGHTING_CAP_FRAC
#undef LIGHTING_DARKEST_VISIBLE_ALPHA
#undef LIGHTING_LUM_FOR_FULL_BRIGHT
#undef LIGHTING_MIN_RADIUS
//set the changed status of all lights which could have possibly lit this atom.
//We don't need to worry about lights which lit us but moved away, since they will have change status set already
//This proc can cause lots of lights to be updated. :(
/atom/proc/UpdateAffectingLights()
/atom/movable/UpdateAffectingLights()
if(isturf(loc))
loc.UpdateAffectingLights()
/turf/UpdateAffectingLights()
if(affecting_lights)
for(var/datum/light_source/thing in affecting_lights)
if (!thing.changed)
thing.changed() //force it to update at next process()
#define LIGHTING_MAX_LUMINOSITY_STATIC 8 //Maximum luminosity to reduce lag.
#define LIGHTING_MAX_LUMINOSITY_MOBILE 7 //Moving objects have a lower max luminosity since these update more often. (lag reduction)
#define LIGHTING_MAX_LUMINOSITY_MOB 6
#define LIGHTING_MAX_LUMINOSITY_TURF 8 //turfs are static too, why was this 1?!
//caps luminosity effects max-range based on what type the light's owner is.
/atom/proc/get_light_range(radius)
return min(radius, LIGHTING_MAX_LUMINOSITY_STATIC)
/atom/movable/get_light_range(radius)
return min(radius, LIGHTING_MAX_LUMINOSITY_MOBILE)
/mob/get_light_range(radius)
return min(radius, LIGHTING_MAX_LUMINOSITY_MOB)
/obj/machinery/light/get_light_range(radius)
return min(radius, LIGHTING_MAX_LUMINOSITY_STATIC)
/turf/get_light_range(radius)
return min(radius, LIGHTING_MAX_LUMINOSITY_TURF)
#undef LIGHTING_MAX_LUMINOSITY_STATIC
#undef LIGHTING_MAX_LUMINOSITY_MOBILE
#undef LIGHTING_MAX_LUMINOSITY_MOB
#undef LIGHTING_MAX_LUMINOSITY_TURF
+153
View File
@@ -0,0 +1,153 @@
/turf
var/dynamic_lighting = DYNAMIC_LIGHTING_ENABLED
luminosity = 1
var/tmp/lighting_corners_initialised = FALSE
var/tmp/list/datum/light_source/affecting_lights // List of light sources affecting this turf.
var/tmp/atom/movable/lighting_overlay/lighting_overlay // Our lighting overlay.
var/tmp/list/datum/lighting_corner/corners
var/tmp/has_opaque_atom = FALSE // Not to be confused with opacity, this will be TRUE if there's any opaque atom on the tile.
/turf/New()
. = ..()
if (opacity)
has_opaque_atom = TRUE
// Causes any affecting light sources to be queued for a visibility update, for example a door got opened.
/turf/proc/reconsider_lights()
for (var/datum/light_source/L in affecting_lights)
L.vis_update()
/turf/proc/lighting_clear_overlay()
if (lighting_overlay)
qdel(lighting_overlay, TRUE)
lighting_overlay = null
for (var/datum/lighting_corner/C in corners)
C.update_active()
for(var/turf/open/space/S in RANGE_TURFS(1,src)) //RANGE_TURFS is in code\__HELPERS\game.dm
S.update_starlight()
// Builds a lighting overlay for us, but only if our area is dynamic.
/turf/proc/lighting_build_overlay()
if (lighting_overlay)
return
var/area/A = loc
if (IS_DYNAMIC_LIGHTING(A))
if (!lighting_corners_initialised)
generate_missing_corners()
PoolOrNew(/atom/movable/lighting_overlay, src)
for (var/datum/lighting_corner/C in corners)
if (!C.active) // We would activate the corner, calculate the lighting for it.
for (var/L in C.affecting)
var/datum/light_source/S = L
S.recalc_corner(C)
C.active = TRUE
// Used to get a scaled lumcount.
/turf/proc/get_lumcount(var/minlum = 0, var/maxlum = 1)
if (!lighting_overlay)
return 0.5
var/totallums = 0
for (var/datum/lighting_corner/L in corners)
totallums += L.lum_r + L.lum_b + L.lum_g
totallums /= 12 // 4 corners, each with 3 channels, get the average.
totallums = (totallums - minlum) / (maxlum - minlum)
return CLAMP01(totallums)
// Can't think of a good name, this proc will recalculate the has_opaque_atom variable.
/turf/proc/recalc_atom_opacity()
has_opaque_atom = FALSE
for (var/atom/A in src.contents + src) // Loop through every movable atom on our tile PLUS ourselves (we matter too...)
if (A.opacity)
has_opaque_atom = TRUE
// If an opaque movable atom moves around we need to potentially update visibility.
/turf/Entered(var/atom/movable/Obj, var/atom/OldLoc)
. = ..()
if (Obj && Obj.opacity)
has_opaque_atom = TRUE // Make sure to do this before reconsider_lights(), incase we're on instant updates. Guaranteed to be on in this case.
reconsider_lights()
/turf/Exited(var/atom/movable/Obj, var/atom/newloc)
. = ..()
if (Obj && Obj.opacity)
recalc_atom_opacity() // Make sure to do this before reconsider_lights(), incase we're on instant updates.
reconsider_lights()
/turf/change_area(var/area/old_area, var/area/new_area)
if (IS_DYNAMIC_LIGHTING(new_area) != IS_DYNAMIC_LIGHTING(old_area))
if (IS_DYNAMIC_LIGHTING(new_area))
lighting_build_overlay()
else
lighting_clear_overlay()
/turf/proc/get_corners()
if (has_opaque_atom)
return null // Since this proc gets used in a for loop, null won't be looped though.
return corners
/turf/proc/generate_missing_corners()
lighting_corners_initialised = TRUE
if (!corners)
corners = list(null, null, null, null)
for (var/i = 1 to 4)
if (corners[i]) // Already have a corner on this direction.
continue
corners[i] = new/datum/lighting_corner(src, LIGHTING_CORNER_DIAGONAL[i])
/turf/ChangeTurf(path)
if(!path || (!use_preloader && path == type)) //Sucks this is here but it would cause problems otherwise.
return ..()
if (!lighting_corners_initialised)
if (!corners)
corners = list(null, null, null, null)
for (var/i = 1 to 4)
if (corners[i]) // Already have a corner on this direction.
continue
corners[i] = new/datum/lighting_corner(src, LIGHTING_CORNER_DIAGONAL[i])
var/old_opacity = opacity
var/old_dynamic_lighting = dynamic_lighting
var/old_affecting_lights = affecting_lights
var/old_lighting_overlay = lighting_overlay
var/old_corners = corners
for(var/obj/effect/decal/cleanable/decal in src.contents)
qdel(decal)
. = ..() //At this point the turf has changed
lighting_corners_initialised = TRUE
recalc_atom_opacity()
lighting_overlay = old_lighting_overlay
affecting_lights = old_affecting_lights
corners = old_corners
if((old_opacity != opacity) || (dynamic_lighting != old_dynamic_lighting))
reconsider_lights()
if(dynamic_lighting != old_dynamic_lighting)
if(IS_DYNAMIC_LIGHTING(src))
lighting_build_overlay()
else
lighting_clear_overlay()
+12
View File
@@ -0,0 +1,12 @@
#ifdef LIGHTING_INSTANT_UPDATES
#undef LIGHTING_INTERVAL
#undef LIGHTING_INSTANT_UPDATES
#endif
#undef LIGHTING_FALLOFF
#undef LIGHTING_LAMBERTIAN
#undef LIGHTING_HEIGHT
#undef LIGHTING_ICON
#undef LIGHTING_BASE_MATRIX
+3 -8
View File
@@ -511,6 +511,9 @@
var/atom/mark = null
var/marked_image = null
/obj/item/weapon/twohanded/required/mining_hammer/New()
set_light(luminosity)
/obj/item/projectile/destabilizer
name = "destabilizing force"
icon_state = "pulse1"
@@ -581,11 +584,3 @@
charged = 1
icon_state = "mining_hammer1"
playsound(src.loc, 'sound/weapons/kenetic_reload.ogg', 60, 1)
/obj/item/weapon/twohanded/required/mining_hammer/pickup(mob/user)
..()
user.AddLuminosity(luminosity)
/obj/item/weapon/twohanded/required/mining_hammer/dropped(mob/user)
..()
user.AddLuminosity(-luminosity)
@@ -5,6 +5,7 @@
shuttleId = "laborcamp"
possible_destinations = "laborcamp_home;laborcamp_away"
req_access = list(access_brig)
light_color = LIGHT_COLOR_CYAN
/obj/machinery/computer/shuttle/labor/one_way
@@ -24,4 +25,4 @@
if(S && S.name == "laborcamp_away")
usr << "<span class='warning'>Shuttle is already at the outpost!</span>"
return 0
..()
..()
+2 -1
View File
@@ -57,6 +57,7 @@
shuttleId = "mining"
possible_destinations = "mining_home;mining_away"
no_destination_swap = 1
light_color = LIGHT_COLOR_CYAN
/*********************Pickaxe & Drills**************************/
@@ -638,4 +639,4 @@
if(cell)
user << text("<span class='notice'>[src] has [cellcharge]/[cellmaxcharge] charge remaining.</span>")
else
user << text("<span class='notice'>[src] has no power supply installed.</span>")
user << text("<span class='notice'>[src] has no power supply installed.</span>")
+2 -2
View File
@@ -109,7 +109,7 @@
on_fire = 1
src.visible_message("<span class='warning'>[src] catches fire!</span>", \
"<span class='userdanger'>You're set on fire!</span>")
src.AddLuminosity(3)
src.set_light(light_range + 3)
throw_alert("fire", /obj/screen/alert/fire)
update_fire()
return TRUE
@@ -119,7 +119,7 @@
if(on_fire)
on_fire = 0
fire_stacks = 0
src.AddLuminosity(-3)
src.set_light(light_range - 3)
clear_alert("fire")
update_fire()
+1 -1
View File
@@ -738,7 +738,7 @@ var/list/ai_list = list()
src << "Camera lights deactivated."
for (var/obj/machinery/camera/C in lit_cameras)
C.SetLuminosity(0)
C.set_light(0)
lit_cameras = list()
return
@@ -1148,7 +1148,7 @@
update_headlamp()
/mob/living/silicon/robot/proc/update_headlamp(var/turn_off = 0, var/cooldown = 100)
SetLuminosity(0)
set_light(0)
if(lamp_intensity && (turn_off || stat || low_power_mode))
src << "<span class='danger'>Your headlamp has been deactivated.</span>"
@@ -1157,7 +1157,7 @@
spawn(cooldown) //10 seconds by default, if the source of the deactivation does not keep stat that long.
lamp_recharging = 0
else
AddLuminosity(lamp_intensity)
set_light(lamp_intensity)
if(lamp_button)
lamp_button.icon_state = "lamp[lamp_intensity]"
@@ -101,14 +101,14 @@
if(stat)
return 0
on = 1
SetLuminosity(initial(luminosity))
set_light(initial(luminosity))
update_icon()
diag_hud_set_botstat()
return 1
/mob/living/simple_animal/bot/proc/turn_off()
on = 0
SetLuminosity(0)
set_light(0)
bot_reset() //Resets an AI's call, should it exist.
update_icon()
@@ -863,7 +863,7 @@ Pass a positive integer as an argument to override a bot's default speed.
else
user << "<span class='warning'>[card] is inactive.</span>"
else
user << "<span class='warning'>The personality slot is locked.</span>"
user << "<span class='warning'>The personality slot is locked.</span>"
else
user << "<span class='warning'>[src] is not compatible with [card]</span>"
@@ -255,7 +255,7 @@
emote_hear = list("barks!", "woofs!", "yaps.","pants.")
emote_see = list("shakes its head.", "chases its tail.","shivers.")
desc = initial(desc)
SetLuminosity(0)
set_light(0)
if(inventory_head && inventory_head.dog_fashion)
var/datum/dog_fashion/DF = new inventory_head.dog_fashion(src)
@@ -119,7 +119,7 @@
/mob/living/simple_animal/drone/cogscarab/New()
. = ..()
SetLuminosity(2,1)
set_light(2,1)
qdel(access_card) //we don't have free access
access_card = null
verbs -= /mob/living/simple_animal/drone/verb/check_laws
@@ -16,9 +16,9 @@
set category = "Drone"
set name = "Toggle drone light"
if(light_on)
AddLuminosity(-8)
set_light(0)
else
AddLuminosity(8)
set_light(8)
light_on = !light_on
@@ -51,4 +51,3 @@
staticChoice = selectedStatic
updateSeeStaticMobs()
@@ -248,10 +248,10 @@ var/global/list/parasites = list() //all currently existing/living guardians
/mob/living/simple_animal/hostile/guardian/proc/ToggleLight()
if(!luminosity)
src << "<span class='notice'>You activate your light.</span>"
SetLuminosity(3)
set_light(3)
else
src << "<span class='notice'>You deactivate your light.</span>"
SetLuminosity(0)
set_light(0)
/mob/living/simple_animal/hostile/guardian/verb/ShowType()
set name = "Check Guardian Type"
@@ -110,8 +110,8 @@
return null
// Check for darkness
var/turf/T = get_turf(loc)
if(T && destination && T.lighting_object)
if(T.lighting_lumcount<1 && destination.lighting_lumcount<1) // No one can see us in the darkness, right?
if(T && destination)
if((T.get_lumcount())<1 && (destination.get_lumcount())<1) // No one can see us in the darkness, right?
return null
if(T == destination)
destination = null
+2 -12
View File
@@ -102,12 +102,7 @@ var/next_mob_id = 0
msg = blind_message
else
continue
else if(T.lighting_object)
if(T.lighting_object.invisibility <= M.see_invisible && !T.lighting_object.luminosity)
if(blind_message) //if the light object is dark and not invisible to us, we see blind_message/nothing
msg = blind_message
else
continue
M.show_message(msg,1,blind_message,2)
/mob/proc/get_top_level_mob()
@@ -140,12 +135,7 @@ proc/get_top_level_mob(var/mob/S)
msg = blind_message
else
continue
else if(T.lighting_object)
if(T.lighting_object.invisibility <= M.see_invisible && !T.lighting_object.luminosity) //the light object is dark and not invisible to us
if(blind_message)
msg = blind_message
else
continue
M.show_message(msg,1,blind_message,2)
// Show a message to all mobs in earshot of this one
+4 -4
View File
@@ -222,7 +222,7 @@
update_icon()
if(on)
if(!light || light.luminosity != brightness)
if(!light || light.light_range != brightness)
switchcount++
if(rigged)
if(status == LIGHT_OK && trigger)
@@ -232,13 +232,13 @@
status = LIGHT_BURNED
icon_state = "[base_state]-burned"
on = 0
SetLuminosity(0)
set_light(0)
else
use_power = 2
SetLuminosity(brightness)
set_light(brightness)
else
use_power = 1
SetLuminosity(0)
set_light(0)
active_power_usage = (brightness * 10)
if(on != on_gs)
+1
View File
@@ -7,6 +7,7 @@
idle_power_usage = 20
active_power_usage = 100
circuit = /obj/item/weapon/circuitboard/computer/powermonitor
light_color = LIGHT_COLOR_ORANGE
var/obj/structure/cable/attached
+9
View File
@@ -86,9 +86,18 @@
// can override if needed
if(powered(power_channel))
stat &= ~NOPOWER
if(!use_auto_lights)
return
set_light(light_range_on, light_power_on)
else
stat |= NOPOWER
if(!use_auto_lights)
return
set_light(0)
return
// connect the machine to a powernet if a node cable is present on the turf
+7 -3
View File
@@ -299,9 +299,13 @@
var/lastgen = 0
var/track = 0 // 0= off 1=timed 2=auto (tracker)
var/trackrate = 600 // 300-900 seconds
var/nexttime = 0 // time for a panel to rotate of 1° in manual tracking
var/nexttime = 0 // time for a panel to rotate of 1 in manual tracking
var/obj/machinery/power/tracker/connected_tracker = null
var/list/connected_panels = list()
use_auto_lights = 1
light_power_on = 1
light_range_on = 3
light_color = LIGHT_COLOR_ORANGE
/obj/machinery/power/solar_control/New()
@@ -503,9 +507,9 @@
connected_tracker.unset_control()
if(track==1 && trackrate) //manual tracking and set a rotation speed
if(nexttime <= world.time) //every time we need to increase/decrease the angle by 1°...
if(nexttime <= world.time) //every time we need to increase/decrease the angle by 1...
targetdir = (targetdir + trackrate/abs(trackrate) + 360) % 360 //... do it
nexttime += 36000/abs(trackrate) //reset the counter for the next 1°
nexttime += 36000/abs(trackrate) //reset the counter for the next 1
//rotates the panel to the passed angle
/obj/machinery/power/solar_control/proc/set_panels(currentdir)
+4 -21
View File
@@ -283,7 +283,7 @@ obj/item/weapon/gun/proc/newshot()
return
user << "<span class='notice'>You click [S] into place on [src].</span>"
if(S.on)
SetLuminosity(0)
set_light(0)
F = S
I.loc = src
update_icon()
@@ -332,21 +332,12 @@ obj/item/weapon/gun/proc/newshot()
/obj/item/weapon/gun/proc/update_gunlight(mob/user = null)
if(F)
if(F.on)
if(loc == user)
user.AddLuminosity(F.brightness_on)
else if(isturf(loc))
SetLuminosity(F.brightness_on)
set_light(F.brightness_on)
else
if(loc == user)
user.AddLuminosity(-F.brightness_on)
else if(isturf(loc))
SetLuminosity(0)
set_light(0)
update_icon()
else
if(loc == user)
user.AddLuminosity(-5)
else if(isturf(loc))
SetLuminosity(0)
set_light(0)
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
@@ -354,19 +345,11 @@ obj/item/weapon/gun/proc/newshot()
/obj/item/weapon/gun/pickup(mob/user)
..()
if(F)
if(F.on)
user.AddLuminosity(F.brightness_on)
SetLuminosity(0)
if(azoom)
azoom.Grant(user)
/obj/item/weapon/gun/dropped(mob/user)
..()
if(F)
if(F.on)
user.AddLuminosity(-F.brightness_on)
SetLuminosity(F.brightness_on)
zoom(user,FALSE)
if(azoom)
azoom.Remove(user)
@@ -72,7 +72,7 @@
/obj/effect/nettingportal/New()
..()
SetLuminosity(3)
set_light(3)
var/obj/item/device/radio/beacon/teletarget = null
for(var/obj/machinery/computer/teleporter/com in machines)
if(com.target)
@@ -14,6 +14,10 @@
var/screen = "home"
var/analyzeVars[0]
var/useramount = 30 // Last used amount
use_auto_lights = 1
light_power_on = 1
light_range_on = 2
light_color = LIGHT_COLOR_BLUE
/obj/machinery/chem_master/New()
create_reagents(100)
@@ -28,6 +28,7 @@
icon_screen = "slime_comp"
icon_keyboard = "rd_key"
light_color = LIGHT_COLOR_PINK
/obj/machinery/computer/camera_advanced/xenobio/CreateEye()
eyeobj = new /mob/camera/aiEye/remote/xenobio()
+2 -2
View File
@@ -474,14 +474,14 @@
T1.shuttleRotate(rotation)
//lighting stuff
T1.redraw_lighting()
T1.reconsider_lights()
SSair.remove_from_active(T1)
T1.CalculateAdjacentTurfs()
SSair.add_to_active(T1,1)
T0.ChangeTurf(turf_type)
T0.redraw_lighting()
T0.reconsider_lights()
SSair.remove_from_active(T0)
T0.CalculateAdjacentTurfs()
SSair.add_to_active(T0,1)
+2
View File
@@ -7,6 +7,8 @@
var/logged_in = "Cargo Department"
var/vmode = 1
clockwork = TRUE //it'd look weird
light_color = LIGHT_COLOR_GREEN
light_range_on = 2
/obj/machinery/computer/stockexchange/New()
..()