mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-30 03:52:52 +00:00
Reworked how slipping on tiles work. If there is too much lube/water on one tile, it will spread to all adjacent tiles. Fixed a potential bug where spilling copious amounts of water on a tile will turn it to ice. Containers are much more saner now. They all share a standard system, unless specified. You can drink from any open holdable container using help intent. You can splash the contents of the container on anything via harm intent. Sinks are more saner, you can refill or empty them easier with various refill amounts. Removed silly exclusive cyborg limb checking for hyposprays. Added a new chemsprayer, the "Xenoblaster" which is a significantly weaker chem sprayer. Two can be found in xenobiology. Large reagent containers (beer kegs, water tanks, fuel tanks) now share a system together. Both can leak their reagents via harm intent with a wrench, and bother can accept any sort of reagent, with exception to the fuel tank. Large reagent container leaking happens over time as opposed to just leaking every time it moves. New chemical, Monoammonium phosphate. Monoammonium phosphate is a fertilizer and also a potent fire extinguishing and preventing chemical. It can be made with 1 part ammonia, 1 part sulfuric acid, 1 part sodium, 1 part phosphorus. All extinguishers now have monoammonium phosphate in them instead of water. Extinguishers can hold any reagent, however they must be filled using an extinguisher refiller cartridge. These can be ordered or found in atmospherics. Nerfed the extinguisher range so it only sprays in a 3x3 radius. Mini-extinguishers spray in a 1x1 radius. Adds Monoammonium phosphate containers across the station. Most watertanks are replaced with Monoammonium phosphate containers.
572 lines
17 KiB
Plaintext
572 lines
17 KiB
Plaintext
/obj/structure/window
|
|
name = "window"
|
|
desc = "A window."
|
|
icon = 'icons/obj/structures.dmi'
|
|
density = 1
|
|
w_class = 3
|
|
|
|
layer = 3.2//Just above doors
|
|
anchored = 1.0
|
|
flags = ON_BORDER
|
|
var/maxhealth = 14.0
|
|
var/maximal_heat = T0C + 100 // Maximal heat before this window begins taking damage from fire
|
|
var/damage_per_fire_tick = 2.0 // Amount of damage per fire tick. Regular windows are not fireproof so they might as well break quickly.
|
|
var/health
|
|
var/ini_dir = null
|
|
var/state = 2
|
|
var/reinf = 0
|
|
var/basestate
|
|
var/shardtype = /obj/item/weapon/material/shard
|
|
var/glasstype = null // Set this in subtypes. Null is assumed strange or otherwise impossible to dismantle, such as for shuttle glass.
|
|
var/silicate = 0 // number of units of silicate
|
|
|
|
atmos_canpass = CANPASS_PROC
|
|
|
|
/obj/structure/window/examine(mob/user)
|
|
. = ..(user)
|
|
|
|
if(health == maxhealth)
|
|
user << "<span class='notice'>It looks fully intact.</span>"
|
|
else
|
|
var/perc = health / maxhealth
|
|
if(perc > 0.75)
|
|
user << "<span class='notice'>It has a few cracks.</span>"
|
|
else if(perc > 0.5)
|
|
user << "<span class='warning'>It looks slightly damaged.</span>"
|
|
else if(perc > 0.25)
|
|
user << "<span class='warning'>It looks moderately damaged.</span>"
|
|
else
|
|
user << "<span class='danger'>It looks heavily damaged.</span>"
|
|
if(silicate)
|
|
if (silicate < 30)
|
|
user << "<span class='notice'>It has a thin layer of silicate.</span>"
|
|
else if (silicate < 70)
|
|
user << "<span class='notice'>It is covered in silicate.</span>"
|
|
else
|
|
user << "<span class='notice'>There is a thick layer of silicate covering it.</span>"
|
|
|
|
/obj/structure/window/proc/take_damage(var/damage = 0, var/sound_effect = 1)
|
|
var/initialhealth = health
|
|
|
|
if(silicate)
|
|
damage = damage * (1 - silicate / 200)
|
|
|
|
health = max(0, health - damage)
|
|
|
|
if(health <= 0)
|
|
shatter()
|
|
else
|
|
if(sound_effect)
|
|
playsound(loc, 'sound/effects/Glasshit.ogg', 100, 1)
|
|
if(health < maxhealth / 4 && initialhealth >= maxhealth / 4)
|
|
visible_message("[src] looks like it's about to shatter!" )
|
|
else if(health < maxhealth / 2 && initialhealth >= maxhealth / 2)
|
|
visible_message("[src] looks seriously damaged!" )
|
|
else if(health < maxhealth * 3/4 && initialhealth >= maxhealth * 3/4)
|
|
visible_message("Cracks begin to appear in [src]!" )
|
|
return
|
|
|
|
/obj/structure/window/proc/apply_silicate(var/amount)
|
|
if(health < maxhealth) // Mend the damage
|
|
health = min(health + amount * 3, maxhealth)
|
|
if(health == maxhealth)
|
|
visible_message("[src] looks fully repaired." )
|
|
else // Reinforce
|
|
silicate = min(silicate + amount, 100)
|
|
updateSilicate()
|
|
|
|
/obj/structure/window/proc/updateSilicate()
|
|
cut_overlays()
|
|
|
|
var/image/img = image(icon, icon_state)
|
|
img.color = "#ffffff"
|
|
img.alpha = silicate * 255 / 100
|
|
add_overlay(img)
|
|
|
|
/obj/structure/window/proc/shatter(var/display_message = 1)
|
|
playsound(src, "shatter", 70, 1)
|
|
if(display_message)
|
|
visible_message("[src] shatters!")
|
|
if(dir == SOUTHWEST)
|
|
var/index = null
|
|
index = 0
|
|
while(index < 2)
|
|
new shardtype(loc) //todo pooling?
|
|
if(reinf)
|
|
new /obj/item/stack/rods(loc)
|
|
index++
|
|
else
|
|
new shardtype(loc) //todo pooling?
|
|
if(reinf)
|
|
new /obj/item/stack/rods(loc)
|
|
qdel(src)
|
|
return
|
|
|
|
/obj/structure/window/bullet_act(var/obj/item/projectile/Proj)
|
|
|
|
var/proj_damage = Proj.get_structure_damage()
|
|
if(!proj_damage) return
|
|
|
|
..()
|
|
take_damage(proj_damage)
|
|
return
|
|
|
|
|
|
/obj/structure/window/ex_act(severity)
|
|
switch(severity)
|
|
if(1.0)
|
|
qdel(src)
|
|
return
|
|
if(2.0)
|
|
shatter(0)
|
|
return
|
|
if(3.0)
|
|
if(prob(50))
|
|
shatter(0)
|
|
return
|
|
else
|
|
take_damage(rand(10,30))
|
|
|
|
//TODO: Make full windows a separate type of window.
|
|
//Once a full window, it will always be a full window, so there's no point
|
|
//having the same type for both.
|
|
/obj/structure/window/proc/is_full_window()
|
|
return (dir == SOUTHWEST || dir == SOUTHEAST || dir == NORTHWEST || dir == NORTHEAST)
|
|
|
|
/obj/structure/window/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
|
if(istype(mover) && mover.checkpass(PASSGLASS))
|
|
return 1
|
|
if(is_full_window())
|
|
return 0 //full tile window, you can't move into it!
|
|
if(get_dir(loc, target) & dir)
|
|
return !density
|
|
else
|
|
return 1
|
|
|
|
|
|
/obj/structure/window/CheckExit(atom/movable/O as mob|obj, target as turf)
|
|
if(istype(O) && O.checkpass(PASSGLASS))
|
|
return 1
|
|
if(get_dir(O.loc, target) == dir)
|
|
return 0
|
|
return 1
|
|
|
|
|
|
/obj/structure/window/hitby(AM as mob|obj)
|
|
..()
|
|
visible_message("<span class='danger'>[src] was hit by [AM].</span>")
|
|
var/tforce = 0
|
|
if(ismob(AM))
|
|
tforce = 40
|
|
else if(isobj(AM))
|
|
var/obj/item/I = AM
|
|
tforce = I.throwforce
|
|
if(reinf) tforce *= 0.25
|
|
if(health - tforce <= 7 && !reinf)
|
|
anchored = 0
|
|
update_nearby_icons()
|
|
step(src, get_dir(AM, src))
|
|
take_damage(tforce)
|
|
|
|
/obj/structure/window/attack_tk(mob/user as mob)
|
|
user.visible_message("<span class='notice'>Something knocks on [src].</span>")
|
|
playsound(loc, 'sound/effects/Glasshit.ogg', 60, 1)
|
|
|
|
/obj/structure/window/attack_hand(mob/user as mob)
|
|
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
|
if(HULK in user.mutations)
|
|
user.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!"))
|
|
user.visible_message("<span class='danger'>[user] smashes through [src]!</span>")
|
|
user.do_attack_animation(src)
|
|
shatter()
|
|
|
|
else if (usr.a_intent == I_HURT)
|
|
|
|
if (istype(usr,/mob/living/carbon/human))
|
|
var/mob/living/carbon/human/H = usr
|
|
if(H.species.can_shred(H))
|
|
attack_generic(H,25)
|
|
return
|
|
|
|
playsound(src.loc, 'sound/effects/glassknock.ogg', 90, 1)
|
|
user.do_attack_animation(src)
|
|
usr.visible_message("<span class='danger'>\The [usr] bangs against \the [src]!</span>",
|
|
"<span class='danger'>You bang against \the [src]!</span>",
|
|
"You hear a banging sound.")
|
|
else
|
|
playsound(src.loc, 'sound/effects/glassknock.ogg', 60, 1)
|
|
usr.visible_message("[usr.name] knocks on the [src.name].",
|
|
"You knock on the [src.name].",
|
|
"You hear a knocking sound.")
|
|
return
|
|
|
|
/obj/structure/window/attack_generic(var/mob/user, var/damage)
|
|
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
|
if(damage >= 10)
|
|
visible_message("<span class='danger'>[user] smashes into [src]!</span>")
|
|
take_damage(damage)
|
|
else
|
|
visible_message("<span class='notice'>\The [user] bonks \the [src] harmlessly.</span>")
|
|
playsound(src.loc, 'sound/effects/Glasshit.ogg', 10, 1, -2)
|
|
user.do_attack_animation(src)
|
|
return 1
|
|
|
|
/obj/structure/window/attackby(obj/item/W as obj, mob/user as mob)
|
|
if(!istype(W)) return//I really wish I did not need this
|
|
if (istype(W, /obj/item/weapon/grab) && get_dist(src,user)<2)
|
|
var/obj/item/weapon/grab/G = W
|
|
if(istype(G.affecting,/mob/living))
|
|
grab_smash_attack(G, BRUTE)
|
|
return
|
|
|
|
if(W.flags & NOBLUDGEON) return
|
|
|
|
if(isscrewdriver(W))
|
|
if(reinf && state >= 1)
|
|
state = 3 - state
|
|
update_nearby_icons()
|
|
playsound(loc, 'sound/items/Screwdriver.ogg', 75, 1)
|
|
user << (state == 1 ? "<span class='notice'>You have unfastened the window from the frame.</span>" : "<span class='notice'>You have fastened the window to the frame.</span>")
|
|
else if(reinf && state == 0)
|
|
anchored = !anchored
|
|
update_nearby_icons()
|
|
playsound(loc, 'sound/items/Screwdriver.ogg', 75, 1)
|
|
user << (anchored ? "<span class='notice'>You have fastened the frame to the floor.</span>" : "<span class='notice'>You have unfastened the frame from the floor.</span>")
|
|
else if(!reinf)
|
|
anchored = !anchored
|
|
update_nearby_icons()
|
|
playsound(loc, 'sound/items/Screwdriver.ogg', 75, 1)
|
|
user << (anchored ? "<span class='notice'>You have fastened the window to the floor.</span>" : "<span class='notice'>You have unfastened the window.</span>")
|
|
else if(iscrowbar(W) && reinf && state <= 1)
|
|
state = 1 - state
|
|
playsound(loc, 'sound/items/Crowbar.ogg', 75, 1)
|
|
user << (state ? "<span class='notice'>You have pried the window into the frame.</span>" : "<span class='notice'>You have pried the window out of the frame.</span>")
|
|
else if(iswrench(W) && !anchored && (!state || !reinf))
|
|
if(!glasstype)
|
|
user << "<span class='notice'>You're not sure how to dismantle \the [src] properly.</span>"
|
|
else
|
|
visible_message("<span class='notice'>[user] dismantles \the [src].</span>")
|
|
if(dir == SOUTHWEST)
|
|
var/obj/item/stack/material/mats = new glasstype(loc)
|
|
mats.amount = is_fulltile() ? 4 : 2
|
|
else
|
|
new glasstype(loc)
|
|
qdel(src)
|
|
else
|
|
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
|
if(W.damtype == BRUTE || W.damtype == BURN)
|
|
user.do_attack_animation(src)
|
|
hit(W.force)
|
|
if(health <= 7)
|
|
anchored = 0
|
|
update_nearby_icons()
|
|
step(src, get_dir(user, src))
|
|
else
|
|
playsound(loc, 'sound/effects/Glasshit.ogg', 75, 1)
|
|
..()
|
|
return
|
|
|
|
/obj/structure/window/proc/grab_smash_attack(obj/item/weapon/grab/G, var/damtype = BRUTE)
|
|
var/mob/living/M = G.affecting
|
|
var/mob/living/user = G.assailant
|
|
|
|
var/state = G.state
|
|
qdel(G) //gotta delete it here because if window breaks, it won't get deleted
|
|
|
|
var/def_zone = ran_zone("head", 20)
|
|
var/blocked = M.run_armor_check(def_zone, "melee")
|
|
switch (state)
|
|
if(1)
|
|
M.visible_message("<span class='warning'>[user] slams [M] against \the [src]!</span>")
|
|
M.apply_damage(7, damtype, def_zone, blocked, src)
|
|
hit(10)
|
|
if(2)
|
|
M.visible_message("<span class='danger'>[user] bashes [M] against \the [src]!</span>")
|
|
if (prob(50))
|
|
M.Weaken(1)
|
|
M.apply_damage(10, damtype, def_zone, blocked, src)
|
|
hit(25)
|
|
if(3)
|
|
M.visible_message("<span class='danger'><big>[user] crushes [M] against \the [src]!</big></span>")
|
|
M.Weaken(5)
|
|
M.apply_damage(20, damtype, def_zone, blocked, src)
|
|
hit(50)
|
|
|
|
/obj/structure/window/proc/hit(var/damage, var/sound_effect = 1)
|
|
if(reinf) damage *= 0.5
|
|
take_damage(damage)
|
|
return
|
|
|
|
|
|
/obj/structure/window/verb/rotate()
|
|
set name = "Rotate Window Counter-Clockwise"
|
|
set category = "Object"
|
|
set src in oview(1)
|
|
|
|
if(usr.incapacitated())
|
|
return 0
|
|
|
|
if(anchored)
|
|
usr << "It is fastened to the floor therefore you can't rotate it!"
|
|
return 0
|
|
|
|
update_nearby_tiles(need_rebuild=1) //Compel updates before
|
|
set_dir(turn(dir, 90))
|
|
updateSilicate()
|
|
update_nearby_tiles(need_rebuild=1)
|
|
return
|
|
|
|
|
|
/obj/structure/window/verb/revrotate()
|
|
set name = "Rotate Window Clockwise"
|
|
set category = "Object"
|
|
set src in oview(1)
|
|
|
|
if(usr.incapacitated())
|
|
return 0
|
|
|
|
if(anchored)
|
|
usr << "It is fastened to the floor therefore you can't rotate it!"
|
|
return 0
|
|
|
|
update_nearby_tiles(need_rebuild=1) //Compel updates before
|
|
set_dir(turn(dir, 270))
|
|
updateSilicate()
|
|
update_nearby_tiles(need_rebuild=1)
|
|
return
|
|
|
|
/obj/structure/window/Initialize(mapload, start_dir = null, constructed=0)
|
|
. = ..()
|
|
|
|
//player-constructed windows
|
|
if (constructed)
|
|
anchored = 0
|
|
|
|
if (start_dir)
|
|
set_dir(start_dir)
|
|
|
|
health = maxhealth
|
|
|
|
ini_dir = dir
|
|
|
|
update_nearby_tiles(need_rebuild=1)
|
|
update_nearby_icons()
|
|
|
|
|
|
/obj/structure/window/Destroy()
|
|
density = 0
|
|
update_nearby_tiles()
|
|
var/turf/location = loc
|
|
loc = null
|
|
for(var/obj/structure/window/W in orange(location, 1))
|
|
W.update_icon()
|
|
loc = location
|
|
return ..()
|
|
|
|
|
|
/obj/structure/window/Move()
|
|
var/ini_dir = dir
|
|
update_nearby_tiles(need_rebuild=1)
|
|
..()
|
|
set_dir(ini_dir)
|
|
update_nearby_tiles(need_rebuild=1)
|
|
|
|
//checks if this window is full-tile one
|
|
/obj/structure/window/proc/is_fulltile()
|
|
if(dir & (dir - 1))
|
|
return 1
|
|
return 0
|
|
|
|
//This proc is used to update the icons of nearby windows. It should not be confused with update_nearby_tiles(), which is an atmos proc!
|
|
/obj/structure/window/proc/update_nearby_icons()
|
|
update_icon()
|
|
for(var/obj/structure/window/W in orange(src, 1))
|
|
W.update_icon()
|
|
|
|
//merges adjacent full-tile windows into one (blatant ripoff from game/smoothwall.dm)
|
|
/obj/structure/window/update_icon()
|
|
//A little cludge here, since I don't know how it will work with slim windows. Most likely VERY wrong.
|
|
//this way it will only update full-tile ones
|
|
cut_overlays()
|
|
if(!is_fulltile())
|
|
icon_state = "[basestate]"
|
|
return
|
|
var/list/dirs = list()
|
|
if(anchored)
|
|
for(var/obj/structure/window/W in orange(src,1))
|
|
if(W.anchored && W.density && W.type == src.type && W.is_fulltile()) //Only counts anchored, not-destroyed fill-tile windows.
|
|
dirs += get_dir(src, W)
|
|
|
|
var/list/connections = dirs_to_corner_states(dirs)
|
|
|
|
icon_state = ""
|
|
for(var/i = 1 to 4)
|
|
var/image/I = image(icon, "[basestate][connections[i]]", dir = 1<<(i-1))
|
|
add_overlay(I)
|
|
|
|
/obj/structure/window/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
|
if(exposed_temperature > maximal_heat)
|
|
hit(damage_per_fire_tick, 0)
|
|
..()
|
|
|
|
|
|
|
|
/obj/structure/window/basic
|
|
desc = "It looks thin and flimsy. A few knocks with... anything, really should shatter it."
|
|
icon_state = "window"
|
|
basestate = "window"
|
|
glasstype = /obj/item/stack/material/glass
|
|
maximal_heat = T0C + 100
|
|
damage_per_fire_tick = 2.0
|
|
maxhealth = 12.0
|
|
|
|
/obj/structure/window/phoronbasic
|
|
name = "phoron window"
|
|
desc = "A borosilicate alloy window. It seems to be quite strong."
|
|
basestate = "phoronwindow"
|
|
icon_state = "phoronwindow"
|
|
shardtype = /obj/item/weapon/material/shard/phoron
|
|
glasstype = /obj/item/stack/material/glass/phoronglass
|
|
maximal_heat = T0C + 2000
|
|
damage_per_fire_tick = 1.0
|
|
maxhealth = 40.0
|
|
|
|
/obj/structure/window/phoronreinforced
|
|
name = "reinforced borosilicate window"
|
|
desc = "A borosilicate alloy window, with rods supporting it. It seems to be very strong."
|
|
basestate = "phoronrwindow"
|
|
icon_state = "phoronrwindow"
|
|
shardtype = /obj/item/weapon/material/shard/phoron
|
|
glasstype = /obj/item/stack/material/glass/phoronrglass
|
|
reinf = 1
|
|
maximal_heat = T0C + 4000
|
|
damage_per_fire_tick = 1.0 // This should last for 80 fire ticks if the window is not damaged at all. The idea is that borosilicate windows have something like ablative layer that protects them for a while.
|
|
maxhealth = 80.0
|
|
|
|
|
|
/obj/structure/window/reinforced
|
|
name = "reinforced window"
|
|
desc = "It looks rather strong. Might take a few good hits to shatter it."
|
|
icon_state = "rwindow"
|
|
basestate = "rwindow"
|
|
maxhealth = 40.0
|
|
reinf = 1
|
|
maximal_heat = T0C + 750
|
|
damage_per_fire_tick = 2.0
|
|
glasstype = /obj/item/stack/material/glass/reinforced
|
|
|
|
|
|
/obj/structure/window/Initialize(mapload, constructed = 0)
|
|
. = ..()
|
|
|
|
//player-constructed windows
|
|
if (!mapload && constructed)
|
|
state = 0
|
|
|
|
/obj/structure/window/reinforced/full
|
|
dir = 5
|
|
icon_state = "fwindow"
|
|
|
|
/obj/structure/window/reinforced/tinted
|
|
name = "tinted window"
|
|
desc = "It looks rather strong and opaque. Might take a few good hits to shatter it."
|
|
icon_state = "twindow"
|
|
basestate = "twindow"
|
|
opacity = 1
|
|
|
|
/obj/structure/window/reinforced/tinted/frosted
|
|
name = "frosted window"
|
|
desc = "It looks rather strong and frosted over. Looks like it might take a few less hits then a normal reinforced window."
|
|
icon_state = "fwindow"
|
|
basestate = "fwindow"
|
|
maxhealth = 30
|
|
|
|
/obj/structure/window/shuttle
|
|
name = "shuttle window"
|
|
desc = "It looks rather strong. Might take a few good hits to shatter it."
|
|
icon = 'icons/obj/smooth/shuttle_window.dmi'
|
|
icon_state = "shuttle_window"
|
|
basestate = "window"
|
|
maxhealth = 40
|
|
reinf = 1
|
|
basestate = "w"
|
|
dir = 5
|
|
smooth = SMOOTH_TRUE
|
|
can_be_unanchored = TRUE
|
|
|
|
/obj/structure/window/shuttle/crescent
|
|
desc = "It looks rather strong."
|
|
|
|
/obj/structure/window/shuttle/crescent/take_damage()
|
|
return
|
|
|
|
/obj/structure/window/shuttle/update_nearby_icons()
|
|
queue_smooth_neighbors(src)
|
|
|
|
/obj/structure/window/update_icon()
|
|
queue_smooth(src)
|
|
|
|
/obj/structure/window/reinforced/polarized
|
|
name = "electrochromic window"
|
|
desc = "Adjusts its tint with voltage. Might take a few good hits to shatter it."
|
|
var/id
|
|
|
|
/obj/structure/window/reinforced/polarized/proc/toggle()
|
|
if(opacity)
|
|
animate(src, color="#FFFFFF", time=5)
|
|
set_opacity(0)
|
|
else
|
|
animate(src, color="#222222", time=5)
|
|
set_opacity(1)
|
|
|
|
/obj/structure/window/reinforced/crescent/attack_hand()
|
|
return
|
|
|
|
/obj/structure/window/reinforced/crescent/attackby()
|
|
return
|
|
|
|
/obj/structure/window/reinforced/crescent/ex_act(var/severity = 2.0)
|
|
return
|
|
|
|
/obj/structure/window/reinforced/crescent/hitby()
|
|
return
|
|
|
|
/obj/structure/window/reinforced/crescent/take_damage()
|
|
return
|
|
|
|
/obj/structure/window/reinforced/crescent/shatter()
|
|
return
|
|
|
|
/obj/machinery/button/windowtint
|
|
name = "window tint control"
|
|
icon = 'icons/obj/power.dmi'
|
|
icon_state = "light0"
|
|
desc = "A remote control switch for polarized windows."
|
|
var/range = 16
|
|
|
|
/obj/machinery/button/windowtint/attack_hand(mob/user as mob)
|
|
if(..())
|
|
return 1
|
|
|
|
toggle_tint()
|
|
|
|
/obj/machinery/button/windowtint/proc/toggle_tint()
|
|
use_power(5)
|
|
|
|
active = !active
|
|
update_icon()
|
|
|
|
for(var/obj/structure/window/reinforced/polarized/W in range(src,range))
|
|
if (W.id == src.id || !W.id)
|
|
spawn(0)
|
|
W.toggle()
|
|
return
|
|
|
|
/obj/machinery/button/windowtint/power_change()
|
|
..()
|
|
if(active && !powered(power_channel))
|
|
toggle_tint()
|
|
|
|
/obj/machinery/button/windowtint/update_icon()
|
|
icon_state = "light[active]"
|