Merge pull request #11357 from Markolie/lighting

Lighting system update
This commit is contained in:
Fox McCloud
2019-05-08 00:27:16 -04:00
committed by GitHub
223 changed files with 5497 additions and 5442 deletions
@@ -247,17 +247,6 @@ client/proc/one_click_antag()
if(closet_spawn)
new /obj/structure/closet/syndicate/nuclear(closet_spawn.loc)
for(var/obj/effect/landmark/A in /area/syndicate_station/start)//Because that's the only place it can BE -Sieve
if(A.name == "Syndicate-Gear-Closet")
new /obj/structure/closet/syndicate/personal(A.loc)
qdel(A)
continue
if(A.name == "Syndicate-Bomb")
new /obj/effect/spawner/newbomb/timer/syndicate(A.loc)
qdel(A)
continue
for(var/datum/mind/synd_mind in ticker.mode.syndicates)
if(synd_mind.current)
if(synd_mind.current.client)
@@ -1,44 +1,44 @@
/area/awaymission/UO71
name = "UO71"
icon_state = "away"
report_alerts = 0
tele_proof = 1
report_alerts = FALSE
tele_proof = TRUE
/area/awaymission/UO71/plaza
name = "UO71 Plaza"
icon_state = "awaycontent1"
fire = 1
fire = TRUE
/area/awaymission/UO71/centralhall
name = "UO71 Central"
icon_state = "awaycontent2"
fire = 1
fire = TRUE
/area/awaymission/UO71/eng
name = "UO71 Engineering"
icon_state = "awaycontent3"
fire = 1
fire = TRUE
/area/awaymission/UO71/mining
name = "UO71 Mining"
icon_state = "awaycontent4"
fire = 1
fire = TRUE
/area/awaymission/UO71/science
name = "UO71 Science"
icon_state = "awaycontent5"
fire = 1
fire = TRUE
/area/awaymission/UO71/medical
name = "UO71 Medical"
icon_state = "awaycontent6"
fire = 1
fire = TRUE
/area/awaymission/UO71/gateway
name = "UO71 Gateway"
icon_state = "awaycontent7"
fire = 1
fire = TRUE
/area/awaymission/UO71/outside
name = "UO71 Outside"
@@ -47,36 +47,41 @@
/area/awaymission/UO71/bridge
name = "UO71 Bridge"
icon_state = "awaycontent21"
fire = 1
requires_power = 0
tele_proof = 1
fire = TRUE
requires_power = FALSE
tele_proof = TRUE
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
/area/awaymission/UO71/queen
name = "UO71 Queen Lair"
icon_state = "awaycontent9"
fire = 1
requires_power = 0
tele_proof = 1
fire = TRUE
requires_power = FALSE
tele_proof = TRUE
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
/area/awaymission/UO71/prince
name = "UO71 Prince Containment"
icon_state = "awaycontent10"
fire = 1
requires_power = 0
tele_proof = 1
fire = TRUE
requires_power = FALSE
tele_proof = TRUE
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
/area/awaymission/UO71/mother
name = "UO71 Mother Containment"
icon_state = "awaycontent10"
fire = 1
requires_power = 0
tele_proof = 1
fire = TRUE
requires_power = FALSE
tele_proof = TRUE
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
/area/awaymission/UO71/loot
name = "UO71 Loot Vault"
icon_state = "awaycontent11"
requires_power = 0
tele_proof = 1
requires_power = FALSE
tele_proof = TRUE
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
/obj/item/paper/terrorspiders1
name = "paper - 'Sealed Facility'"
@@ -3,25 +3,24 @@
/area/awaymission/BMPship
name = "\improper BMP Asteroids"
icon_state = "away"
luminosity = 0
report_alerts = 0
report_alerts = FALSE
/area/awaymission/BMPship/Aft
name = "\improper Aft Block"
icon_state = "away1"
requires_power = 1
requires_power = TRUE
/area/awaymission/BMPship/Midship
name = "\improper Midship Block"
icon_state = "away2"
requires_power = 1
requires_power = TRUE
/area/awaymission/BMPship/Fore
name = "\improper Fore Block"
icon_state = "away3"
requires_power = 1
requires_power = TRUE
/area/awaymission/BMPship/Gate
name = "\improper Gateway Block"
icon_state = "away4"
requires_power = 1
requires_power = TRUE
@@ -3,7 +3,7 @@
/area/awaymission/challenge
name = "Challenge"
icon_state = "away"
report_alerts = 0
report_alerts = FALSE
/area/awaymission/challenge/start
name = "Where Am I?"
@@ -12,12 +12,14 @@
/area/awaymission/challenge/main
name = "\improper Danger Room"
icon_state = "away1"
requires_power = 0
requires_power = FALSE
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
/area/awaymission/challenge/end
name = "Administration"
icon_state = "away2"
requires_power = 0
requires_power = FALSE
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
/obj/machinery/power/emitter/energycannon
@@ -1,21 +0,0 @@
//Clown Planet Areas
/area/planet/clown
name = "\improper Clown Planet"
icon_state = "honk"
luminosity = 1
dynamic_lighting = 0
requires_power = 0
report_alerts = 0
/area/awaymission/clownplanet/miningtown
name = "\improper Clown Planet - Bananium-o-Rama"
icon_state = "away1"
luminosity = 1
requires_power = 0
/area/awaymission/clownplanet/mine
name = "\improper Clown Planet - Bananium-o-Rama Mines"
icon_state = "away2"
luminosity = 1
requires_power = 0
@@ -307,6 +307,7 @@
name = "Powered Tile"
icon_state = "teleporter"
requires_power = FALSE
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
/area/ruin/space/ancientstation/space
name = "Exposed To Space"
@@ -3,8 +3,9 @@
/area/awaymission/spacebattle
name = "\improper Space Battle"
icon_state = "away"
requires_power = 0
report_alerts = 0
requires_power = FALSE
report_alerts = FALSE
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
/area/awaymission/spacebattle/cruiser
name = "\improper Nanotrasen Cruiser"
@@ -2,7 +2,8 @@
/area/awaymission/spacehotel
name = "Deep Space Hotel 419"
requires_power = 0
requires_power = FALSE
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
/area/awaymission/spacehotel/kitchen
name = "Hotel Kitchen"
@@ -161,7 +161,7 @@ var/sc_safecode5 = "[rand(0,9)]"
desc = "Your body becomes weak and your feel your mind slipping away as you try to comprehend what you know can't be possible."
move_self = 0 //Contianed narsie does not move!
grav_pull = 0 //Contained narsie does not pull stuff in!
var/uneatable = list(/turf/space, /obj/effect/overlay, /atom/movable/lighting_overlay, /mob/living/simple_animal/hostile/construct)
var/uneatable = list(/turf/space, /obj/effect/overlay, /atom/movable/lighting_object, /mob/living/simple_animal/hostile/construct)
//Override this to prevent no adminlog runtimes and admin warnings about a singularity without containment
/obj/singularity/narsie/sc_Narsie/admin_investigate_setup()
@@ -9,31 +9,30 @@
/area/awaymission/wwmines
name = "\improper Wild West Mines"
icon_state = "away1"
luminosity = 1
requires_power = 0
requires_power = FALSE
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
/area/awaymission/wwgov
name = "\improper Wild West Mansion"
icon_state = "away2"
luminosity = 1
requires_power = 0
requires_power = FALSE
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
/area/awaymission/wwrefine
name = "\improper Wild West Refinery"
icon_state = "away3"
luminosity = 1
requires_power = 0
requires_power = FALSE
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
/area/awaymission/wwvault
name = "\improper Wild West Vault"
icon_state = "away3"
luminosity = 0
/area/awaymission/wwvaultdoors
name = "\improper Wild West Vault Doors" // this is to keep the vault area being entirely lit because of requires_power
icon_state = "away2"
requires_power = 0
luminosity = 0
requires_power = FALSE
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
/*
* Wish Granter
+11 -6
View File
@@ -1,8 +1,8 @@
/area/awaymission/upperlevel
name = "Open Space"
color = "#888"
dynamic_lighting = 0
requires_power = 0
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
requires_power = FALSE
// Used by /turf/unsimulated/floor/upperlevel as a reference for where the other floor is
/obj/effect/levelref
@@ -84,9 +84,14 @@
/obj/effect/portal_sensor/proc/check_light()
var/turf/T = loc
if(istype(T) && T.lighting_overlay && !T.lighting_overlay.needs_update)
var/atom/movable/lighting_overlay/O = T.lighting_overlay
var/hash = O.lum_r + O.lum_g + O.lum_b
if(istype(T) && T.lighting_object && !T.lighting_object.needs_update)
var/atom/movable/lighting_object/O = T.lighting_object
var/hash = 0
for(var/lighting_corner in O)
var/datum/lighting_corner/C = lighting_corner
hash = hash + C.lum_r + C.lum_g + C.lum_b
if(hash != light_hash)
light_hash = hash
trigger()
@@ -365,4 +370,4 @@
screen_loc = "CENTER[ox >= 0 ? "+" : ""][ox],CENTER[oy >= 0 ? "+" : ""][oy]"
/obj/effect/view_portal_dummy/attack_ghost(mob/user)
owner.attack_ghost(user)
owner.attack_ghost(user)
+14 -5
View File
@@ -333,6 +333,8 @@
if(!prefs)
prefs = new /datum/preferences(src)
preferences_datums[ckey] = prefs
else
prefs.parent = src
prefs.last_ip = address //these are gonna be used for banning
prefs.last_id = computer_id //these are gonna be used for banning
if(world.byond_version >= 511 && byond_version >= 511 && prefs.clientfps)
@@ -388,10 +390,8 @@
if(establish_db_connection())
to_chat(src,"<span class='notice'>You have enabled karma gains.")
if(!void)
void = new()
screen += void
generate_clickcatcher()
apply_clickcatcher()
if(custom_event_msg && custom_event_msg != "")
to_chat(src, "<h1 class='alert'>Custom Event</h1>")
@@ -778,6 +778,15 @@
else
winset(src, "rpane.changelog", "background-color=none;text-color=#000000")
/client/proc/generate_clickcatcher()
if(!void)
void = new()
screen += void
/client/proc/apply_clickcatcher()
generate_clickcatcher()
var/list/actualview = getviewsize(view)
void.UpdateGreed(actualview[1],actualview[2])
/client/proc/send_ssd_warning(mob/M)
if(!config.ssd_warning)
@@ -789,4 +798,4 @@
to_chat(src, "Interacting with SSD players is against server rules unless you've ahelped first for permission. If you have, <a href='byond://?src=[UID()];ssdwarning=accepted'>confirm that</A> and proceed.")
return TRUE
#undef SSD_WARNING_TIMER
#undef SSD_WARNING_TIMER
+10 -17
View File
@@ -183,7 +183,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
// 0 = character settings, 1 = game preferences
var/current_tab = TAB_CHAR
// OOC Metadata:
// OOC Metadata:
var/metadata = ""
var/slot_name = ""
@@ -452,6 +452,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
dat += "<b>Donator Publicity:</b> <a href='?_src_=prefs;preference=donor_public'><b>[(toggles & DONATOR_PUBLIC) ? "Public" : "Hidden"]</b></a><br>"
dat += "<b>Fancy NanoUI:</b> <a href='?_src_=prefs;preference=nanoui'>[(nanoui_fancy) ? "Yes" : "No"]</a><br>"
dat += "<b>FPS:</b> <a href='?_src_=prefs;preference=clientfps;task=input'>[clientfps]</a><br>"
dat += "<b>Ambient Occlusion:</b> <a href='?_src_=prefs;preference=ambientocclusion'><b>[toggles & AMBIENT_OCCLUSION ? "Enabled" : "Disabled"]</b></a><br>"
dat += "<b>Ghost Ears:</b> <a href='?_src_=prefs;preference=ghost_ears'><b>[(toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]</b></a><br>"
dat += "<b>Ghost Sight:</b> <a href='?_src_=prefs;preference=ghost_sight'><b>[(toggles & CHAT_GHOSTSIGHT) ? "All Emotes" : "Nearest Creatures"]</b></a><br>"
dat += "<b>Ghost Radio:</b> <a href='?_src_=prefs;preference=ghost_radio'><b>[(toggles & CHAT_GHOSTRADIO) ? "All Chatter" : "Nearest Speakers"]</b></a><br>"
@@ -1919,22 +1920,6 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
if(world.byond_version >= 511 && user.client && user.client.byond_version >= 511)
parent.fps = clientfps
/*
if("skin_style")
var/skin_style_name = input(user, "Select a new skin style") as null|anything in list("default1", "default2", "default3")
if(!skin_style_name) return
*/
/* if("spawnpoint")
var/list/spawnkeys = list()
for(var/S in spawntypes)
spawnkeys += S
var/choice = input(user, "Where would you like to spawn when latejoining?") as null|anything in spawnkeys
if(!choice || !spawntypes[choice])
spawnpoint = "Arrivals Shuttle"
return
spawnpoint = choice */
else
switch(href_list["preference"])
if("publicity")
@@ -2079,6 +2064,14 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
if(href_list["tab"])
current_tab = text2num(href_list["tab"])
if("ambientocclusion")
toggles ^= AMBIENT_OCCLUSION
if(parent && parent.screen && parent.screen.len)
var/obj/screen/plane_master/game_world/PM = locate(/obj/screen/plane_master/game_world) in parent.screen
PM.filters -= FILTER_AMBIENT_OCCLUSION
if(toggles & AMBIENT_OCCLUSION)
PM.filters += FILTER_AMBIENT_OCCLUSION
ShowChoices(user)
return 1
@@ -55,7 +55,7 @@
ooccolor = sanitize_hexcolor(ooccolor, initial(ooccolor))
UI_style = sanitize_inlist(UI_style, list("White", "Midnight"), initial(UI_style))
default_slot = sanitize_integer(default_slot, 1, max_save_slots, initial(default_slot))
toggles = sanitize_integer(toggles, 0, 2097151, initial(toggles))
toggles = sanitize_integer(toggles, 0, TOGGLES_TOTAL, initial(toggles))
sound = sanitize_integer(sound, 0, 65535, initial(sound))
UI_style_color = sanitize_hexcolor(UI_style_color, initial(UI_style_color))
UI_style_alpha = sanitize_integer(UI_style_alpha, 0, 255, initial(UI_style_alpha))
@@ -230,7 +230,6 @@
to_chat(usr, "<span class='notice'>You have disabled karma gains.")
else
to_chat(usr, "<span class='notice'>You have enabled karma gains.")
return
/client/verb/toggle_popup_limiter()
set name = "Toggle Text Popup Limiter"
@@ -242,4 +241,4 @@
to_chat(usr, "<span class='notice'>You have enabled text popup limiting.")
else
to_chat(usr, "<span class='notice'>You have disabled text popup limiting.")
return
+6 -3
View File
@@ -151,9 +151,10 @@
slot_flags = SLOT_EYES
materials = list(MAT_GLASS = 250)
var/vision_flags = 0
var/darkness_view = 0 //Base human is 2
var/see_in_dark = 0 //Base human is 2
var/invis_view = SEE_INVISIBLE_LIVING
var/invis_override = 0
var/lighting_alpha
var/emagged = 0
var/list/color_view = null//overrides client.color while worn
@@ -304,9 +305,11 @@ BLIND // can't see anything
slot_flags = SLOT_HEAD
var/blockTracking // Do we block AI tracking?
var/HUDType = null
var/darkness_view = 0
var/helmet_goggles_invis_view = 0
var/vision_flags = 0
var/see_in_dark = 0
var/lighting_alpha
var/can_toggle = null
//Mask
+25 -23
View File
@@ -37,7 +37,7 @@
item_state = "glasses"
origin_tech = "magnets=1;engineering=2"
vision_flags = SEE_TURFS
invis_view = SEE_INVISIBLE_MINIMUM //don't render darkness while wearing these
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
prescription_upgradable = 1
species_fit = list("Vox")
sprite_sheets = list(
@@ -52,7 +52,8 @@
icon_state = "nvgmeson"
item_state = "glasses"
origin_tech = "magnets=4;engineering=5;plasmatech=4"
darkness_view = 8
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
prescription_upgradable = 0
/obj/item/clothing/glasses/meson/prescription
@@ -103,8 +104,8 @@
desc = "Now you can science in darkness."
icon_state = "nvpurple"
item_state = "glasses"
darkness_view = 8
invis_view = SEE_INVISIBLE_MINIMUM //don't render darkness while wearing these
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE //don't render darkness while wearing these
/obj/item/clothing/glasses/janitor
name = "Janitorial Goggles"
@@ -122,8 +123,8 @@
icon_state = "night"
item_state = "glasses"
origin_tech = "materials=4;magnets=4;plasmatech=4;engineering=4"
darkness_view = 8
invis_view = SEE_INVISIBLE_MINIMUM //don't render darkness while wearing these
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE //don't render darkness while wearing these
species_fit = list("Vox")
sprite_sheets = list(
"Vox" = 'icons/mob/species/vox/eyes.dmi',
@@ -223,7 +224,7 @@
name = "sunglasses"
icon_state = "sun"
item_state = "sunglasses"
darkness_view = 1
see_in_dark = 1
flash_protect = 1
tint = 1
prescription_upgradable = 1
@@ -237,7 +238,7 @@
/obj/item/clothing/glasses/sunglasses/fake
desc = "Cheap, plastic sunglasses. They don't even have UV protection."
name = "cheap sunglasses"
darkness_view = 0
see_in_dark = 0
flash_protect = 0
tint = 0
@@ -285,7 +286,7 @@
name = "sunglasses"
icon_state = "sun"
item_state = "sunglasses"
darkness_view = 1
see_in_dark = 1
flash_protect = 1
tint = 1
species_fit = list("Vox")
@@ -382,6 +383,7 @@
item_state = "glasses"
origin_tech = "magnets=3"
vision_flags = SEE_MOBS
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
flash_protect = -1
species_fit = list("Vox")
sprite_sheets = list(
@@ -389,18 +391,18 @@
"Grey" = 'icons/mob/species/grey/eyes.dmi'
)
emp_act(severity)
if(istype(src.loc, /mob/living/carbon/human))
var/mob/living/carbon/human/M = src.loc
to_chat(M, "<span class='warning'>The Optical Thermal Scanner overloads and blinds you!</span>")
if(M.glasses == src)
M.EyeBlind(3)
M.EyeBlurry(5)
if(!(M.disabilities & NEARSIGHTED))
M.BecomeNearsighted()
spawn(100)
M.CureNearsighted()
..()
/obj/item/clothing/glasses/thermal/emp_act(severity)
if(istype(src.loc, /mob/living/carbon/human))
var/mob/living/carbon/human/M = src.loc
to_chat(M, "<span class='warning'>The Optical Thermal Scanner overloads and blinds you!</span>")
if(M.glasses == src)
M.EyeBlind(3)
M.EyeBlurry(5)
if(!(M.disabilities & NEARSIGHTED))
M.BecomeNearsighted()
spawn(100)
M.CureNearsighted()
..()
/obj/item/clothing/glasses/thermal/syndi //These are now a traitor item, concealed as mesons. -Pete
name = "Optical Meson Scanner"
@@ -503,11 +505,11 @@
icon_state = "godeye"
item_state = "godeye"
vision_flags = SEE_TURFS|SEE_MOBS|SEE_OBJS
darkness_view = 8
see_in_dark = 8
scan_reagents = 1
flags = NODROP
flags_cover = null
invis_view = SEE_INVISIBLE_MINIMUM
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
/obj/item/clothing/glasses/godeye/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, src) && W != src && W.loc == user)
+10 -9
View File
@@ -50,8 +50,8 @@
icon_state = "healthhudnight"
item_state = "glasses"
origin_tech = "magnets=4;biotech=4;plasmatech=4;engineering=5"
darkness_view = 8
invis_view = SEE_INVISIBLE_MINIMUM //don't render darkness while wearing these
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
prescription_upgradable = 0
/obj/item/clothing/glasses/hud/diagnostic
@@ -72,8 +72,8 @@
icon_state = "diagnostichudnight"
item_state = "glasses"
origin_tech = "magnets=4;powerstorage=4;plasmatech=4;engineering=5"
darkness_view = 8
invis_view = SEE_INVISIBLE_MINIMUM //don't render darkness while wearing these
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
prescription_upgradable = 0
/obj/item/clothing/glasses/hud/security
@@ -105,14 +105,15 @@
icon_state = "jensenshades"
item_state = "jensenshades"
vision_flags = SEE_MOBS
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
/obj/item/clothing/glasses/hud/security/night
name = "\improper Night Vision Security HUD"
desc = "An advanced heads-up display which provides id data and vision in complete darkness."
icon_state = "securityhudnight"
origin_tech = "magnets=4;combat=4;plasmatech=4;engineering=5"
darkness_view = 8
invis_view = SEE_INVISIBLE_MINIMUM //don't render darkness while wearing these
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE //don't render darkness while wearing these
prescription_upgradable = 0
/obj/item/clothing/glasses/hud/security/sunglasses/read_only
@@ -123,7 +124,7 @@
desc = "Sunglasses with a HUD."
icon_state = "sunhud"
origin_tech = "magnets=3;combat=3;engineering=3"
darkness_view = 1
see_in_dark = 1
flash_protect = 1
tint = 1
prescription_upgradable = 1
@@ -153,8 +154,8 @@
desc = "A hydroponic HUD fitted with a light amplifier."
icon_state = "hydroponichudnight"
item_state = "glasses"
darkness_view = 8
invis_view = SEE_INVISIBLE_MINIMUM //don't render darkness while wearing these
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
prescription_upgradable = 0
/obj/item/clothing/glasses/hud/security/tajblind
+2 -1
View File
@@ -50,6 +50,7 @@
desc = "A helmet with a built-in thermal scanning visor."
icon_state = "helmetthermals"
vision_flags = SEE_MOBS
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
/obj/item/clothing/head/helmet/meson
name = "meson visor helmet"
@@ -67,7 +68,7 @@
name = "night-vision helmet"
desc = "A helmet with a built-in pair of night vision goggles."
icon_state = "helmetNVG"
helmet_goggles_invis_view = SEE_INVISIBLE_MINIMUM //don't render darkness while wearing these
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE //don't render darkness while wearing these
/obj/item/clothing/head/helmet/alt
name = "bulletproof helmet"
@@ -47,7 +47,8 @@
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
unacidable = 1
vision_flags = SEE_MOBS
helmet_goggles_invis_view = SEE_INVISIBLE_MINIMUM //don't render darkness while wearing these
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE //don't render darkness while wearing these
see_in_dark = 8
HUDType = MEDHUD
strip_delay = 130
@@ -630,7 +630,7 @@
var/area/t = get_area(M)
var/obj/item/radio/headset/a = new /obj/item/radio/headset(src)
if(istype(t, /area/syndicate_station) || istype(t, /area/syndicate_mothership) || istype(t, /area/shuttle/syndicate_elite) )
if(istype(t, /area/syndicate_mothership) || istype(t, /area/shuttle/syndicate_elite))
//give the syndicats a bit of stealth
a.autosay("[M] has been vandalized in Space!", "[M]'s Death Alarm")
else
+2 -1
View File
@@ -58,7 +58,8 @@
blueeffect.screen_loc = "WEST,SOUTH to EAST,NORTH"
blueeffect.icon = 'icons/effects/effects.dmi'
blueeffect.icon_state = "shieldsparkles"
blueeffect.layer = 17
blueeffect.layer = FLASH_LAYER
blueeffect.plane = FULLSCREEN_PLANE
blueeffect.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
M.client.screen += blueeffect
sleep(20)
+15 -11
View File
@@ -17,10 +17,11 @@ We hope you enjoy the lights.", "Harmless ions approaching", new_sound = 'sound/
M.playsound_local(null, 'sound/ambience/aurora_caelus.ogg', 20, FALSE, pressure_affected = FALSE)
/datum/event/aurora_caelus/start()
for(var/s in GLOB.station_level_space_turfs)
var/turf/space/S = s
S.set_light(S.light_range * 3, S.light_power * 0.5, aurora_colors[1])
CHECK_TICK
for(var/area in GLOB.all_areas)
var/area/A = area
if(initial(A.dynamic_lighting) == DYNAMIC_LIGHTING_IFSTARLIGHT)
for(var/turf/space/S in A)
S.set_light(S.light_range * 3, S.light_power * 0.5)
/datum/event/aurora_caelus/tick()
if(aurora_progress >= aurora_colors.len)
@@ -28,15 +29,18 @@ We hope you enjoy the lights.", "Harmless ions approaching", new_sound = 'sound/
if(activeFor % 5 == 0)
aurora_progress++
var/aurora_color = aurora_colors[aurora_progress]
for(var/s in GLOB.station_level_space_turfs)
var/turf/space/S = s
S.set_light(l_color = aurora_color)
CHECK_TICK
for(var/area in GLOB.all_areas)
var/area/A = area
if(initial(A.dynamic_lighting) == DYNAMIC_LIGHTING_IFSTARLIGHT)
for(var/turf/space/S in A)
S.set_light(l_color = aurora_color)
/datum/event/aurora_caelus/end()
for(var/s in GLOB.station_level_space_turfs)
var/turf/space/S = s
fade_to_black(S)
for(var/area in GLOB.all_areas)
var/area/A = area
if(initial(A.dynamic_lighting) == DYNAMIC_LIGHTING_IFSTARLIGHT)
for(var/turf/space/S in A)
fade_to_black(S)
event_announcement.Announce("The Aurora Caelus event is now ending. Starlight conditions will slowly return to normal. \
When this has concluded, please return to your workplace and continue work as normal. \
Have a pleasant shift, [station_name()], and thank you for watching with us.",
+1 -1
View File
@@ -23,7 +23,7 @@
"atrazine","banana","charcoal","space_drugs","methamphetamine","holywater","ethanol","hot_coco","facid",
"blood","morphine","ether","fluorine","mutadone","mutagen","hydrocodone","fuel",
"haloperidol","lsd","syndicate_nanites","lipolicide","frostoil","salglu_solution","beepskysmash",
"omnizine", "amanitin", "neurotoxin", "synaptizine")
"omnizine", "amanitin", "neurotoxin", "synaptizine", "rotatium")
var/datum/reagents/R = new/datum/reagents(50)
R.my_atom = vent
R.add_reagent(pick(gunk), 50)
+1 -1
View File
@@ -54,7 +54,7 @@ turf: (lighting_turf.dm)
- Create lighting overlays for this turf
atom/movable/lighting_overlay: (lighting_overlay.dm)
atom/movable/lighting_object: (lighting_object.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
+26 -5
View File
@@ -1,9 +1,30 @@
/area
luminosity = TRUE
var/dynamic_lighting = TRUE
var/dynamic_lighting = DYNAMIC_LIGHTING_ENABLED
/area/New()
. = ..()
/area/proc/set_dynamic_lighting(var/new_dynamic_lighting = DYNAMIC_LIGHTING_ENABLED)
if(new_dynamic_lighting == dynamic_lighting)
return FALSE
if(dynamic_lighting)
luminosity = FALSE
dynamic_lighting = new_dynamic_lighting
if(IS_DYNAMIC_LIGHTING(src))
cut_overlay(/obj/effect/fullbright)
for (var/turf/T in src)
if(IS_DYNAMIC_LIGHTING(T))
T.lighting_build_overlay()
else
add_overlay(/obj/effect/fullbright)
for (var/turf/T in src)
if(T.lighting_object)
T.lighting_clear_overlay()
return TRUE
/area/vv_edit_var(var_name, var_value)
switch(var_name)
if("dynamic_lighting")
set_dynamic_lighting(var_value)
return TRUE
return ..()
+79 -46
View File
@@ -1,14 +1,18 @@
/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/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/datum/light_source/light
var/list/light_sources
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.
// Nonsensical value for l_color default, so we can detect if it gets set to null.
// 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(l_range, l_power, l_color = NONSENSICAL_VALUE)
/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
@@ -18,59 +22,48 @@
if(l_color != NONSENSICAL_VALUE)
light_color = l_color
SEND_SIGNAL(src, COMSIG_ATOM_SET_LIGHT, l_range, l_power, 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)
if(light)
light.destroy()
light = null
if(!light_power || !light_range) // We won't emit light anyways, destroy the light source.
QDEL_NULL(light)
else
if(!istype(loc, /atom/movable))
if(!ismovableatom(loc)) // We choose what atom should be the top atom of the light here.
. = src
else
. = loc
if(light)
if(light) // Update the light or create it if it does not exist.
light.update(.)
else
light = new /datum/light_source(src, .)
light = new/datum/light_source(src, .)
/atom/proc/extinguish_light()
return
/atom/Destroy()
if(light)
light.destroy()
light = null
return ..()
// 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()
return ..()
/atom/movable/Move()
var/turf/old_loc = loc
. = ..()
if(opacity && istype(T))
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()
if(loc != old_loc)
for(var/datum/light_source/L in light_sources)
L.source_atom.update_light()
var/turf/new_loc = loc
if(istype(old_loc) && opacity)
old_loc.reconsider_lights()
if(istype(new_loc) && opacity)
new_loc.reconsider_lights()
/atom/proc/set_opacity(new_opacity)
// 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
@@ -88,14 +81,54 @@
if(old_has_opaque_atom != T.has_opaque_atom)
T.reconsider_lights()
/obj/item/equipped()
. = ..()
update_light()
/obj/item/pickup()
/atom/movable/Moved(atom/OldLoc, Dir)
. = ..()
update_light()
var/datum/light_source/L
var/thing
for (thing in light_sources) // Cycle through the light sources on this atom and tell them to update.
L = thing
L.source_atom.update_light()
/obj/item/dropped()
. = ..()
update_light()
/atom/vv_edit_var(var_name, var_value)
switch (var_name)
if("light_range")
set_light(l_range=var_value)
return TRUE
if("light_power")
set_light(l_power=var_value)
return TRUE
if("light_color")
set_light(l_color=var_value)
return TRUE
return ..()
/atom/proc/flash_lighting_fx(_range = FLASH_LIGHT_RANGE, _power = FLASH_LIGHT_POWER, _color = LIGHT_COLOR_WHITE, _duration = FLASH_LIGHT_DURATION, _reset_lighting = TRUE)
return
/turf/flash_lighting_fx(_range = FLASH_LIGHT_RANGE, _power = FLASH_LIGHT_POWER, _color = LIGHT_COLOR_WHITE, _duration = FLASH_LIGHT_DURATION, _reset_lighting = TRUE)
if(!_duration)
stack_trace("Lighting FX obj created on a turf without a duration")
new /obj/effect/dummy/lighting_obj (src, _color, _range, _power, _duration)
/obj/flash_lighting_fx(_range = FLASH_LIGHT_RANGE, _power = FLASH_LIGHT_POWER, _color = LIGHT_COLOR_WHITE, _duration = FLASH_LIGHT_DURATION, _reset_lighting = TRUE)
var/temp_color
var/temp_power
var/temp_range
if(!_reset_lighting) //incase the obj already has a lighting color that you don't want cleared out after, ie computer monitors.
temp_color = light_color
temp_power = light_power
temp_range = light_range
set_light(_range, _power, _color)
addtimer(CALLBACK(src, /atom/proc/set_light, _reset_lighting ? initial(light_range) : temp_range, _reset_lighting ? initial(light_power) : temp_power, _reset_lighting ? initial(light_color) : temp_color), _duration, TIMER_OVERRIDE|TIMER_UNIQUE)
/mob/living/flash_lighting_fx(_range = FLASH_LIGHT_RANGE, _power = FLASH_LIGHT_POWER, _color = LIGHT_COLOR_WHITE, _duration = FLASH_LIGHT_DURATION, _reset_lighting = TRUE)
mob_light(_color, _range, _power, _duration)
/mob/living/proc/mob_light(_color, _range, _power, _duration)
var/obj/effect/dummy/lighting_obj/moblight/mob_light_obj = new (src, _color, _range, _power, _duration)
return mob_light_obj
+56 -38
View File
@@ -1,15 +1,13 @@
/var/total_lighting_corners = 0
/var/datum/lighting_corner/dummy/dummy_lighting_corner = new
// Because we can control each corner of every lighting overlay.
// Because we can control each corner of every lighting object.
// 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)
GLOBAL_LIST_INIT(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/list/turf/masters
var/list/datum/light_source/affecting // Light sources affecting us.
var/active = FALSE // TRUE if one of our masters has dynamic lighting.
var/x = 0
@@ -27,13 +25,9 @@
var/cache_b = LIGHTING_SOFT_THRESHOLD
var/cache_mx = 0
var/update_gen = 0
/datum/lighting_corner/New(var/turf/new_turf, var/diagonal)
. = ..()
total_lighting_corners++
masters = list()
masters[new_turf] = turn(diagonal, 180)
z = new_turf.z
@@ -51,75 +45,99 @@
// Diagonal one is easy.
T = get_step(new_turf, diagonal)
if (T) // In case we're on the map's border.
if (!T.corners)
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))
i = GLOB.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)
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))
i = GLOB.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)
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))
i = GLOB.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)
var/turf/T
var/thing
for (thing in masters)
T = thing
if(T.lighting_object)
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)
if((abs(delta_r)+abs(delta_g)+abs(delta_b)) == 0)
return
lum_r += delta_r
lum_g += delta_g
lum_b += delta_b
if (!needs_update)
if(!needs_update)
needs_update = TRUE
lighting_update_corners += src
GLOB.lighting_update_corners += src
/datum/lighting_corner/proc/update_overlays()
// 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.
/datum/lighting_corner/proc/update_objects()
// Cache these values a head of time so 4 individual lighting objects don't all calculate them individually.
var/lum_r = src.lum_r
var/lum_g = src.lum_g
var/lum_b = src.lum_b
var/mx = max(lum_r, lum_g, lum_b) // Scale it so one of them is the strongest lum, if it is above 1.
. = 1 // factor
if (mx > 1)
if(mx > 1)
. = 1 / mx
else if (mx < LIGHTING_SOFT_THRESHOLD)
#if LIGHTING_SOFT_THRESHOLD != 0
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
cache_r = round(lum_r * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD
cache_g = round(lum_g * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD
cache_b = round(lum_b * ., LIGHTING_ROUND_VALUE) || LIGHTING_SOFT_THRESHOLD
#else
cache_r = round(lum_r * ., LIGHTING_ROUND_VALUE)
cache_g = round(lum_g * ., LIGHTING_ROUND_VALUE)
cache_b = round(lum_b * ., LIGHTING_ROUND_VALUE)
#endif
cache_mx = round(mx, LIGHTING_ROUND_VALUE)
for (var/TT in masters)
var/turf/T = TT
if (T.lighting_overlay)
if (!T.lighting_overlay.needs_update)
T.lighting_overlay.needs_update = TRUE
lighting_update_overlays += T.lighting_overlay
if(T.lighting_object)
if(!T.lighting_object.needs_update)
T.lighting_object.needs_update = TRUE
GLOB.lighting_update_objects += T.lighting_object
/datum/lighting_corner/dummy/New()
return
/datum/lighting_corner/Destroy(var/force)
if(!force)
return QDEL_HINT_LETMELIVE
stack_trace("Attempted qdel of a lighting corner.")
return ..()
+148
View File
@@ -0,0 +1,148 @@
/atom/movable/lighting_object
name = ""
anchored = TRUE
icon = LIGHTING_ICON
icon_state = "transparent"
color = LIGHTING_BASE_MATRIX
plane = LIGHTING_PLANE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
layer = LIGHTING_LAYER
invisibility = INVISIBILITY_LIGHTING
simulated = FALSE
var/needs_update = FALSE
var/turf/myturf
/atom/movable/lighting_object/Initialize(mapload)
. = ..()
verbs.Cut()
myturf = loc
if(myturf.lighting_object)
qdel(myturf.lighting_object, force = TRUE)
myturf.lighting_object = src
myturf.luminosity = 0
for(var/turf/space/S in RANGE_TURFS(1, src)) //RANGE_TURFS is in code\__HELPERS\game.dm
S.update_starlight()
needs_update = TRUE
GLOB.lighting_update_objects += src
/atom/movable/lighting_object/Destroy(var/force)
if(force)
GLOB.lighting_update_objects -= src
if(loc != myturf)
var/turf/oldturf = get_turf(myturf)
var/turf/newturf = get_turf(loc)
stack_trace("A lighting object was qdeleted with a different loc then it is suppose to have ([COORD(oldturf)] -> [COORD(newturf)])")
if(isturf(myturf))
myturf.lighting_object = null
myturf.luminosity = 1
myturf = null
return ..()
else
return QDEL_HINT_LETMELIVE
/atom/movable/lighting_object/proc/update()
if(loc != myturf)
if(loc)
var/turf/oldturf = get_turf(myturf)
var/turf/newturf = get_turf(loc)
warning("A lighting object realised it's loc had changed in update() ([myturf]\[[myturf ? myturf.type : "null"]]([COORD(oldturf)]) -> [loc]\[[ loc ? loc.type : "null"]]([COORD(newturf)]))!")
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.
var/static/datum/lighting_corner/dummy/dummy_lighting_corner = new
var/list/corners = myturf.corners
var/datum/lighting_corner/cr = dummy_lighting_corner
var/datum/lighting_corner/cg = dummy_lighting_corner
var/datum/lighting_corner/cb = dummy_lighting_corner
var/datum/lighting_corner/ca = dummy_lighting_corner
if(corners) //done this way for speed
cr = corners[3] || dummy_lighting_corner
cg = corners[2] || dummy_lighting_corner
cb = corners[4] || dummy_lighting_corner
ca = corners[1] || dummy_lighting_corner
var/max = max(cr.cache_mx, cg.cache_mx, cb.cache_mx, ca.cache_mx)
var/rr = cr.cache_r
var/rg = cr.cache_g
var/rb = cr.cache_b
var/gr = cg.cache_r
var/gg = cg.cache_g
var/gb = cg.cache_b
var/br = cb.cache_r
var/bg = cb.cache_g
var/bb = cb.cache_b
var/ar = ca.cache_r
var/ag = ca.cache_g
var/ab = ca.cache_b
#if LIGHTING_SOFT_THRESHOLD != 0
var/set_luminosity = max > LIGHTING_SOFT_THRESHOLD
#else
// Because of floating points™?, it won't even be a flat 0.
// This number is mostly arbitrary.
var/set_luminosity = max > 1e-6
#endif
if((rr & gr & br & ar) && (rg + gg + bg + ag + rb + gb + bb + ab == 8))
//anything that passes the first case is very likely to pass the second, and addition is a little faster in this case
icon_state = "transparent"
color = null
else if(!set_luminosity)
icon_state = "dark"
color = null
else
icon_state = null
color = list(
rr, rg, rb, 00,
gr, gg, gb, 00,
br, bg, bb, 00,
ar, ag, ab, 00,
00, 00, 00, 01
)
luminosity = set_luminosity
// Variety of overrides so the overlays don't get affected by weird things.
/atom/movable/lighting_object/ex_act(severity)
return 0
/atom/movable/lighting_object/singularity_act()
return
/atom/movable/lighting_object/singularity_pull()
return
/atom/movable/lighting_object/blob_act()
return
/atom/movable/lighting_object/onTransitZ()
return
// Override here to prevent things accidentally moving around overlays.
/atom/movable/lighting_object/forceMove(atom/destination, var/no_tp=FALSE, var/harderforce = FALSE)
if(harderforce)
. = ..()
-89
View File
@@ -1,89 +0,0 @@
/var/total_lighting_overlays = 0
/atom/movable/lighting_overlay
name = ""
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
simulated = 0
anchored = 1
icon = LIGHTING_ICON
layer = LIGHTING_LAYER
plane = LIGHTING_PLANE
invisibility = INVISIBILITY_LIGHTING
color = LIGHTING_BASE_MATRIX
icon_state = "light1"
blend_mode = BLEND_MULTIPLY
var/lum_r = 0
var/lum_g = 0
var/lum_b = 0
var/needs_update = FALSE
/atom/movable/lighting_overlay/New(var/atom/loc, var/no_update = FALSE)
. = ..()
verbs.Cut()
total_lighting_overlays++
var/turf/T = loc //If this runtimes atleast we'll know what's creating overlays outside of turfs.
T.lighting_overlay = src
T.luminosity = 0
if(no_update)
return
update_overlay()
/atom/movable/lighting_overlay/proc/update_overlay()
set waitfor = FALSE
var/turf/T = loc
if(!istype(T))
if(loc)
log_debug("A lighting overlay realised its loc was NOT a turf (actual loc: [loc][loc ? ", " + loc.type : "null"]) in update_overlay() and got qdel'ed!")
else
log_debug("A lighting overlay realised it was in nullspace in update_overlay() and got pooled!")
qdel(src)
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
/atom/movable/lighting_overlay/singularity_act()
return
/atom/movable/lighting_overlay/singularity_pull()
return
/atom/movable/lighting_overlay/Destroy()
total_lighting_overlays--
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
return ..()
+9 -13
View File
@@ -1,16 +1,12 @@
/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(!T.dynamic_lighting)
/proc/create_all_lighting_objects()
for(var/area/A in GLOB.all_areas)
if(!IS_DYNAMIC_LIGHTING(A))
continue
var/area/A = T.loc
if(!A.dynamic_lighting)
continue
for(var/turf/T in A)
if(!IS_DYNAMIC_LIGHTING(T))
continue
new /atom/movable/lighting_overlay(T, TRUE)
new/atom/movable/lighting_object(T)
CHECK_TICK
CHECK_TICK
+206 -198
View File
@@ -1,12 +1,12 @@
/var/total_lighting_sources = 0
// 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/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/turf/pixel_turf // The turf the top_atom appears to over.
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()
@@ -26,133 +26,80 @@
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
var/needs_update = LIGHTING_NO_UPDATE // Whether we are queued for an update.
/datum/light_source/New(var/atom/owner, var/atom/top)
total_lighting_sources++
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.
LAZYADD(source_atom.light_sources, src)
top_atom = top
if(top_atom != source_atom)
if(!top.light_sources)
top.light_sources = list()
top_atom.light_sources += src
LAZYADD(top_atom.light_sources, src)
source_turf = top_atom
pixel_turf = get_turf_pixel(top_atom) || source_turf
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()
total_lighting_sources--
destroyed = TRUE
force_update()
/datum/light_source/Destroy(force)
remove_lum()
if(source_atom)
if(!source_atom.light_sources)
log_runtime(EXCEPTION("Atom [source_atom] was a light source, but lacked a light source list!\n"), source_atom)
else
source_atom.light_sources -= src
LAZYREMOVE(source_atom.light_sources, src)
if(top_atom)
top_atom.light_sources -= src
LAZYREMOVE(top_atom.light_sources, src)
if(needs_update)
GLOB.lighting_update_lights -= src
. = ..()
// Yes this doesn't align correctly on anything other than 4 width tabs.
// If you want it to go switch everybody to elastic tab stops.
// Actually that'd be great if you could!
#define EFFECT_UPDATE(level) \
if(needs_update == LIGHTING_NO_UPDATE) \
GLOB.lighting_update_lights += src; \
if(needs_update < level) \
needs_update = level; \
// 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; \
}
// 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
if(top_atom != source_atom && top_atom.light_sources) // Remove ourselves from the light sources of that top atom.
LAZYREMOVE(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()
LAZYADD(top_atom.light_sources, src) // Add ourselves to the light sources of our new top atom.
top_atom.light_sources += src // Add ourselves to the light sources of our new top atom.
effect_update(null)
EFFECT_UPDATE(LIGHTING_CHECK_UPDATE)
// Will force an update without checking if it's actually needed.
/datum/light_source/proc/force_update()
force_update = 1
effect_update(null)
EFFECT_UPDATE(LIGHTING_FORCE_UPDATE)
// 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(isturf(top_atom))
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
EFFECT_UPDATE(LIGHTING_VIS_UPDATE)
// 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
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
@@ -163,128 +110,189 @@
// 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 LUM_FALLOFF(C, T) (1 - CLAMP01(sqrt((C.x - T.x) ** 2 + (C.y - T.y) ** 2 + LIGHTING_HEIGHT) / max(1, light_range)))
#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 \
#define APPLY_CORNER(C) \
. = LUM_FALLOFF(C, pixel_turf); \
. *= light_power; \
var/OLD = effect_str[C]; \
effect_str[C] = .; \
\
C.update_lumcount \
( \
(. * lum_r) - (OLD * applied_lum_r), \
(. * lum_g) - (OLD * applied_lum_g), \
(. * lum_b) - (OLD * 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 \
#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
/datum/light_source/proc/remove_lum()
applied = FALSE
var/thing
for (thing in affecting_turfs)
var/turf/T = thing
LAZYREMOVE(T.affecting_lights, src)
affecting_turfs = null
var/datum/lighting_corner/C
for (thing in effect_str)
C = thing
REMOVE_CORNER(C)
LAZYREMOVE(C.affecting, src)
effect_str = null
/datum/light_source/proc/recalc_corner(var/datum/lighting_corner/C)
LAZYINITLIST(effect_str)
if(effect_str[C]) // Already have one.
REMOVE_CORNER(C)
effect_str[C] = 0
APPLY_CORNER(C)
UNSETEMPTY(effect_str)
/datum/light_source/proc/update_corners()
var/update = FALSE
var/atom/source_atom = src.source_atom
if(QDELETED(source_atom))
qdel(src)
return
if(source_atom.light_power != light_power)
light_power = source_atom.light_power
update = TRUE
if(source_atom.light_range != light_range)
light_range = source_atom.light_range
update = TRUE
if(!top_atom)
top_atom = source_atom
update = TRUE
if(!light_range || !light_power)
qdel(src)
return
if(isturf(top_atom))
if(source_turf != top_atom)
source_turf = top_atom
pixel_turf = source_turf
update = TRUE
else if(top_atom.loc != source_turf)
source_turf = top_atom.loc
pixel_turf = get_turf_pixel(top_atom)
update = TRUE
else
var/P = get_turf_pixel(top_atom)
if(P != pixel_turf)
pixel_turf = P
update = TRUE
if(!isturf(source_turf))
if(applied)
remove_lum()
return
if(light_range && light_power && !applied)
update = TRUE
if(source_atom.light_color != light_color)
light_color = source_atom.light_color
parse_light_color()
update = TRUE
else if(applied_lum_r != lum_r || applied_lum_g != lum_g || applied_lum_b != lum_b)
update = TRUE
if(update)
needs_update = LIGHTING_CHECK_UPDATE
applied = TRUE
else if(needs_update == LIGHTING_CHECK_UPDATE)
return //nothing's changed
var/list/datum/lighting_corner/corners = list()
var/list/turf/turfs = list()
var/thing
var/datum/lighting_corner/C
var/turf/T
if(source_turf)
var/oldlum = source_turf.luminosity
source_turf.luminosity = CEILING(light_range, 1)
for(T in view(CEILING(light_range, 1), source_turf))
for (thing in T.get_corners(source_turf))
C = thing
corners[C] = 0
turfs += T
source_turf.luminosity = oldlum
LAZYINITLIST(affecting_turfs)
var/list/L = turfs - affecting_turfs // New turfs, add us to the affecting lights of them.
affecting_turfs += L
for (thing in L)
T = thing
LAZYADD(T.affecting_lights, src)
L = affecting_turfs - turfs // Now-gone turfs, remove us from the affecting lights.
affecting_turfs -= L
for (thing in L)
T = thing
LAZYREMOVE(T.affecting_lights, src)
LAZYINITLIST(effect_str)
if(needs_update == LIGHTING_VIS_UPDATE)
for (thing in corners - effect_str) // New corners
C = thing
LAZYADD(C.affecting, src)
if(!C.active)
effect_str[C] = 0
continue
APPLY_CORNER(C)
else
L = corners - effect_str
for (thing in L) // New corners
C = thing
LAZYADD(C.affecting, src)
if(!C.active)
effect_str[C] = 0
continue
APPLY_CORNER(C)
for (thing in corners - L) // Existing corners
C = thing
if(!C.active)
effect_str[C] = 0
continue
APPLY_CORNER(C)
L = effect_str - corners
for (thing in L) // Old, now gone, corners.
C = thing
REMOVE_CORNER(C)
LAZYREMOVE(C.affecting, src)
effect_str -= L
// 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()
UNSETEMPTY(effect_str)
UNSETEMPTY(affecting_turfs)
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)
effect_str[C] = 0
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)
effect_str[C] = 0
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 EFFECT_UPDATE
#undef LUM_FALLOFF
#undef REMOVE_CORNER
#undef APPLY_CORNER
#undef APPLY_CORNER
+77 -44
View File
@@ -5,98 +5,131 @@
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/atom/movable/lighting_object/lighting_object // Our lighting object.
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)
var/datum/light_source/L
var/thing
for (thing in affecting_lights)
L = thing
L.vis_update()
/turf/proc/lighting_clear_overlay()
if(lighting_overlay)
qdel(lighting_overlay)
if(lighting_object)
qdel(lighting_object, TRUE)
for(var/datum/lighting_corner/C in corners)
var/datum/lighting_corner/C
var/thing
for (thing in corners)
if(!thing)
continue
C = thing
C.update_active()
// Builds a lighting overlay for us, but only if our area is dynamic.
// Builds a lighting object for us, but only if our area is dynamic.
/turf/proc/lighting_build_overlay()
if(lighting_overlay)
return
if(lighting_object)
qdel(lighting_object,force=TRUE) //Shitty fix for lighting objects persisting after death
var/area/A = loc
if(A.dynamic_lighting)
if(!lighting_corners_initialised)
generate_missing_corners()
if(!IS_DYNAMIC_LIGHTING(A) && !light_sources)
return
new /atom/movable/lighting_overlay(src)
if(!lighting_corners_initialised)
generate_missing_corners()
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)
new/atom/movable/lighting_object(src)
C.active = TRUE
var/thing
var/datum/lighting_corner/C
var/datum/light_source/S
for (thing in corners)
if(!thing)
continue
C = thing
if(!C.active) // We would activate the corner, calculate the lighting for it.
for (thing in C.affecting)
S = thing
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)
if(!lighting_object)
return 1
var/totallums = 0
for(var/datum/lighting_corner/L in corners)
totallums += max(L.lum_r, L.lum_g, L.lum_b)
var/thing
var/datum/lighting_corner/L
for (thing in corners)
if(!thing)
continue
L = thing
totallums += L.lum_r + L.lum_b + L.lum_g
totallums /= 4 // 4 corners, max channel selected, return the average
totallums /= 12 // 4 corners, each with 3 channels, get the average.
totallums =(totallums - minlum) /(maxlum - minlum)
totallums = (totallums - minlum) / (maxlum - minlum)
return CLAMP01(totallums)
// Returns a boolean whether the turf is on soft lighting.
// Soft lighting being the threshold at which point the overlay considers
// itself as too dark to allow sight and see_in_dark becomes useful.
// So basically if this returns true the tile is unlit black.
/turf/proc/is_softly_lit()
if(!lighting_object)
return FALSE
return !lighting_object.luminosity
// 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
has_opaque_atom = opacity
if(!has_opaque_atom)
for (var/atom/A in src.contents) // Loop through every movable atom on our tile PLUS ourselves (we matter too...)
if(A.opacity)
has_opaque_atom = TRUE
break
// 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)
/turf/Exited(atom/movable/Obj, 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/proc/change_area(var/area/old_area, var/area/new_area)
if(SSlighting.initialized)
if(new_area.dynamic_lighting != old_area.dynamic_lighting)
if(new_area.dynamic_lighting)
lighting_build_overlay()
else
lighting_clear_overlay()
/turf/proc/get_corners()
if(!IS_DYNAMIC_LIGHTING(src) && !light_sources)
return null
if(!lighting_corners_initialised)
generate_missing_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()
if(!IS_DYNAMIC_LIGHTING(src) && !light_sources)
return
lighting_corners_initialised = TRUE
if(!corners)
corners = list(null, null, null, null)
for(var/i = 1 to 4)
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])
corners[i] = new/datum/lighting_corner(src, GLOB.LIGHTING_CORNER_DIAGONAL[i])
@@ -1,7 +0,0 @@
#undef LIGHTING_FALLOFF
#undef LIGHTING_LAMBERTIAN
#undef LIGHTING_HEIGHT
#undef LIGHTING_ICON
#undef LIGHTING_BASE_MATRIX
@@ -184,42 +184,52 @@
generic_pixel_x = 1
vehicle_move_delay = 1
// Wisp Lantern
//Wisp Lantern
/obj/item/wisp_lantern
name = "spooky lantern"
desc = "This lantern gives off no light, but is home to a friendly wisp."
icon = 'icons/obj/lighting.dmi'
icon_state = "lantern-blue"
item_state = "lantern"
light_range = 7
var/obj/effect/wisp/wisp
var/sight_flags = SEE_MOBS
var/lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
/obj/item/wisp_lantern/attack_self(mob/user)
if(!wisp)
to_chat(user, "<span class='warning'>The wisp has gone missing!</span>")
return
if(wisp.loc == src)
to_chat(user, "<span class='notice'>You release the wisp. It begins to bob around your head.</span>")
user.sight |= SEE_MOBS
icon_state = "lantern"
wisp.orbit(user, 20, forceMove = TRUE)
return
if(wisp.loc == src)
RegisterSignal(user, COMSIG_MOB_UPDATE_SIGHT, .proc/update_user_sight)
to_chat(user, "<span class='notice'>You release the wisp. It begins to bob around your head.</span>")
icon_state = "lantern"
wisp.orbit(user, 20)
set_light(0)
user.update_sight()
to_chat(user, "<span class='notice'>The wisp enhances your vision.</span>")
feedback_add_details("wisp_lantern","F") // freed
else
UnregisterSignal(user, COMSIG_MOB_UPDATE_SIGHT)
to_chat(user, "<span class='notice'>You return the wisp to the lantern.</span>")
if(wisp.orbiting)
var/atom/A = wisp.orbiting
if(isliving(A))
var/mob/living/M = A
M.sight &= ~SEE_MOBS
to_chat(M, "<span class='notice'>Your vision returns to normal.</span>")
wisp.stop_orbit()
wisp.loc = src
wisp.forceMove(src)
set_light(initial(light_range))
user.update_sight()
to_chat(user, "<span class='notice'>Your vision returns to normal.</span>")
icon_state = "lantern-blue"
feedback_add_details("wisp_lantern","R") // returned
/obj/item/wisp_lantern/New()
..()
/obj/item/wisp_lantern/Initialize(mapload)
. = ..()
wisp = new(src)
/obj/item/wisp_lantern/Destroy()
@@ -230,17 +240,20 @@
wisp.visible_message("<span class='notice'>[wisp] has a sad feeling for a moment, then it passes.</span>")
return ..()
/obj/item/wisp_lantern/proc/update_user_sight(mob/user)
user.sight |= sight_flags
if(!isnull(lighting_alpha))
user.lighting_alpha = min(user.lighting_alpha, lighting_alpha)
/obj/effect/wisp
name = "friendly wisp"
desc = "Happy to light your way."
icon = 'icons/obj/lighting.dmi'
icon_state = "orb"
layer = ABOVE_ALL_MOB_LAYER
light_power = 1
light_range = 7
layer = ABOVE_ALL_MOB_LAYER
//Red/Blue Cubes
/obj/item/warp_cube
name = "blue cube"
desc = "A mysterious blue cube."
+3 -2
View File
@@ -273,8 +273,9 @@
/area/survivalpod
name = "\improper Emergency Shelter"
icon_state = "away"
requires_power = 0
has_gravity = 1
requires_power = FALSE
has_gravity = TRUE
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
/obj/item/survivalcapsule
name = "bluespace shelter capsule"
+9 -25
View File
@@ -184,28 +184,6 @@
mode = MINEDRONE_COLLECT
SetCollectBehavior()
/mob/living/simple_animal/hostile/mining_drone/update_sight()
if(!client)
return
if(stat == DEAD)
grant_death_vision()
return
if(mesons_active)
sight |= SEE_TURFS
see_invisible = SEE_INVISIBLE_MINIMUM
else
sight &= ~SEE_TURFS
see_invisible = SEE_INVISIBLE_LIVING
see_in_dark = initial(see_in_dark)
if(client.eye != src)
var/atom/A = client.eye
if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates.
return
//Actions for sentient minebots
/datum/action/innate/minedrone
@@ -232,10 +210,16 @@
/datum/action/innate/minedrone/toggle_meson_vision/Activate()
var/mob/living/simple_animal/hostile/mining_drone/user = owner
user.mesons_active = !user.mesons_active
user.update_sight()
if(user.sight & SEE_TURFS)
user.sight &= ~SEE_TURFS
user.lighting_alpha = initial(user.lighting_alpha)
else
user.sight |= SEE_TURFS
user.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
to_chat(user, "<span class='notice'>You toggle your meson vision [(user.mesons_active) ? "on" : "off"].</span>")
user.sync_lighting_plane_alpha()
to_chat(user, "<span class='notice'>You toggle your meson vision [(user.sight & SEE_TURFS) ? "on" : "off"].</span>")
/datum/action/innate/minedrone/toggle_mode
name = "Toggle Mode"
+1 -1
View File
@@ -7,7 +7,7 @@
move_resist = INFINITY
status_flags = GODMODE // You can't damage it.
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
see_in_dark = 7
see_in_dark = 8
invisibility = 101 // No one can see us
sight = SEE_SELF
move_on_shuttle = 0
+1 -1
View File
@@ -1,6 +1,6 @@
/mob/dead/observer/Logout()
if(client)
client.images -= ghost_darkness_images
client.images -= ghost_images
..()
spawn(0)
if(src && !key) //we've transferred to another mob. This ghost should be deleted.
+29 -10
View File
@@ -1,7 +1,7 @@
#define GHOST_CAN_REENTER 1
#define GHOST_IS_OBSERVER 2
var/list/image/ghost_darkness_images = list() //this is a list of images for things ghosts should still be able to see when they toggle darkness
var/list/image/ghost_images = list()
GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
@@ -74,7 +74,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
ghostimage.appearance_flags |= KEEP_TOGETHER
ghostimage.alpha = alpha
appearance_flags |= KEEP_TOGETHER
ghost_darkness_images |= ghostimage
ghost_images |= ghostimage
updateallghostimages()
if(!T) T = pick(latejoin) //Safety in case we cannot find the body's position
forceMove(T)
@@ -90,7 +90,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
M.following_mobs -= src
following = null
if(ghostimage)
ghost_darkness_images -= ghostimage
ghost_images -= ghostimage
QDEL_NULL(ghostimage)
updateallghostimages()
return ..()
@@ -676,14 +676,32 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set desc = "Toggles your ability to see things only ghosts can see, like other ghosts"
set category = "Ghost"
ghostvision = !(ghostvision)
updateghostsight()
update_sight()
to_chat(usr, "You [(ghostvision?"now":"no longer")] have ghost vision.")
/mob/dead/observer/verb/toggle_darkness()
set name = "Toggle Darkness"
set category = "Ghost"
seedarkness = !(seedarkness)
updateghostsight()
switch(lighting_alpha)
if (LIGHTING_PLANE_ALPHA_VISIBLE)
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
if (LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE)
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
if (LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE)
lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE
else
lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
update_sight()
/mob/dead/observer/update_sight()
if (!ghostvision)
see_invisible = SEE_INVISIBLE_LIVING
else
see_invisible = SEE_INVISIBLE_OBSERVER
updateghostimages()
. = ..()
/mob/dead/observer/proc/updateghostsight()
if(!seedarkness)
@@ -691,7 +709,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
else
see_invisible = SEE_INVISIBLE_OBSERVER
if(!ghostvision)
see_invisible = SEE_INVISIBLE_LIVING;
see_invisible = SEE_INVISIBLE_LIVING
updateghostimages()
/proc/updateallghostimages()
@@ -701,11 +720,11 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/proc/updateghostimages()
if(!client)
return
if(seedarkness || !ghostvision)
client.images -= ghost_darkness_images
if(!ghostvision)
client.images -= ghost_images
else
//add images for the 60inv things ghosts can normally see when darkness is enabled so they can see them now
client.images |= ghost_darkness_images
client.images |= ghost_images
if(ghostimage)
client.images -= ghostimage //remove ourself
+4 -4
View File
@@ -38,8 +38,8 @@
if(!l_hand && has_left_hand())
W.forceMove(src) //TODO: move to equipped?
l_hand = W
W.layer = 20 //TODO: move to equipped?
W.plane = HUD_PLANE //TODO: move to equipped?
W.layer = ABOVE_HUD_LAYER //TODO: move to equipped?
W.plane = ABOVE_HUD_PLANE //TODO: move to equipped?
W.equipped(src,slot_l_hand)
if(pulling == W)
stop_pulling()
@@ -54,8 +54,8 @@
if(!r_hand && has_right_hand())
W.forceMove(src)
r_hand = W
W.layer = 20
W.plane = HUD_PLANE
W.layer = ABOVE_HUD_LAYER
W.plane = ABOVE_HUD_PLANE
W.equipped(src,slot_r_hand)
if(pulling == W)
stop_pulling()
+49 -12
View File
@@ -5,18 +5,21 @@
icon = 'icons/mob/alien.dmi'
gender = NEUTER
dna = null
alien_talk_understand = 1
nightvision = 1
alien_talk_understand = TRUE
var/nightvision = FALSE
see_in_dark = 4
var/obj/item/card/id/wear_id = null // Fix for station bounced radios -- Skie
var/has_fine_manipulation = 0
var/move_delay_add = 0 // movement delay to add
var/has_fine_manipulation = FALSE
var/move_delay_add = FALSE // movement delay to add
status_flags = CANPARALYSE|CANPUSH
var/heal_rate = 5
var/large = 0
var/large = FALSE
var/heat_protection = 0.5
var/leaping = 0
var/leaping = FALSE
ventcrawler = 2
var/list/alien_organs = list()
var/death_message = "lets out a waning guttural screech, green blood bubbling from its maw..."
@@ -149,15 +152,17 @@
if(!nightvision)
see_in_dark = 8
see_invisible = SEE_INVISIBLE_MINIMUM
nightvision = 1
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
nightvision = TRUE
usr.hud_used.nightvisionicon.icon_state = "nightvision1"
else if(nightvision == 1)
see_in_dark = 4
see_invisible = 45
nightvision = 0
else if(nightvision)
see_in_dark = initial(see_in_dark)
lighting_alpha = initial(lighting_alpha)
nightvision = FALSE
usr.hud_used.nightvisionicon.icon_state = "nightvision0"
update_sight()
/mob/living/carbon/alien/assess_threat(var/mob/living/simple_animal/bot/secbot/judgebot, var/lasercolor)
if(judgebot.emagged == 2)
@@ -264,3 +269,35 @@ Des: Removes all infected images from the alien.
return pick("xltrails_1", "xltrails_2")
else
return pick("xttrails_1", "xttrails_2")
/mob/living/carbon/alien/update_sight()
if(!client)
return
if(stat == DEAD)
grant_death_vision()
return
sight = SEE_MOBS
if(nightvision)
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
else
see_in_dark = initial(see_in_dark)
lighting_alpha = initial(lighting_alpha)
if(client.eye != src)
var/atom/A = client.eye
if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates.
return
for(var/obj/item/organ/internal/cyberimp/eyes/E in internal_organs)
sight |= E.vision_flags
if(E.see_in_dark)
see_in_dark = max(see_in_dark, E.see_in_dark)
if(E.see_invisible)
see_invisible = min(see_invisible, E.see_invisible)
if(!isnull(E.lighting_alpha))
lighting_alpha = min(lighting_alpha, E.lighting_alpha)
SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT)
sync_lighting_plane_alpha()
@@ -28,33 +28,3 @@
//BREATH TEMPERATURE
handle_breath_temperature(breath)
/mob/living/carbon/alien/update_sight()
if(!client)
return
if(stat == DEAD)
grant_death_vision()
return
sight = SEE_MOBS
if(nightvision)
see_in_dark = 8
see_invisible = SEE_INVISIBLE_MINIMUM
else
see_in_dark = 4
see_invisible = SEE_INVISIBLE_LEVEL_TWO
if(client.eye != src)
var/atom/A = client.eye
if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates.
return
for(var/obj/item/organ/internal/cyberimp/eyes/E in internal_organs)
sight |= E.vision_flags
if(E.dark_view)
see_in_dark = max(see_in_dark, E.dark_view)
if(E.see_invisible)
see_invisible = min(see_invisible, E.see_invisible)
if(see_override)
see_invisible = see_override
+36 -3
View File
@@ -323,8 +323,8 @@
return
var/extra_darkview = 0
if(E.dark_view)
extra_darkview = max(E.dark_view - 2, 0)
if(E.see_in_dark)
extra_darkview = max(E.see_in_dark - 2, 0)
extra_damage = extra_darkview
var/light_amount = 10 // assume full brightness
@@ -1129,4 +1129,37 @@ so that different stomachs can handle things in different ways VB*/
/mob/living/carbon/proc/shock_internal_organs(intensity)
for(var/obj/item/organ/O in internal_organs)
O.shock_organ(intensity)
O.shock_organ(intensity)
/mob/living/carbon/update_sight()
if(!client)
return
if(stat == DEAD)
grant_death_vision()
return
sight = initial(sight)
lighting_alpha = initial(lighting_alpha)
for(var/obj/item/organ/internal/cyberimp/eyes/E in internal_organs)
sight |= E.vision_flags
if(E.see_in_dark)
see_in_dark = max(see_in_dark, E.see_in_dark)
if(E.see_invisible)
see_invisible = min(see_invisible, E.see_invisible)
if(!isnull(E.lighting_alpha))
lighting_alpha = min(lighting_alpha, E.lighting_alpha)
if(client.eye != src)
var/atom/A = client.eye
if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates.
return
if(XRAY in mutations)
sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS)
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT)
sync_lighting_plane_alpha()
@@ -559,11 +559,14 @@
/mob/living/carbon/human/update_sight()
if(!client)
return
if(stat == DEAD)
grant_death_vision()
return
dna.species.update_sight(src)
SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT)
sync_lighting_plane_alpha()
//Added a safety check in case you want to shock a human mob directly through electrocute_act.
/mob/living/carbon/human/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = FALSE, override = FALSE, tesla_shock = FALSE, illusion = FALSE, stun = TRUE)
@@ -1444,11 +1447,7 @@
dna.species.on_species_gain(src)
see_in_dark = dna.species.get_resultant_darksight(src)
if(see_in_dark > 2)
see_invisible = SEE_INVISIBLE_LEVEL_ONE
else
see_invisible = SEE_INVISIBLE_LIVING
update_sight()
dna.species.handle_dna(src) //Give them whatever special dna business they got.
@@ -115,7 +115,7 @@
update_tint()
if(G.prescription)
update_nearsighted_effects()
if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view)
if(G.vision_flags || G.see_in_dark || G.invis_override || G.invis_view || !isnull(G.lighting_alpha))
update_sight()
update_inv_glasses()
update_client_colour()
@@ -128,7 +128,7 @@
// Bandanas and paper hats go on the head but are not head clothing
if(istype(I,/obj/item/clothing/head))
var/obj/item/clothing/head/hat = I
if(hat.vision_flags || hat.darkness_view || hat.helmet_goggles_invis_view)
if(hat.vision_flags || hat.see_in_dark || !isnull(hat.lighting_alpha))
update_sight()
head_update(I)
update_inv_head()
@@ -202,8 +202,8 @@
W.screen_loc = null
W.loc = src
W.equipped(src, slot)
W.layer = 20
W.plane = HUD_PLANE
W.layer = ABOVE_HUD_LAYER
W.plane = ABOVE_HUD_PLANE
switch(slot)
if(slot_back)
@@ -248,8 +248,8 @@
var/obj/item/clothing/ears/offear/O = new(W)
O.loc = src
r_ear = O
O.layer = 20
O.plane = HUD_PLANE
O.layer = ABOVE_HUD_LAYER
O.plane = ABOVE_HUD_PLANE
update_inv_ears(redraw_mob)
if(slot_r_ear)
r_ear = W
@@ -257,8 +257,8 @@
var/obj/item/clothing/ears/offear/O = new(W)
O.loc = src
l_ear = O
O.layer = 20
O.plane = HUD_PLANE
O.layer = ABOVE_HUD_LAYER
O.plane = ABOVE_HUD_PLANE
update_inv_ears(redraw_mob)
if(slot_glasses)
glasses = W
@@ -267,7 +267,7 @@
update_tint()
if(G.prescription)
update_nearsighted_effects()
if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view)
if(G.vision_flags || G.see_in_dark || G.invis_override || G.invis_view || !isnull(G.lighting_alpha))
update_sight()
update_inv_glasses(redraw_mob)
update_client_colour()
@@ -283,7 +283,7 @@
// paper + bandanas
if(istype(W, /obj/item/clothing/head))
var/obj/item/clothing/head/hat = W
if(hat.vision_flags || hat.darkness_view || hat.helmet_goggles_invis_view)
if(hat.vision_flags || hat.see_in_dark || !isnull(hat.lighting_alpha))
update_sight()
head_update(W)
update_inv_head(redraw_mob)
@@ -39,8 +39,6 @@
var/siemens_coeff = 1 //base electrocution coefficient
var/invis_sight = SEE_INVISIBLE_LIVING
var/hazard_high_pressure = HAZARD_HIGH_PRESSURE // Dangerously high pressure.
var/warning_high_pressure = WARNING_HIGH_PRESSURE // High pressure warning.
var/warning_low_pressure = WARNING_LOW_PRESSURE // Low pressure warning.
@@ -630,22 +628,18 @@ It'll return null if the organ doesn't correspond, so include null checks when u
return null
return has_organ[organ_slot]
/datum/species/proc/get_resultant_darksight(mob/living/carbon/human/H) //Returns default value of 2 if the mob doesn't have eyes, otherwise it grabs the eyes darksight.
var/resultant_darksight = 2
/datum/species/proc/update_sight(mob/living/carbon/human/H)
var/obj/item/organ/internal/eyes/eyes = H.get_int_organ(/obj/item/organ/internal/eyes)
if(eyes)
resultant_darksight = eyes.get_dark_view()
return resultant_darksight
/datum/species/proc/update_sight(mob/living/carbon/human/H)
H.sight = initial(H.sight)
H.see_in_dark = get_resultant_darksight(H)
H.see_invisible = invis_sight
if(H.see_in_dark > 2) //Preliminary see_invisible handling as per set_species() in code\modules\mob\living\carbon\human\human.dm.
H.see_invisible = SEE_INVISIBLE_LEVEL_ONE
H.sight |= eyes.vision_flags
H.see_in_dark = eyes.see_in_dark
H.see_invisible = eyes.see_invisible
H.lighting_alpha = eyes.lighting_alpha
else
H.see_invisible = SEE_INVISIBLE_LIVING
H.sight = initial(H.sight)
H.see_in_dark = initial(H.see_in_dark)
H.see_invisible = initial(H.see_invisible)
H.lighting_alpha = initial(H.lighting_alpha)
if(H.client && H.client.eye != H)
var/atom/A = H.client.eye
@@ -656,39 +650,43 @@ It'll return null if the organ doesn't correspond, so include null checks when u
if(H.mind.vampire.get_ability(/datum/vampire_passive/full))
H.sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
H.see_in_dark = 8
H.see_invisible = SEE_INVISIBLE_MINIMUM
H.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
else if(H.mind.vampire.get_ability(/datum/vampire_passive/vision))
H.sight |= SEE_MOBS
H.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
for(var/obj/item/organ/internal/cyberimp/eyes/E in H.internal_organs)
H.sight |= E.vision_flags
if(E.dark_view)
H.see_in_dark = E.dark_view
if(E.see_in_dark)
H.see_in_dark = max(H.see_in_dark, E.see_in_dark)
if(E.see_invisible)
H.see_invisible = min(H.see_invisible, E.see_invisible)
if(E.lighting_alpha)
H.lighting_alpha = min(H.lighting_alpha, E.lighting_alpha)
var/lesser_darkview_bonus = INFINITY
// my glasses, I can't see without my glasses
if(H.glasses)
var/obj/item/clothing/glasses/G = H.glasses
H.sight |= G.vision_flags
lesser_darkview_bonus = G.darkness_view
H.see_in_dark = max(G.see_in_dark, H.see_in_dark)
if(G.invis_override)
H.see_invisible = G.invis_override
else
H.see_invisible = min(G.invis_view, H.see_invisible)
if(!isnull(G.lighting_alpha))
H.lighting_alpha = min(G.lighting_alpha, H.lighting_alpha)
// better living through hat trading
if(H.head)
if(istype(H.head, /obj/item/clothing/head))
var/obj/item/clothing/head/hat = H.head
H.sight |= hat.vision_flags
H.see_in_dark = max(hat.see_in_dark, H.see_in_dark)
if(hat.darkness_view) // Pick the lowest of the two darkness_views between the glasses and helmet.
lesser_darkview_bonus = min(hat.darkness_view,lesser_darkview_bonus)
if(hat.helmet_goggles_invis_view)
H.see_invisible = min(hat.helmet_goggles_invis_view, H.see_invisible)
if(!isnull(hat.lighting_alpha))
H.lighting_alpha = min(hat.lighting_alpha, H.lighting_alpha)
if(istype(H.back, /obj/item/rig)) ///aghhh so snowflakey
var/obj/item/rig/rig = H.back
@@ -697,27 +695,27 @@ It'll return null if the organ doesn't correspond, so include null checks when u
if(rig.visor && rig.visor.vision && rig.visor.active && rig.visor.vision.glasses)
var/obj/item/clothing/glasses/G = rig.visor.vision.glasses
if(istype(G))
H.see_in_dark = (G.darkness_view ? G.darkness_view : get_resultant_darksight(H)) // Otherwise we keep our darkness view with togglable nightvision.
if(G.vision_flags) // MESONS
H.sight |= G.vision_flags
H.sight |= G.vision_flags
H.see_in_dark = max(G.see_in_dark, H.see_in_dark)
H.see_invisible = min(G.invis_view, H.see_invisible)
if(lesser_darkview_bonus != INFINITY)
H.see_in_dark = max(lesser_darkview_bonus, H.see_in_dark)
if(!isnull(G.lighting_alpha))
H.lighting_alpha = min(G.lighting_alpha, H.lighting_alpha)
if(H.vision_type)
H.see_in_dark = max(H.see_in_dark, H.vision_type.see_in_dark, get_resultant_darksight(H))
H.see_invisible = H.vision_type.see_invisible
if(H.vision_type.light_sensitive)
H.weakeyes = 1
H.sight |= H.vision_type.sight_flags
H.see_in_dark = max(H.see_in_dark, H.vision_type.see_in_dark)
if(!isnull(H.vision_type.lighting_alpha))
H.lighting_alpha = min(H.vision_type.lighting_alpha, H.lighting_alpha)
if(H.vision_type.light_sensitive)
H.weakeyes = TRUE
if(XRAY in H.mutations)
H.sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS)
if(H.see_override) //Override all
H.see_invisible = H.see_override
H.sync_lighting_plane_alpha()
/datum/species/proc/water_act(mob/living/carbon/human/M, volume, temperature, source)
if(abs(temperature - M.bodytemperature) > 10) //If our water and mob temperature varies by more than 10K, cool or/ heat them appropriately
-30
View File
@@ -343,36 +343,6 @@
Sleeping(2)
return sleeping
/mob/living/carbon/update_sight()
if(!client)
return
if(stat == DEAD)
grant_death_vision()
return
see_invisible = initial(see_invisible)
see_in_dark = initial(see_in_dark)
sight = initial(sight)
if(XRAY in mutations)
grant_xray_vision()
if(client.eye != src)
var/atom/A = client.eye
if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates.
return
for(var/obj/item/organ/internal/cyberimp/eyes/E in internal_organs)
sight |= E.vision_flags
if(E.dark_view)
see_in_dark = max(see_in_dark,E.dark_view)
if(E.see_invisible)
see_invisible = min(see_invisible, E.see_invisible)
if(see_override)
see_invisible = see_override
/mob/living/carbon/handle_hud_icons()
return
+2 -15
View File
@@ -206,28 +206,15 @@
if(!remote_view && !client.adminobs)
reset_perspective(null)
/mob/living/proc/update_sight()
if(stat == DEAD)
grant_death_vision()
return
// Gives a mob the vision of being dead
/mob/living/proc/grant_death_vision()
sight |= SEE_TURFS
sight |= SEE_MOBS
sight |= SEE_OBJS
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
see_in_dark = 8
see_invisible = SEE_INVISIBLE_OBSERVER
// See through walls, dark, etc.
// basically the same as death vision except you can't
// see ghosts
/mob/living/proc/grant_xray_vision()
sight |= SEE_TURFS
sight |= SEE_MOBS
sight |= SEE_OBJS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_LEVEL_TWO
sync_lighting_plane_alpha()
/mob/living/proc/handle_hud_icons()
handle_hud_icons_health()
+36
View File
@@ -1013,3 +1013,39 @@
for(var/atom/A in src)
if(A.light_range > 0)
A.extinguish_light()
/mob/living/vv_edit_var(var_name, var_value)
switch(var_name)
if("stat")
if((stat == DEAD) && (var_value < DEAD))//Bringing the dead back to life
GLOB.dead_mob_list -= src
GLOB.living_mob_list += src
if((stat < DEAD) && (var_value == DEAD))//Kill he
GLOB.living_mob_list -= src
GLOB.dead_mob_list += src
. = ..()
switch(var_name)
if("weakened")
SetWeakened(var_value)
if("stunned")
SetStunned(var_value)
if("paralysis")
SetParalysis(var_value)
if("sleeping")
SetSleeping(var_value)
if("maxHealth")
updatehealth()
if("resize")
update_transform()
if("lighting_alpha")
sync_lighting_plane_alpha()
/mob/living/update_sight()
if(!client)
return
if(stat == DEAD)
grant_death_vision()
return
. = ..()
@@ -33,7 +33,6 @@
var/mob_size = MOB_SIZE_HUMAN
var/metabolism_efficiency = 1 //more or less efficiency to metabolize helpful/harmful reagents and regulate body temperature..
var/digestion_ratio = 1 //controls how quickly reagents metabolize; largely governered by species attributes.
var/nightvision = 0
var/bloodcrawl = 0 //0 No blood crawling, 1 blood crawling, 2 blood crawling+mob devour
var/holder = null //The holder for blood crawling
+24 -1
View File
@@ -1290,4 +1290,27 @@ var/list/ai_verbs_default = list(
return FALSE
/mob/living/silicon/ai/ExtinguishMob()
return
return
/mob/living/silicon/ai/update_sight()
if(!client)
return
if(stat == DEAD)
grant_death_vision()
return
see_invisible = initial(see_invisible)
see_in_dark = initial(see_in_dark)
lighting_alpha = initial(lighting_alpha)
sight = initial(sight)
if(aiRestorePowerRoutine)
sight = sight &~ SEE_TURFS
sight = sight &~ SEE_MOBS
sight = sight &~ SEE_OBJS
see_in_dark = 0
SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT)
sync_lighting_plane_alpha()
@@ -116,7 +116,8 @@
var/turf/t = turf
if(obscuredTurfs[t])
if(!t.obscured)
t.obscured = image('icons/effects/cameravis.dmi', t, null, 15)
t.obscured = image('icons/effects/cameravis.dmi', t, null, BYOND_LIGHTING_LAYER + 0.1)
t.obscured.plane = BYOND_LIGHTING_PLANE + 1
obscured += t.obscured
for(var/eye in seenby)
@@ -169,7 +170,8 @@
for(var/turf in obscuredTurfs)
var/turf/t = turf
if(!t.obscured)
t.obscured = image('icons/effects/cameravis.dmi', t, "black", 15)
t.obscured = image('icons/effects/cameravis.dmi', t, "black", BYOND_LIGHTING_LAYER + 0.1)
t.obscured.plane = BYOND_LIGHTING_PLANE + 1
obscured += t.obscured
#undef UPDATE_BUFFER
#undef UPDATE_BUFFER
@@ -152,16 +152,3 @@
/mob/living/silicon/ai/rejuvenate()
..()
add_ai_verbs(src)
/mob/living/silicon/ai/update_sight()
see_invisible = initial(see_invisible)
see_in_dark = initial(see_in_dark)
sight = initial(sight)
if(aiRestorePowerRoutine)
sight = sight&~SEE_TURFS
sight = sight&~SEE_MOBS
sight = sight&~SEE_OBJS
see_in_dark = 0
if(see_override)
see_invisible = see_override
@@ -55,24 +55,24 @@
if(!module_state_1)
O.mouse_opacity = initial(O.mouse_opacity)
module_state_1 = O
O.layer = 20
O.plane = HUD_PLANE
O.layer = ABOVE_HUD_LAYER
O.plane = ABOVE_HUD_PLANE
O.screen_loc = inv1.screen_loc
contents += O
set_actions(O)
else if(!module_state_2)
O.mouse_opacity = initial(O.mouse_opacity)
module_state_2 = O
O.layer = 20
O.plane = HUD_PLANE
O.layer = ABOVE_HUD_LAYER
O.plane = ABOVE_HUD_PLANE
O.screen_loc = inv2.screen_loc
contents += O
set_actions(O)
else if(!module_state_3)
O.mouse_opacity = initial(O.mouse_opacity)
module_state_3 = O
O.layer = 20
O.plane = HUD_PLANE
O.layer = ABOVE_HUD_LAYER
O.plane = ABOVE_HUD_PLANE
O.screen_loc = inv3.screen_loc
contents += O
set_actions(O)
@@ -88,40 +88,6 @@
return 1
/mob/living/silicon/robot/update_sight()
if(!client)
return
if(stat == DEAD)
grant_death_vision()
return
see_invisible = initial(see_invisible)
see_in_dark = initial(see_in_dark)
sight = initial(sight)
if(client.eye != src)
var/atom/A = client.eye
if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates.
return
if(sight_mode & BORGMESON)
sight |= SEE_TURFS
see_invisible = min(see_invisible, SEE_INVISIBLE_MINIMUM)
see_in_dark = 1
if(sight_mode & BORGXRAY)
sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS)
see_invisible = SEE_INVISIBLE_LIVING
see_in_dark = 8
if(sight_mode & BORGTHERM)
sight |= SEE_MOBS
see_invisible = min(see_invisible, SEE_INVISIBLE_LIVING)
see_in_dark = 8
if(see_override)
see_invisible = see_override
/mob/living/silicon/robot/handle_hud_icons()
update_items()
update_cell()
+38 -1
View File
@@ -114,7 +114,9 @@ var/list/robot_verbs_default = list(
robot_modules_background = new()
robot_modules_background.icon_state = "block"
robot_modules_background.layer = 19 //Objects that appear on screen are on layer 20, UI should be just below it.
robot_modules_background.layer = HUD_LAYER //Objects that appear on screen are on layer 20, UI should be just below it.
robot_modules_background.plane = HUD_PLANE
ident = rand(1, 999)
rename_character(null, get_default_name())
update_icons()
@@ -1392,3 +1394,38 @@ var/list/robot_verbs_default = list(
/mob/living/silicon/robot/check_ear_prot()
return ear_protection
/mob/living/silicon/robot/update_sight()
if(!client)
return
if(stat == DEAD)
grant_death_vision()
return
see_invisible = initial(see_invisible)
see_in_dark = initial(see_in_dark)
sight = initial(sight)
lighting_alpha = initial(lighting_alpha)
if(client.eye != src)
var/atom/A = client.eye
if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates.
return
if(sight_mode & BORGMESON)
sight |= SEE_TURFS
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
if(sight_mode & BORGXRAY)
sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS)
see_invisible = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
see_in_dark = 8
if(sight_mode & BORGTHERM)
sight |= SEE_MOBS
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT)
sync_lighting_plane_alpha()
@@ -168,7 +168,7 @@
melee_damage_lower = 25
melee_damage_upper = 25
attacktext = "slashes"
see_in_dark = 7
see_in_dark = 8
attack_sound = 'sound/weapons/bladeslice.ogg'
const_type = "wraith"
construct_spells = list(/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift)
@@ -30,7 +30,7 @@
status_flags = CANPUSH
minbodytemp = 0
see_in_dark = 8
see_invisible = SEE_INVISIBLE_MINIMUM
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
gold_core_spawnable = CHEM_MOB_SPAWN_HOSTILE
death_sound = 'sound/voice/hiss6.ogg'
deathmessage = "lets out a waning guttural screech, green blood bubbling from its maw..."
@@ -16,7 +16,8 @@
emote_hear = list("chitters")
speak_chance = 5
turns_per_move = 5
see_in_dark = 10
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
butcher_results = list(/obj/item/reagent_containers/food/snacks/spidermeat = 2, /obj/item/reagent_containers/food/snacks/spiderleg = 8)
response_help = "pets"
response_disarm = "gently pushes aside"
@@ -16,7 +16,7 @@
var/throw_message = "bounces off of"
var/icon_aggro = null // for swapping to when we get aggressive
see_in_dark = 8
see_invisible = SEE_INVISIBLE_MINIMUM
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
mob_size = MOB_SIZE_LARGE
/mob/living/simple_animal/hostile/asteroid/Aggro()
@@ -33,14 +33,14 @@
animate_movement = NO_STEPS // Do not animate movement, you jump around as you're a scary statue.
see_in_dark = 13
see_in_dark = 8
vision_range = 12
aggro_vision_range = 12
idle_vision_range = 12
search_objects = 1 // So that it can see through walls
see_invisible = SEE_INVISIBLE_OBSERVER_NOLIGHTING
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
sight = SEE_SELF|SEE_MOBS|SEE_OBJS|SEE_TURFS
move_force = MOVE_FORCE_EXTREMELY_STRONG
move_resist = MOVE_FORCE_EXTREMELY_STRONG
@@ -104,7 +104,7 @@
return null
// Check for darkness
var/turf/T = get_turf(loc)
if(T && destination && T.lighting_overlay)
if(T && destination && T.lighting_object)
if(T.get_lumcount() * 10 < 1 && destination.get_lumcount() * 10 < 1) // No one can see us in the darkness, right?
return null
if(T == destination)
@@ -189,13 +189,6 @@
L.EyeBlind(4)
return
/mob/living/simple_animal/hostile/statue/update_sight()
if(!client)
return
if(stat == DEAD)
grant_death_vision()
return
//Toggle Night Vision
/obj/effect/proc_holder/spell/targeted/night_vision
name = "Toggle Nightvision"
@@ -207,15 +200,23 @@
message = "<span class='notice'>You toggle your night vision!</span>"
range = -1
include_user = 1
var/non_night_vision = SEE_INVISIBLE_LIVING
var/night_vision = SEE_INVISIBLE_OBSERVER_NOLIGHTING
/obj/effect/proc_holder/spell/targeted/night_vision/cast(list/targets, mob/user = usr)
for(var/mob/living/target in targets)
if(target.see_invisible == non_night_vision)
target.see_invisible = night_vision
else
target.see_invisible = non_night_vision
switch(target.lighting_alpha)
if (LIGHTING_PLANE_ALPHA_VISIBLE)
target.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
name = "Toggle Nightvision \[More]"
if (LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE)
target.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
name = "Toggle Nightvision \[Full]"
if (LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE)
target.lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE
name = "Toggle Nightvision \[OFF]"
else
target.lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
name = "Toggle Nightvision \[ON]"
target.update_sight()
/mob/living/simple_animal/hostile/statue/sentience_act()
faction -= "neutral"
@@ -94,9 +94,8 @@ var/global/list/ts_spiderling_list = list()
// Vision
idle_vision_range = 10
aggro_vision_range = 10
see_in_dark = 10
nightvision = 1
see_invisible = 5
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
sight = SEE_MOBS
// AI aggression settings
@@ -543,8 +543,8 @@
W.forceMove(src)
W.equipped(src, slot)
W.layer = 20
W.plane = HUD_PLANE
W.layer = ABOVE_HUD_LAYER
W.plane = ABOVE_HUD_PLANE
switch(slot)
if(slot_collar)
@@ -575,22 +575,6 @@
can_have_ai = FALSE
return
/mob/living/simple_animal/update_sight()
if(!client)
return
if(stat == DEAD)
grant_death_vision()
return
see_invisible = initial(see_invisible)
see_in_dark = initial(see_in_dark)
sight = initial(sight)
if(client.eye != src)
var/atom/A = client.eye
if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates.
return
/mob/living/simple_animal/can_hear()
. = TRUE
+11 -1
View File
@@ -930,7 +930,7 @@ var/list/slot_equipment_priority = list( \
// They should be in a cell or the Brig portion of the shuttle.
var/area/A = loc.loc
if(!istype(A, /area/security/prison) && !istype(A, /area/prison))
if(!istype(A, /area/security/prison))
if(!istype(A, /area/shuttle/escape) || loc.name != "Brig floor")
return 0
@@ -1347,3 +1347,13 @@ var/list/slot_equipment_priority = list( \
/mob/proc/is_literate()
return FALSE
/mob/proc/update_sight()
SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT)
sync_lighting_plane_alpha()
/mob/proc/sync_lighting_plane_alpha()
if(hud_used)
var/obj/screen/plane_master/lighting/L = hud_used.plane_masters["[LIGHTING_PLANE]"]
if (L)
L.alpha = lighting_alpha
+3 -4
View File
@@ -1,6 +1,6 @@
/mob
density = 1
layer = 4.0
layer = MOB_LAYER
animate_movement = 2
pressure_resistance = 8
dont_save = TRUE //to avoid it messing up in buildmode saving
@@ -83,7 +83,6 @@
var/obj/item/clothing/mask/wear_mask = null//Carbon
var/seer = 0 //for cult//Carbon, probably Human
var/see_override = 0
var/datum/hud/hud_used = null
@@ -93,7 +92,7 @@
var/list/grabbed_by = list()
var/list/requests = list()
var/lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
var/list/mapobjs = list()
var/in_throw_mode = 0
@@ -177,7 +176,7 @@
var/player_ghosted = 0
var/turf/listed_turf = null //the current turf being examined in the stat panel
var/list/shouldnt_see = list(/atom/movable/lighting_overlay) //list of objects that this mob shouldn't see in the stat panel. this silliness is needed because of AI alt+click and cult blood runes
var/list/shouldnt_see = list(/atom/movable/lighting_object) //list of objects that this mob shouldn't see in the stat panel. this silliness is needed because of AI alt+click and cult blood runes
var/kills = 0
+4 -4
View File
@@ -334,15 +334,15 @@
else if(h_user.l_store == src)
h_user.unEquip(src)
B.loc = h_user
B.layer = 20
B.plane = HUD_PLANE
B.layer = ABOVE_HUD_LAYER
B.plane = ABOVE_HUD_PLANE
h_user.l_store = B
h_user.update_inv_pockets()
else if(h_user.r_store == src)
h_user.unEquip(src)
B.loc = h_user
B.layer = 20
B.plane = HUD_PLANE
B.layer = ABOVE_HUD_LAYER
B.plane = ABOVE_HUD_PLANE
h_user.r_store = B
h_user.update_inv_pockets()
else if(h_user.head == src)
+1 -1
View File
@@ -35,7 +35,7 @@ By design, d1 is the smallest direction and d2 is the highest
icon_state = "0-1"
var/d1 = 0
var/d2 = 1
layer = 2.44 //Just below unary stuff, which is at 2.45 and above pipes, which are at 2.4
layer = WIRE_LAYER //Just below unary stuff, which is at 2.45 and above pipes, which are at 2.4
color = COLOR_RED
/obj/structure/cable/yellow
@@ -604,6 +604,32 @@
M.emote("laugh")
return list(effect, update_flags)
/datum/reagent/rotatium //Rotatium. Fucks up your rotation and is hilarious
name = "Rotatium"
id = "rotatium"
description = "A constantly swirling, oddly colourful fluid. Causes the consumer's sense of direction and hand-eye coordination to become wild."
reagent_state = LIQUID
color = "#AC88CA" //RGB: 172, 136, 202
metabolization_rate = 0.6 * REAGENTS_METABOLISM
taste_message = "spinning"
/datum/reagent/rotatium/on_mob_life(mob/living/carbon/M)
if(M.hud_used)
if(current_cycle >= 20 && current_cycle % 20 == 0)
var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"])
var/rotation = min(round(current_cycle / 20), 89) // By this point the player is probably puking and quitting anyway
for(var/whole_screen in screens)
animate(whole_screen, transform = matrix(rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING, loop = -1)
animate(transform = matrix(-rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING)
return ..()
/datum/reagent/rotatium/on_mob_delete(mob/living/M)
if(M && M.hud_used)
var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"])
for(var/whole_screen in screens)
animate(whole_screen, transform = matrix(), time = 5, easing = QUAD_EASING)
..()
//////////////////////////////
// Synth-Drugs //
//////////////////////////////
@@ -109,7 +109,7 @@
if(!(istype(B) && B.off_floor))
qdel(O)
else
if(!istype(O, /atom/movable/lighting_overlay))
if(!istype(O, /atom/movable/lighting_object))
O.color = initial(O.color)
O.clean_blood()
@@ -174,4 +174,11 @@
required_reagents = list("formaldehyde" = 1, "sodium" = 1, "chlorine" = 1, "lithium" = 1)
result_amount = 4
mix_message = "The mixture thins and loses all color."
mix_sound = 'sound/goonstation/misc/drinkfizz.ogg'
mix_sound = 'sound/goonstation/misc/drinkfizz.ogg'
/datum/chemical_reaction/rotatium
name = "Rotatium"
id = "Rotatium"
result = "rotatium"
required_reagents = list("lsd" = 1, "teslium" = 1, "methamphetamine" = 1)
mix_message = "<span class='danger'>After sparks, fire, and the smell of LSD, the mix is constantly spinning with no stop in sight.</span>"
+1 -1
View File
@@ -680,7 +680,7 @@
dir = 0 // dir will contain dominant direction for junction pipes
var/health = 10 // health points 0-10
armor = list("melee" = 25, "bullet" = 10, "laser" = 10, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100)
layer = 2.3 // slightly lower than wires and other pipes
layer = DISPOSAL_PIPE_LAYER // slightly lower than wires and other pipes
var/base_icon_state // initial icon state on map
// new pipe, set the icon_state as on map
+6 -6
View File
@@ -3,18 +3,18 @@
/area/ruin/
name = "\improper Unexplored Location"
icon_state = "away"
has_gravity = 1
there_can_be_many = 1
has_gravity = TRUE
there_can_be_many = TRUE
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
/area/ruin/unpowered
always_unpowered = 0
always_unpowered = FALSE
/area/ruin/unpowered/no_grav
has_gravity = 0
has_gravity = FALSE
/area/ruin/powered
requires_power = 0
requires_power = FALSE
@@ -291,6 +291,8 @@
/mob/camera/aiEye/remote/shuttle_docker/update_remote_sight(mob/living/user)
user.sight = SEE_TURFS
..()
return TRUE
/datum/action/innate/shuttledocker_rotate
+2 -4
View File
@@ -8,9 +8,6 @@
forceMove(T1)
return 1
/atom/movable/lighting_overlay/onShuttleMove()
return 0
/obj/effect/landmark/shuttle_import/onShuttleMove()
// Used for marking where to preview/load shuttles
return 0
@@ -60,4 +57,5 @@
/obj/machinery/door/airlock/postDock(obj/docking_port/stationary/S1)
. = ..()
if(!S1.lock_shuttle_doors && id_tag == "s_docking_airlock")
INVOKE_ASYNC(src, .proc/unlock)
INVOKE_ASYNC(src, .proc/unlock)
+3 -8
View File
@@ -442,11 +442,6 @@
if(canMove())
return -1
// //rotate transit docking ports, so we don't need zillions of variants
// if(istype(S1, /obj/docking_port/stationary/transit))
// S1.dir = turn(NORTH, -travelDir)
var/obj/docking_port/stationary/S0 = get_docked()
var/turf_type = /turf/space
var/area_type = /area/space
@@ -467,8 +462,6 @@
rotation += (rotation % 90) //diagonal rotations not allowed, round up
rotation = SimplifyDegrees(rotation)
//remove area surrounding docking port
if(areaInstance.contents.len)
var/area/A0 = locate("[area_type]")
@@ -506,10 +499,12 @@
if(rotation)
T1.shuttleRotate(rotation)
//lighting stuff
//atmos and lighting stuff
SSair.remove_from_active(T1)
T1.CalculateAdjacentTurfs()
SSair.add_to_active(T1,1)
T1.lighting_build_overlay()
T0.ChangeTurf(turf_type)
+1 -13
View File
@@ -58,7 +58,7 @@
var/contcount
for(var/atom/A in T.contents)
if(istype(A,/atom/movable/lighting_overlay))
if(istype(A,/atom/movable/lighting_object))
continue
if(istype(A,/obj/machinery/light))
continue //hacky but whatever, shuttles need three spots each for this shit
@@ -750,18 +750,6 @@
frequency.post_signal(src, status_signal)
/**********
MISC
**********/
/area/supply/station
name = "Supply Shuttle"
icon_state = "shuttle3"
requires_power = 0
/area/supply/dock
name = "Supply Shuttle"
icon_state = "shuttle3"
requires_power = 0
#undef ORDER_SCREEN_WIDTH
#undef ORDER_SCREEN_HEIGHT
+7 -4
View File
@@ -8,8 +8,10 @@
w_class = WEIGHT_CLASS_TINY
var/vision_flags = 0
var/dark_view = 0
var/see_in_dark = 0
var/see_invisible = 0
var/lighting_alpha
var/eye_colour = "#000000"
var/old_eye_colour = "#000000"
var/flash_protect = 0
@@ -54,7 +56,7 @@
implant_color = "#AEFF00"
origin_tech = "materials=4;engineering=4;biotech=4;magnets=4"
vision_flags = SEE_TURFS
see_invisible = SEE_INVISIBLE_MINIMUM
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
aug_message = "Suddenly, you realize how much of a mess the station really is..."
/obj/item/organ/internal/cyberimp/eyes/xray
@@ -63,8 +65,8 @@
implant_color = "#000000"
origin_tech = "materials=4;programming=4;biotech=6;magnets=4"
vision_flags = SEE_MOBS | SEE_OBJS | SEE_TURFS
dark_view = 8
see_invisible = SEE_INVISIBLE_MINIMUM
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
/obj/item/organ/internal/cyberimp/eyes/thermals
name = "Thermals implant"
@@ -72,6 +74,7 @@
eye_colour = "#FFCC00"
implant_color = "#FFCC00"
vision_flags = SEE_MOBS
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE
flash_protect = -1
origin_tech = "materials=5;programming=4;biotech=4;magnets=4;syndicate=1"
aug_message = "You see prey everywhere you look..."
+7 -6
View File
@@ -10,9 +10,13 @@
var/list/colourblind_matrix = MATRIX_GREYSCALE //Special colourblindness parameters. By default, it's black-and-white.
var/list/replace_colours = LIST_GREYSCALE_REPLACE
var/dependent_disabilities = null //Gets set by eye-dependent disabilities such as colourblindness so the eyes can transfer the disability during transplantation.
var/dark_view = 2 //Default dark_view for Humans.
var/weld_proof = null //If set, the eyes will not take damage during welding. eg. IPC optical sensors do not take damage when they weld things while all other eyes will.
var/vision_flags = 0
var/see_in_dark = 2
var/see_invisible = SEE_INVISIBLE_LIVING
var/lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE
/obj/item/organ/internal/eyes/proc/update_colour()
dna.write_eyes_attributes(src)
@@ -31,11 +35,8 @@
else
return colourmatrix
/obj/item/organ/internal/eyes/proc/get_dark_view() //Returns dark_view (if the eyes are organic) for see_invisible handling in species.dm to be autoprocessed by life().
return dark_view
/obj/item/organ/internal/eyes/proc/shine()
if(is_robotic() || (dark_view > EYE_SHINE_THRESHOLD))
if(is_robotic() || (see_in_dark > EYE_SHINE_THRESHOLD))
return TRUE
/obj/item/organ/internal/eyes/insert(mob/living/carbon/human/M, special = 0)
@@ -70,7 +71,7 @@
colourmatrix = null
..() //Make sure the organ's got the robotic status indicators before updating the client colour.
if(owner)
owner.update_client_colour(0) //Since mechanical eyes give dark_view of 2 and full colour vision atm, just having this here is fine.
owner.update_client_colour(0) //Since mechanical eyes give see_in_dark of 2 and full colour vision atm, just having this here is fine.
/obj/item/organ/internal/eyes/cybernetic
name = "cybernetic eyes"
@@ -4,4 +4,4 @@
/obj/item/organ/internal/eyes/abductor
name = "abductor eyeballs"
dark_view = 3
see_in_dark = 3
@@ -26,4 +26,4 @@
name = "drask eyeballs"
icon = 'icons/obj/species_organs/drask.dmi'
desc = "Drask eyes. They look even stranger disembodied"
dark_view = 5
see_in_dark = 5
+1 -1
View File
@@ -23,7 +23,7 @@
name = "grey eyeballs"
desc = "They still look creepy and emotionless"
icon = 'icons/obj/species_organs/grey.dmi'
dark_view = 5
see_in_dark = 5
/obj/item/organ/internal/heart/grey
name = "grey heart"
@@ -1,3 +1,3 @@
/obj/item/organ/internal/eyes/shadow
name = "dark orbs"
dark_view = 8
see_in_dark = 8
@@ -8,12 +8,12 @@
name = "tajaran eyeballs"
colourblind_matrix = MATRIX_TAJ_CBLIND //The colour matrix and darksight parameters that the mob will recieve when they get the disability.
replace_colours = LIST_TAJ_REPLACE
dark_view = 8
see_in_dark = 8
/obj/item/organ/internal/eyes/tajaran/farwa //Being the lesser form of Tajara, Farwas have an utterly incurable version of their colourblindness.
name = "farwa eyeballs"
colourmatrix = MATRIX_TAJ_CBLIND
dark_view = 8
see_in_dark = 8
replace_colours = LIST_TAJ_REPLACE
/obj/item/organ/internal/heart/tajaran
@@ -7,7 +7,7 @@
/obj/item/organ/internal/eyes/unathi
name = "unathi eyeballs"
icon = 'icons/obj/species_organs/unathi.dmi'
dark_view = 3
see_in_dark = 3
/obj/item/organ/internal/heart/unathi
name = "unathi heart"
@@ -8,12 +8,12 @@
icon = 'icons/obj/species_organs/vulpkanin.dmi'
colourblind_matrix = MATRIX_VULP_CBLIND //The colour matrix and darksight parameters that the mob will recieve when they get the disability.
replace_colours = LIST_VULP_REPLACE
dark_view = 8
see_in_dark = 8
/obj/item/organ/internal/eyes/vulpkanin/wolpin //Being the lesser form of Vulpkanin, Wolpins have an utterly incurable version of their colourblindness.
name = "wolpin eyeballs"
colourmatrix = MATRIX_VULP_CBLIND
dark_view = 8
see_in_dark = 8
replace_colours = LIST_VULP_REPLACE
/obj/item/organ/internal/heart/vulpkanin
+1 -1
View File
@@ -8,4 +8,4 @@
slot = "hivenode"
/obj/item/organ/internal/eyes/wryn
dark_view = 3
see_in_dark = 3
+1 -1
View File
@@ -22,7 +22,7 @@
var/delay_timer = null
var/list/blacklist = list(/obj/tram/rail,/atom/movable/lighting_overlay)
var/list/blacklist = list(/obj/tram/rail,/atom/movable/lighting_object)
var/list/ancwhitelist = list(/obj/tram, /obj/vehicle, /obj/structure/chair, /obj/structure/grille, /obj/structure/window)
/obj/tram/tram_controller/New()