mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-14 00:23:29 +01:00
Merge pull request #11357 from Markolie/lighting
Lighting system update
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.",
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 ..()
|
||||
@@ -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
|
||||
|
||||
@@ -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 ..()
|
||||
@@ -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)
|
||||
. = ..()
|
||||
@@ -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 ..()
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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."
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>"
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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..."
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -8,4 +8,4 @@
|
||||
slot = "hivenode"
|
||||
|
||||
/obj/item/organ/internal/eyes/wryn
|
||||
dark_view = 3
|
||||
see_in_dark = 3
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user