mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-07-13 08:56:49 +01:00
75dfa30013
Unused vars take up memory and worsen proc overhead. By far the worst offenders to this are vars on /atom and /mob since they more or less globally stack lots and lots and lots and lots of proc overhead. So I'm cleaning up unused vars on these to save resources. I also noted several vars that are excellent candidates for making components or elements. When I'm not drowning in school work anymore, their time is numbered. Mfw every space carp forever has a CCIA record, no wonder mobs are laggy.
849 lines
26 KiB
Plaintext
849 lines
26 KiB
Plaintext
/// The lighting system.
|
|
/// Consists of light fixtures (/obj/structure/machinery/light) and light tube/bulb items (/obj/item/light).
|
|
|
|
/// 20W per unit luminosity
|
|
#define LIGHTING_POWER_FACTOR 40
|
|
/// Standard tube light fixture
|
|
/obj/structure/machinery/light
|
|
name = "light fixture"
|
|
icon = 'icons/obj/machinery/light.dmi'
|
|
/// Base description and icon_state
|
|
var/base_state = "tube"
|
|
icon_state = "tube_preview"
|
|
desc = "A lighting fixture."
|
|
anchored = TRUE
|
|
layer = ABOVE_HUMAN_LAYER
|
|
use_power = POWER_USE_ACTIVE
|
|
idle_power_usage = 2
|
|
active_power_usage = 20
|
|
/// Lights are calculated via area so they don't need to be in the machine list.
|
|
power_channel = AREA_USAGE_LIGHT
|
|
always_area_sensitive = TRUE
|
|
obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED
|
|
/// Luminosity when on, also used in power calculation.
|
|
var/brightness_range = 7
|
|
var/brightness_power = 0.75
|
|
var/night_brightness_range = 6
|
|
var/night_brightness_power = 0.3
|
|
var/supports_nightmode = TRUE
|
|
var/nightmode = FALSE
|
|
var/brightness_color = LIGHT_COLOR_OFFWHITE
|
|
/// Expected types defined in lightning.dm
|
|
var/status = LIGHT_OK
|
|
var/flickering = 0
|
|
/// Type of light item.
|
|
var/light_type = /obj/item/light/tube
|
|
var/obj/item/light/inserted_light = /obj/item/light/tube
|
|
var/fitting = "tube"
|
|
/// Whether the bulb can break during its init or not.
|
|
var/must_start_working = FALSE
|
|
/// If TRUE light sources have a 50% chance to be broken instead after Initialize.
|
|
var/maybe_broken = FALSE
|
|
/// Count of number of times the light was switched on/off. This is used to calculate the probability of the light burning out.
|
|
var/switchcount = 0
|
|
/// TRUE if rigged to explode.
|
|
var/rigged = 0
|
|
var/obj/item/cell/cell
|
|
/// If TRUE this fixture generates a very weak cell at roundstart.
|
|
var/start_with_cell = TRUE
|
|
/// If TRUE the light is in emergency mode.
|
|
var/emergency_mode = FALSE
|
|
/// If TRUE this light cannot enter emergency mode.
|
|
var/no_emergency = FALSE
|
|
|
|
var/next_spark = 0
|
|
|
|
var/bulb_is_noisy = TRUE
|
|
|
|
var/fitting_has_empty_icon = FALSE
|
|
var/fitting_is_on_floor = FALSE
|
|
|
|
var/previous_stat
|
|
var/randomize_color = TRUE
|
|
var/default_color
|
|
/// This is also defined at the area level! If you want to mess with
|
|
/// light fixture colours without touching specific subtypes, you
|
|
/// should probably be looking at the area's variables, not at this.
|
|
var/static/list/randomized_colors = LIGHT_WARM_COLORS
|
|
var/static/list/emergency_lights = list(
|
|
LIGHT_MODE_RED = LIGHT_COLOR_EMERGENCY,
|
|
LIGHT_MODE_DELTA = LIGHT_COLOR_ORANGE
|
|
)
|
|
init_flags = 0
|
|
|
|
/obj/structure/machinery/light/mechanics_hints(mob/user, distance, is_adjacent)
|
|
. += ..()
|
|
. += "Use Grab intent on a working light to remove it from its fixture."
|
|
|
|
/obj/structure/machinery/light/feedback_hints(mob/user, distance, is_adjacent)
|
|
. += ..()
|
|
switch(status)
|
|
if(LIGHT_OK)
|
|
. += "It is turned [!(stat & POWEROFF) ? "on" : "off"]."
|
|
if(LIGHT_EMPTY)
|
|
. += "\The [fitting] has been removed."
|
|
if(LIGHT_BURNED)
|
|
. += "\The [fitting] is burnt out."
|
|
if(LIGHT_BROKEN)
|
|
. += "\The [fitting] has been smashed."
|
|
if(cell)
|
|
. += "The charge meter reads [round((cell.charge / cell.maxcharge) * 100, 0.1)]%."
|
|
|
|
/obj/structure/machinery/light/built/Initialize()
|
|
status = LIGHT_EMPTY
|
|
stat |= MAINT
|
|
. = ..()
|
|
|
|
/obj/structure/machinery/light/floor/built/Initialize()
|
|
status = LIGHT_EMPTY
|
|
stat |= MAINT
|
|
. = ..()
|
|
|
|
/obj/structure/machinery/light/small/built/Initialize()
|
|
status = LIGHT_EMPTY
|
|
stat |= MAINT
|
|
. = ..()
|
|
|
|
/obj/structure/machinery/light/small/floor/built/Initialize()
|
|
status = LIGHT_EMPTY
|
|
stat |= MAINT
|
|
. = ..()
|
|
|
|
/obj/structure/machinery/light/spot/built/Initialize()
|
|
status = LIGHT_EMPTY
|
|
stat |= MAINT
|
|
. = ..()
|
|
|
|
/obj/structure/machinery/light/Initialize(mapload)
|
|
. = ..()
|
|
LAZYADD(SSmachinery.all_lights, src)
|
|
|
|
if (!has_power())
|
|
stat |= NOPOWER
|
|
if (start_with_cell && !no_emergency)
|
|
cell = new /obj/item/cell/device/emergency_light(src)
|
|
|
|
if (!must_start_working && mapload && loc && isNotAdminLevel(z))
|
|
switch(fitting)
|
|
if("tube")
|
|
if(prob(2) || (maybe_broken && prob(50)))
|
|
broken(1)
|
|
if("bulb")
|
|
if(prob(5) || (maybe_broken && prob(50)))
|
|
broken(1)
|
|
if("large tube")
|
|
if(prob(1) || (maybe_broken && prob(50)))
|
|
broken(1)
|
|
|
|
// If we're randomizing the color of this fixture, we check if the area has a special palette.
|
|
// This is intended to save mapping time by automating light variations in different areas.
|
|
if(randomize_color)
|
|
var/area/A = get_area(src)
|
|
randomized_colors = A.area_lighting
|
|
|
|
brightness_color = pick(randomized_colors)
|
|
|
|
default_color = brightness_color // We need a different var so the new color doesn't get wiped away. Initial() wouldn't work since brightness_color is overridden.
|
|
update(0)
|
|
set_pixel_offsets()
|
|
|
|
/obj/structure/machinery/light/Destroy()
|
|
LAZYREMOVE(SSmachinery.all_lights, src)
|
|
QDEL_NULL(cell)
|
|
return ..()
|
|
|
|
/obj/structure/machinery/light/set_pixel_offsets()
|
|
pixel_x = dir & (NORTH|SOUTH) ? 0 : (dir == EAST ? 12 : -12)
|
|
pixel_y = dir & (NORTH|SOUTH) ? (dir == NORTH ? DEFAULT_WALL_OFFSET : -2) : 0
|
|
|
|
/obj/structure/machinery/light/small/set_pixel_offsets()
|
|
pixel_x = dir & (NORTH|SOUTH) ? 0 : (dir == EAST ? 12 : -12)
|
|
pixel_y = dir & (NORTH|SOUTH) ? (dir == NORTH ? DEFAULT_WALL_OFFSET : -22) : 0
|
|
|
|
/obj/structure/machinery/light/floor/set_pixel_offsets()
|
|
pixel_x = pixel_x
|
|
pixel_y = pixel_y
|
|
|
|
/obj/structure/machinery/light/small/floor/set_pixel_offsets()
|
|
pixel_x = pixel_x
|
|
pixel_y = pixel_y
|
|
|
|
/obj/structure/machinery/light/update_icon()
|
|
ClearOverlays()
|
|
if ((status == LIGHT_EMPTY) || !fitting_has_empty_icon)
|
|
icon_state = "[base_state]_empty"
|
|
else
|
|
icon_state = "[base_state]"
|
|
var/on = emergency_mode || !stat
|
|
switch(status) // set icon_states
|
|
if(LIGHT_OK)
|
|
var/target_color
|
|
if (emergency_mode)
|
|
target_color = LIGHT_COLOR_RED
|
|
else
|
|
target_color = brightness_color
|
|
if (supports_nightmode && nightmode && !stat)
|
|
target_color = BlendRGB("#D2D2D2", target_color, 0.25)
|
|
|
|
if (on)
|
|
var/image/I = LIGHT_FIXTURE_CACHE(icon, "[base_state]_on", target_color)
|
|
var/image/E = emissive_appearance(icon, "[base_state]_on")
|
|
AddOverlays(I)
|
|
AddOverlays(E)
|
|
else
|
|
AddOverlays(LIGHT_FIXTURE_CACHE(icon, "[base_state]_off", target_color))
|
|
|
|
if(LIGHT_BURNED)
|
|
AddOverlays(LIGHT_FIXTURE_CACHE(icon, "[base_state]_burned", brightness_color))
|
|
stat |= BROKEN
|
|
stat &= ~MAINT
|
|
|
|
if(LIGHT_BROKEN)
|
|
AddOverlays(LIGHT_FIXTURE_CACHE(icon, "[base_state]_broken", brightness_color))
|
|
stat |= BROKEN
|
|
stat &= ~MAINT
|
|
|
|
// update the icon_state and luminosity of the light depending on its state
|
|
/obj/structure/machinery/light/proc/update(var/trigger = 1)
|
|
emergency_mode = FALSE
|
|
|
|
switch (status)
|
|
if(LIGHT_OK)
|
|
stat &= ~(MAINT|BROKEN)
|
|
|
|
if(LIGHT_EMPTY)
|
|
stat |= MAINT
|
|
stat &= ~BROKEN
|
|
|
|
if (LIGHT_BURNED)
|
|
stat |= BROKEN
|
|
stat &= ~MAINT
|
|
|
|
if (LIGHT_BROKEN)
|
|
stat |= BROKEN
|
|
stat &= ~MAINT
|
|
|
|
if (previous_stat != stat && !stat && bulb_is_noisy)
|
|
playsound(loc, 'sound/effects/lighton.ogg', 65, 1)
|
|
|
|
previous_stat = stat
|
|
if(!stat)
|
|
var/area/local_area = get_area(src)
|
|
if(local_area && istype(local_area, /area/turbolift))
|
|
// Elevators raise the switchcount constantly by moving, resulting in constantly broken lights, this prevents this behavior.
|
|
switchcount = 0
|
|
else
|
|
switchcount++
|
|
if(rigged)
|
|
if(status == LIGHT_OK && trigger)
|
|
log_admin("LOG: Rigged light explosion, last touched by [fingerprintslast]")
|
|
message_admins("LOG: Rigged light explosion, last touched by [fingerprintslast]")
|
|
explode()
|
|
|
|
else if(prob(min(60,(switchcount**2) * 0.05))) // LEMURIAN SEA, REDUCE 0.05 -> 0.01 AFTER ARC
|
|
if(status == LIGHT_OK && trigger)
|
|
status = LIGHT_BURNED
|
|
stat |= BROKEN
|
|
set_light(0)
|
|
else
|
|
update_use_power(POWER_USE_ACTIVE)
|
|
change_power_consumption(light_range * LIGHTING_POWER_FACTOR, POWER_USE_ACTIVE)
|
|
if (supports_nightmode && nightmode)
|
|
set_light(night_brightness_range, night_brightness_power, brightness_color)
|
|
else
|
|
set_light(brightness_range, brightness_power, brightness_color)
|
|
else if (has_emergency_power(LIGHT_EMERGENCY_POWER_USE) && !(stat & POWEROFF))
|
|
update_use_power(POWER_USE_IDLE)
|
|
emergency_mode = TRUE
|
|
var/new_power = round(max(0.5, 0.75 * (cell.charge / cell.maxcharge)), 0.1)
|
|
set_light(brightness_range * 0.25, new_power, LIGHT_COLOR_EMERGENCY)
|
|
else
|
|
update_use_power(POWER_USE_IDLE)
|
|
set_light(0)
|
|
|
|
update_icon()
|
|
|
|
change_power_consumption((light_range * light_power) * 10, POWER_USE_ACTIVE)
|
|
|
|
if((status == LIGHT_BROKEN) || emergency_mode || (cell && !cell.fully_charged() && has_power()))
|
|
START_PROCESSING_MACHINE(src, MACHINERY_PROCESS_SELF)
|
|
else if(processing_flags)
|
|
STOP_PROCESSING_MACHINE(src, MACHINERY_PROCESS_SELF)
|
|
|
|
/obj/structure/machinery/light/proc/broken_sparks()
|
|
if(world.time > next_spark && !(stat & POWEROFF) && has_power())
|
|
spark(src, 3, GLOB.alldirs)
|
|
next_spark = world.time + 1 MINUTE + (rand(-15, 15) SECONDS)
|
|
|
|
// ehh
|
|
/obj/structure/machinery/light/process(seconds_per_tick)
|
|
if (cell && has_power())
|
|
cell.give(0.2 * seconds_per_tick)
|
|
if(cell.fully_charged())
|
|
return PROCESS_KILL
|
|
if (emergency_mode && !use_emergency_power(LIGHT_EMERGENCY_POWER_USE))
|
|
update(FALSE)
|
|
return PROCESS_KILL
|
|
if(status == LIGHT_BROKEN)
|
|
broken_sparks()
|
|
|
|
/obj/structure/machinery/light/proc/has_emergency_power(pwr = LIGHT_EMERGENCY_POWER_USE)
|
|
if (no_emergency | !cell)
|
|
return FALSE
|
|
if (pwr ? cell.charge >= pwr : cell.charge)
|
|
return status == LIGHT_OK
|
|
|
|
/obj/structure/machinery/light/proc/use_emergency_power(pwr = 0.2)
|
|
if (!has_emergency_power(pwr))
|
|
return FALSE
|
|
if (cell.charge > 600) // Default mini-cell max is 500.
|
|
visible_message(SPAN_WARNING("\The [src] short-circuits!"), SPAN_WARNING("You hear glass breaking."))
|
|
broken()
|
|
return FALSE
|
|
cell.use(pwr)
|
|
// Hopefully this doesn't cause too many lighting updates.
|
|
var/new_power = round(max(0.5, 0.75 * (cell.charge / cell.maxcharge)), 0.1)
|
|
if (!IsAboutEqual(light_power, new_power))
|
|
set_light(l_power = new_power)
|
|
return TRUE
|
|
|
|
/obj/structure/machinery/light/proc/check_update()
|
|
if (emergency_mode)
|
|
return light_range != brightness_range * 0.25 || light_power != max(0.5, 0.75 * (cell.charge / cell.maxcharge)) || light_color != LIGHT_COLOR_EMERGENCY
|
|
else if (supports_nightmode && nightmode)
|
|
return light_range != night_brightness_range || light_power != night_brightness_power || light_color != brightness_color
|
|
else
|
|
return light_range != brightness_range || light_power != brightness_power || light_color != brightness_color
|
|
|
|
/obj/structure/machinery/light/attack_generic(mob/user, damage, attack_message, environment_smash, armor_penetration, attack_flags, damage_type)
|
|
if(!damage)
|
|
return
|
|
if(status == LIGHT_EMPTY)
|
|
to_chat(user, SPAN_WARNING("\The [src] is useless to you."))
|
|
return
|
|
if(!(status == LIGHT_OK || status == LIGHT_BURNED))
|
|
return
|
|
if(status == LIGHT_BROKEN)
|
|
user.visible_message(SPAN_WARNING("\The [user] completely shatters \the [src]!"), SPAN_WARNING("You completely shatter \the [src]!"))
|
|
shatter()
|
|
else
|
|
user.visible_message(SPAN_WARNING("\The [user] smashes \the [src]!"), SPAN_WARNING("You smash \the [src]!"))
|
|
broken()
|
|
user.do_attack_animation(src)
|
|
return TRUE
|
|
|
|
// attack with item - insert light (if right type), otherwise try to break the light
|
|
|
|
/obj/structure/machinery/light/attackby(obj/item/attacking_item, mob/user)
|
|
//Light replacer code
|
|
if(istype(attacking_item, /obj/item/lightreplacer))
|
|
var/obj/item/lightreplacer/LR = attacking_item
|
|
if(isliving(user))
|
|
var/mob/living/U = user
|
|
LR.ReplaceLight(src, U)
|
|
return
|
|
|
|
// attempt to insert light
|
|
if(istype(attacking_item, /obj/item/light))
|
|
if(status != LIGHT_EMPTY)
|
|
to_chat(user, SPAN_WARNING("There's already a [fitting] inserted."))
|
|
return
|
|
else
|
|
src.add_fingerprint(user)
|
|
var/obj/item/light/L = attacking_item
|
|
if(istype(L, light_type))
|
|
status = L.status
|
|
to_chat(user, SPAN_NOTICE("You insert \the [L]."))
|
|
switchcount = L.switchcount
|
|
rigged = L.rigged
|
|
brightness_range = L.brightness_range
|
|
brightness_power = L.brightness_power
|
|
brightness_color = L.brightness_color
|
|
inserted_light = L.type
|
|
if (!has_power())
|
|
stat |= NOPOWER
|
|
else
|
|
stat &= ~NOPOWER
|
|
|
|
update()
|
|
|
|
user.drop_from_inventory(L,get_turf(src))
|
|
qdel(L)
|
|
|
|
if(!stat && rigged)
|
|
log_admin("LOG: Rigged light explosion, last touched by [fingerprintslast]")
|
|
message_admins("LOG: Rigged light explosion, last touched by [fingerprintslast]")
|
|
|
|
explode()
|
|
else
|
|
to_chat(user, SPAN_WARNING("This type of light requires a [fitting]."))
|
|
return
|
|
|
|
// attempt to break the light
|
|
//If xenos decide they want to smash a light bulb with a toolbox, who am I to stop them? /N
|
|
|
|
else if(status != LIGHT_BROKEN && status != LIGHT_EMPTY)
|
|
smash_check(attacking_item, user, "smashes", "smashes", TRUE)
|
|
else if(status == LIGHT_BROKEN)
|
|
smash_check(attacking_item, user, "completely shatters", "shatters completely", FALSE)
|
|
|
|
// attempt to stick weapon into light socket
|
|
else if(status == LIGHT_EMPTY)
|
|
if(attacking_item.tool_behaviour == TOOL_SCREWDRIVER) //If it's a screwdriver open it.
|
|
attacking_item.play_tool_sound(get_turf(src), 75)
|
|
user.visible_message(SPAN_NOTICE("\The [user] opens \the [src]'s casing."), SPAN_NOTICE("You open \the [src]'s casing."), SPAN_NOTICE("You hear a noise."))
|
|
var/obj/structure/machinery/light_construct/newlight = null
|
|
switch(fitting)
|
|
if("tube")
|
|
newlight = new /obj/structure/machinery/light_construct(get_turf(src))
|
|
newlight.icon_state = "tube-construct-stage2"
|
|
|
|
if("bulb")
|
|
newlight = new /obj/structure/machinery/light_construct/small(get_turf(src))
|
|
newlight.icon_state = "bulb-construct-stage2"
|
|
|
|
if("large tube")
|
|
newlight = new /obj/structure/machinery/light_construct/spot(get_turf(src))
|
|
newlight.icon_state = "slight-construct-stage2"
|
|
newlight.dir = src.dir
|
|
newlight.stage = 2
|
|
newlight.fingerprints = src.fingerprints
|
|
newlight.fingerprintshidden = src.fingerprintshidden
|
|
newlight.fingerprintslast = src.fingerprintslast
|
|
if(cell)
|
|
newlight.cell = cell
|
|
cell.forceMove(newlight)
|
|
cell = null
|
|
qdel(src)
|
|
return
|
|
|
|
to_chat(user, SPAN_WARNING("You stick \the [attacking_item] into the light socket!"))
|
|
if(has_power() && (attacking_item.obj_flags & OBJ_FLAG_CONDUCTABLE))
|
|
spark(src, 3)
|
|
if(prob(75))
|
|
electrocute_mob(user, get_area(src), src, rand(0.7,1.0))
|
|
|
|
/obj/structure/machinery/light/proc/smash_check(var/obj/O, var/mob/living/user, var/others_text, var/self_text, var/only_break)
|
|
if(prob(1 + O.force * 5))
|
|
user.visible_message(SPAN_WARNING("\The [user] [others_text] \the [src]!"), SPAN_WARNING("You hit \the [src], and it [self_text]!"), SPAN_WARNING("You hear a tinkle of breaking glass!"))
|
|
if(!stat && (O.obj_flags & OBJ_FLAG_CONDUCTABLE))
|
|
if(prob(12))
|
|
electrocute_mob(user, get_area(src), src, 0.3)
|
|
if(only_break)
|
|
broken()
|
|
else
|
|
shatter()
|
|
else
|
|
user.visible_message(SPAN_WARNING("\The [user] hits \the [src], but it doesn't break."), SPAN_WARNING("You hit \the [src], but it doesn't break."), SPAN_WARNING("You hear something hitting against glass."))
|
|
|
|
/obj/structure/machinery/light/bullet_act(obj/projectile/hitting_projectile, def_zone, piercing_hit)
|
|
. = ..()
|
|
if(. != BULLET_ACT_HIT)
|
|
return .
|
|
|
|
bullet_ping(hitting_projectile)
|
|
shatter()
|
|
|
|
// returns whether this light has power
|
|
// true if area has power
|
|
/obj/structure/machinery/light/proc/has_power()
|
|
var/area/A = get_area(src)
|
|
return A && (!A.requires_power || A.power_light)
|
|
|
|
/obj/structure/machinery/light/proc/flicker(amount = rand(10,20))
|
|
set waitfor = FALSE
|
|
if (flickering || stat || status != LIGHT_OK)
|
|
return
|
|
|
|
flickering = TRUE
|
|
var/offset = 1
|
|
var/thecallback = CALLBACK(src, PROC_REF(handle_flicker))
|
|
for (var/i = 0; i < amount; i++)
|
|
addtimer(thecallback, offset)
|
|
offset += rand(5, 15)
|
|
|
|
addtimer(CALLBACK(src, PROC_REF(end_flicker)), offset)
|
|
|
|
/obj/structure/machinery/light/proc/handle_flicker()
|
|
if (status == LIGHT_OK)
|
|
stat ^= POWEROFF
|
|
update(FALSE)
|
|
if (prob(50))
|
|
playsound(src.loc, 'sound/effects/light_flicker.ogg', 75, 1)
|
|
|
|
/obj/structure/machinery/light/proc/end_flicker()
|
|
stat &= ~POWEROFF
|
|
update(FALSE)
|
|
flickering = FALSE
|
|
|
|
// ai attack - make lights flicker, because why not
|
|
|
|
/obj/structure/machinery/light/attack_ai(mob/user)
|
|
if(!ai_can_interact(user))
|
|
return
|
|
src.flicker(1)
|
|
return
|
|
|
|
// attack with hand - remove tube/bulb
|
|
// if hands aren't protected and the light is on, burn the player
|
|
/obj/structure/machinery/light/attack_hand(mob/user)
|
|
add_fingerprint(user)
|
|
|
|
if(status == LIGHT_EMPTY)
|
|
to_chat(user, SPAN_WARNING("There is no [fitting] in \the [src]."))
|
|
return
|
|
|
|
if(istype(user,/mob/living/carbon/human))
|
|
var/mob/living/carbon/human/H = user
|
|
if(H.a_intent == I_HURT && H.species.can_shred(H))
|
|
if(status != LIGHT_BROKEN || status != LIGHT_EMPTY)
|
|
H.visible_message(SPAN_WARNING("\The [user] smashes \the [src]!"), SPAN_WARNING("You smash \the [src]!"), SPAN_WARNING("You hear the tinkle of breaking glass."))
|
|
broken()
|
|
return
|
|
else if(status == LIGHT_BROKEN)
|
|
H.visible_message(SPAN_WARNING("\The [user] completely shatters \the [src]!"), SPAN_WARNING("You shatter \the [src] completely!"), SPAN_WARNING("You hear the tinkle of breaking glass."))
|
|
shatter()
|
|
return
|
|
|
|
if(user.a_intent != I_GRAB && status == LIGHT_OK)
|
|
return
|
|
|
|
// create a light tube/bulb item and put it in the user's hand
|
|
if(inserted_light)
|
|
var/obj/item/light/L = new inserted_light()
|
|
L.status = status
|
|
L.rigged = rigged
|
|
L.brightness_range = brightness_range
|
|
L.brightness_power = brightness_power
|
|
L.brightness_color = brightness_color
|
|
|
|
// light item inherits the switchcount, then zero it
|
|
L.switchcount = switchcount
|
|
switchcount = 0
|
|
|
|
L.update()
|
|
L.add_fingerprint(user)
|
|
|
|
user.put_in_active_hand(L) //puts it in our active hand
|
|
|
|
to_chat(user, SPAN_NOTICE("You remove the light [fitting]."))
|
|
|
|
inserted_light = null
|
|
|
|
status = LIGHT_EMPTY
|
|
stat |= MAINT
|
|
update()
|
|
|
|
/obj/structure/machinery/light/do_simple_ranged_interaction(var/mob/user)
|
|
if(status == LIGHT_EMPTY)
|
|
to_chat(user, "There is no [fitting] in this light.")
|
|
return
|
|
|
|
to_chat(user, "You telekinetically remove the light [fitting].")
|
|
// create a light tube/bulb item and put it in the user's hand
|
|
var/obj/item/light/L = new inserted_light()
|
|
L.status = status
|
|
L.rigged = rigged
|
|
L.brightness_range = brightness_range
|
|
L.brightness_power = brightness_power
|
|
L.brightness_color = brightness_color
|
|
|
|
// light item inherits the switchcount, then zero it
|
|
L.switchcount = switchcount
|
|
switchcount = 0
|
|
|
|
L.update()
|
|
L.add_fingerprint(user)
|
|
L.forceMove(loc)
|
|
|
|
inserted_light = null
|
|
|
|
status = LIGHT_EMPTY
|
|
update()
|
|
|
|
/obj/structure/machinery/light/attack_ghost(mob/user)
|
|
if(round_is_spooky())
|
|
flicker(rand(2,5))
|
|
else
|
|
return ..()
|
|
|
|
/// Break the light and make sparks if was on
|
|
/obj/structure/machinery/light/proc/broken(skip_sound_and_sparks = 0)
|
|
if(status == LIGHT_EMPTY)
|
|
return
|
|
|
|
if(!skip_sound_and_sparks)
|
|
if(status == LIGHT_OK || status == LIGHT_BURNED)
|
|
playsound(src.loc, 'sound/effects/glass_hit.ogg', 75, 1)
|
|
if(!stat)
|
|
spark(src, 3)
|
|
status = LIGHT_BROKEN
|
|
stat |= BROKEN
|
|
update()
|
|
|
|
/obj/structure/machinery/light/proc/shatter()
|
|
if(status == LIGHT_EMPTY)
|
|
return
|
|
status = LIGHT_EMPTY
|
|
stat |= BROKEN
|
|
update()
|
|
playsound(get_turf(src), 'sound/effects/glass_hit.ogg', 75, TRUE)
|
|
new /obj/item/material/shard(get_turf(src))
|
|
|
|
/obj/structure/machinery/light/proc/fix()
|
|
if(status == LIGHT_OK)
|
|
return
|
|
status = LIGHT_OK
|
|
update()
|
|
|
|
// explosion effect
|
|
// destroy the whole light fixture or just shatter it
|
|
|
|
/obj/structure/machinery/light/ex_act(severity)
|
|
switch(severity)
|
|
if(1.0)
|
|
qdel(src)
|
|
return
|
|
if(2.0)
|
|
if (prob(75))
|
|
shatter()
|
|
if(3.0)
|
|
if (prob(50))
|
|
broken()
|
|
return
|
|
|
|
// called when area power state changes
|
|
/obj/structure/machinery/light/power_change()
|
|
SHOULD_CALL_PARENT(FALSE)
|
|
addtimer(CALLBACK(src, PROC_REF(handle_power_change)), rand(1, 2 SECONDS), TIMER_UNIQUE | TIMER_NO_HASH_WAIT)
|
|
|
|
/obj/structure/machinery/light/proc/handle_power_change()
|
|
if (has_power())
|
|
stat &= ~NOPOWER
|
|
else
|
|
stat |= NOPOWER
|
|
|
|
update()
|
|
|
|
// called when on fire
|
|
|
|
/obj/structure/machinery/light/fire_act(exposed_temperature, exposed_volume)
|
|
. = ..()
|
|
|
|
if(prob(max(0, exposed_temperature - 673))) //0% at <400C, 100% at >500C
|
|
broken()
|
|
|
|
// explode the light
|
|
|
|
/obj/structure/machinery/light/proc/explode()
|
|
set waitfor = FALSE
|
|
var/turf/T = get_turf(src.loc)
|
|
broken() // break it first to give a warning
|
|
sleep(2)
|
|
explosion(T, 0, 0, 2, 2)
|
|
sleep(1)
|
|
qdel(src)
|
|
|
|
/obj/structure/machinery/light/set_emergency_state(var/new_security_level)
|
|
var/area/A = get_area(src)
|
|
if(new_security_level in emergency_lights)
|
|
if(A.emergency_lights)
|
|
brightness_color = emergency_lights[new_security_level]
|
|
update(0)
|
|
else
|
|
if(brightness_color != default_color)
|
|
brightness_color = default_color
|
|
update(0)
|
|
|
|
/obj/structure/machinery/light/clean()
|
|
. = ..()
|
|
brightness_color = initial(brightness_color)
|
|
update()
|
|
|
|
/*
|
|
##############################
|
|
LIGHT SUBTYPES
|
|
##############################
|
|
*/
|
|
|
|
//---- Tube lights
|
|
|
|
/obj/structure/machinery/light/built
|
|
start_with_cell = FALSE
|
|
|
|
/obj/structure/machinery/light/broken
|
|
status = LIGHT_BROKEN
|
|
icon_state = "tube_broken_preview"
|
|
|
|
/obj/structure/machinery/light/maybe_broken
|
|
maybe_broken = TRUE
|
|
icon_state = "tube_maybe_broken_preview"
|
|
|
|
/obj/structure/machinery/light/maybe_broken/decayed
|
|
brightness_color = LIGHT_COLOR_DECAYED
|
|
randomize_color = FALSE
|
|
|
|
/obj/structure/machinery/light/skrell
|
|
base_state = "skrell"
|
|
icon_state = "skrell_empty"
|
|
supports_nightmode = FALSE
|
|
fitting = "skrell"
|
|
bulb_is_noisy = FALSE
|
|
light_type = /obj/item/light/tube
|
|
inserted_light = /obj/item/light/tube
|
|
brightness_power = 0.45
|
|
brightness_color = LIGHT_COLOR_PURPLE
|
|
|
|
/obj/structure/machinery/light/voidtamer
|
|
name = "voidtamer light fixture"
|
|
base_state = "voidtamer"
|
|
icon_state = "voidtamer_empty"
|
|
desc = "A lighting fixture, decorated in gold and carp hide."
|
|
|
|
/obj/structure/machinery/light/spot
|
|
name = "spotlight fixture"
|
|
icon_state = "tube_empty"
|
|
desc = "An extremely powerful lighting fixture."
|
|
fitting = "large tube"
|
|
light_type = /obj/item/light/tube/large
|
|
inserted_light = /obj/item/light/tube/large
|
|
brightness_range = 12
|
|
brightness_power = 3.5
|
|
supports_nightmode = FALSE
|
|
|
|
/obj/structure/machinery/light/colored/blue
|
|
brightness_color = LIGHT_COLOR_BLUE
|
|
randomize_color = FALSE
|
|
|
|
/obj/structure/machinery/light/colored/red
|
|
brightness_color = LIGHT_COLOR_RED
|
|
randomize_color = FALSE
|
|
icon_state = "tube_red_preview"
|
|
|
|
/obj/structure/machinery/light/colored/violet
|
|
brightness_color = LIGHT_COLOR_VIOLET
|
|
randomize_color = FALSE
|
|
icon_state = "tube_violet_preview"
|
|
|
|
/obj/structure/machinery/light/colored/decayed
|
|
brightness_color = LIGHT_COLOR_DECAYED
|
|
randomize_color = FALSE
|
|
icon_state = "tube_decayed_preview"
|
|
|
|
/obj/structure/machinery/light/colored/dying
|
|
brightness_color = LIGHT_COLOR_DYING
|
|
randomize_color = FALSE
|
|
icon_state = "tube_decayed_preview"
|
|
|
|
/obj/structure/machinery/light/colored/decayed/dimmed
|
|
brightness_power = 0.2
|
|
|
|
/obj/structure/machinery/light/colored/beige
|
|
brightness_color = LIGHT_COLOR_BEIGE
|
|
randomize_color = FALSE
|
|
icon_state = "tube_decayed_preview"
|
|
|
|
//---- Floor lights
|
|
|
|
/obj/structure/machinery/light/floor
|
|
name = "floor lighting fixture"
|
|
icon_state = "floortube_example"
|
|
base_state = "floortube"
|
|
desc = "A lighting fixture. This one is set into the floor."
|
|
layer = ABOVE_TILE_LAYER
|
|
fitting_has_empty_icon = TRUE
|
|
fitting_is_on_floor = TRUE
|
|
|
|
/obj/structure/machinery/light/floor/broken
|
|
status = LIGHT_BROKEN
|
|
icon_state = "floortube"
|
|
|
|
/obj/structure/machinery/light/floor/maybe_broken
|
|
maybe_broken = TRUE
|
|
icon_state = "floortube_maybe_broken_preview"
|
|
|
|
/obj/structure/machinery/light/floor/maybe_broken/decayed
|
|
brightness_color = LIGHT_COLOR_DECAYED
|
|
randomize_color = FALSE
|
|
|
|
/obj/structure/machinery/light/floor/maybe_broken
|
|
maybe_broken = TRUE
|
|
icon_state = "floortube_maybe_broken"
|
|
|
|
/obj/structure/machinery/light/floor/decayed
|
|
brightness_color = "#fabd6d"
|
|
randomize_color = FALSE
|
|
brightness_power = 0.3
|
|
|
|
/obj/structure/machinery/light/floor/decayed/brighter
|
|
brightness_power = 0.45
|
|
|
|
/obj/structure/machinery/light/floor/decayed/brighter/broken
|
|
status = LIGHT_BROKEN
|
|
icon_state = "floortube"
|
|
|
|
//---- Small bulb lights
|
|
|
|
/obj/structure/machinery/light/small
|
|
icon_state = "bulb_preview"
|
|
base_state = "bulb"
|
|
fitting = "bulb"
|
|
brightness_range = 5
|
|
brightness_power = 0.45
|
|
brightness_color = LIGHT_COLOR_TUNGSTEN
|
|
desc = "A small lighting fixture."
|
|
light_type = /obj/item/light/bulb
|
|
inserted_light = /obj/item/light/bulb
|
|
supports_nightmode = FALSE
|
|
bulb_is_noisy = FALSE
|
|
|
|
/obj/structure/machinery/light/small/broken
|
|
status = LIGHT_BROKEN
|
|
icon_state = "bulb_broken_preview"
|
|
|
|
/obj/structure/machinery/light/small/maybe_broken
|
|
maybe_broken = TRUE
|
|
icon_state = "bulb_maybe_broken_preview"
|
|
|
|
/obj/structure/machinery/light/small/maybe_broken/decayed
|
|
brightness_color = LIGHT_COLOR_DECAYED
|
|
randomize_color = FALSE
|
|
|
|
/obj/structure/machinery/light/small/floor
|
|
name = "small floor lighting fixture"
|
|
icon_state = "floor_example"
|
|
base_state = "floor"
|
|
desc = "A small lighting fixture. This one is set into the floor."
|
|
fitting_is_on_floor = TRUE
|
|
layer = ABOVE_TILE_LAYER
|
|
|
|
/obj/structure/machinery/light/small/floor/emergency
|
|
icon_state = "floor_emergency"
|
|
brightness_range = 6
|
|
brightness_power = 0.45
|
|
brightness_color = LIGHT_COLOR_EMERGENCY_SOFT
|
|
randomize_color = FALSE
|
|
|
|
/obj/structure/machinery/light/small/floor/beige
|
|
brightness_color = LIGHT_COLOR_BEIGE
|
|
randomize_color = FALSE
|
|
|
|
/obj/structure/machinery/light/small/emergency
|
|
icon_state = "bulb_emergency_preview"
|
|
brightness_range = 6
|
|
brightness_power = 0.45
|
|
brightness_color = LIGHT_COLOR_EMERGENCY_SOFT
|
|
randomize_color = FALSE
|
|
|
|
/obj/structure/machinery/light/small/red
|
|
brightness_range = 2.5
|
|
brightness_power = 0.45
|
|
brightness_color = LIGHT_COLOR_RED
|
|
randomize_color = FALSE
|
|
|
|
/obj/structure/machinery/light/small/decayed
|
|
brightness_range = 6
|
|
brightness_power = 0.45
|
|
brightness_color = LIGHT_COLOR_DECAYED
|
|
randomize_color = FALSE
|