Merge branch 'dev' of https://github.com/Baystation12/Baystation12 into newmalf-merge

This commit is contained in:
Atlantis
2015-05-11 07:46:51 +02:00
213 changed files with 3665 additions and 3634 deletions

View File

@@ -277,6 +277,13 @@ var/global/floorIsLava = 0
var/dat = "<html><head><title>Info on [key]</title></head>"
dat += "<body>"
var/p_age = "unknown"
for(var/client/C in clients)
if(C.ckey == key)
p_age = C.player_age
break
dat +="<span style='color:#000000; font-weight: bold'>Player age: [p_age]</span><br>"
var/savefile/info = new("data/player_saves/[copytext(key, 1, 2)]/[key]/info.sav")
var/list/infos
info >> infos

View File

@@ -110,7 +110,8 @@ var/list/admin_verbs_fun = list(
/client/proc/cmd_admin_add_random_ai_law,
/client/proc/make_sound,
/client/proc/toggle_random_events,
/client/proc/editappear
/client/proc/editappear,
/client/proc/roll_dices
)
var/list/admin_verbs_spawn = list(
/datum/admins/proc/spawn_fruit,
@@ -255,6 +256,7 @@ var/list/admin_verbs_hideable = list(
/client/proc/cmd_debug_tog_aliens,
/client/proc/air_report,
/client/proc/enable_debug_verbs,
/client/proc/roll_dices,
/proc/possess,
/proc/release
)

View File

@@ -13,7 +13,7 @@
display_name = holder.fakekey
for(var/mob/M in mob_list)
if((M.mind && M.mind.special_role && M.client) || (M.client && M.client.holder))
if((M.mind && M.mind.special_role && M.client) || check_rights(R_ADMIN, 0, M))
M << "<font color='#960018'><span class='ooc'>" + create_text_tag("aooc", "Antag-OOC:", M.client) + " <EM>[display_name]:</EM> <span class='message'>[msg]</span></span></font>"
log_ooc("(ANTAG) [key] : [msg]")

View File

@@ -525,6 +525,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
//log_admin("[key_name(src)] has alienized [M.key].")
var/list/dresspacks = list(
"strip",
"job",
"standard space gear",
"tournament standard red",
"tournament standard green",
@@ -555,10 +556,25 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
for (var/obj/item/I in M)
if (istype(I, /obj/item/weapon/implant))
continue
qdel(I)
M.drop_from_inventory(I)
if(I.loc != M)
qdel(I)
switch(dresscode)
if ("strip")
//do nothing
if ("job")
var/selected_job = input("Select job", "Robust quick dress shop") as null|anything in joblist
if (isnull(selected_job))
return
var/datum/job/job = job_master.GetJob(selected_job)
if(!job)
return
job.equip(M)
job.apply_fingerprints(M)
job_master.spawnId(M, selected_job)
if ("standard space gear")
M.equip_to_slot_or_del(new /obj/item/clothing/shoes/black(M), slot_shoes)

View File

@@ -0,0 +1,24 @@
/client/proc/roll_dices()
set category = "Fun"
set name = "Roll Dice"
if(!check_rights(R_FUN))
return
var/sum = input("How many times should we throw?") as num
var/side = input("Select the number of sides.") as num
if(!side)
side = 6
if(!sum)
sum = 2
var/dice = num2text(sum) + "d" + num2text(side)
if(alert("Do you want to inform the world about your game?",,"Yes", "No") == "Yes")
world << "<h2 style=\"color:#A50400\">The dice have been rolled by Gods!</h2>"
var/result = roll(dice)
if(alert("Do you want to inform the world about the result?",,"Yes", "No") == "Yes")
world << "<h2 style=\"color:#A50400\">Gods rolled [dice], result is [result]</h2>"
message_admins("[key_name_admin(src)] rolled dice [dice], result is [result]", 1)

View File

@@ -208,8 +208,8 @@
O.vars[variable]) as num|null
if(new_value == null) return
if(variable=="luminosity")
O.SetLuminosity(new_value)
if(variable=="light_range")
O.set_light(new_value)
else
O.vars[variable] = new_value
@@ -217,24 +217,24 @@
if(istype(O, /mob))
for(var/mob/M in mob_list)
if ( istype(M , O.type) )
if(variable=="luminosity")
M.SetLuminosity(new_value)
if(variable=="light_range")
M.set_light(new_value)
else
M.vars[variable] = O.vars[variable]
else if(istype(O, /obj))
for(var/obj/A in world)
if ( istype(A , O.type) )
if(variable=="luminosity")
A.SetLuminosity(new_value)
if(variable=="light_range")
A.set_light(new_value)
else
A.vars[variable] = O.vars[variable]
else if(istype(O, /turf))
for(var/turf/A in world)
if ( istype(A , O.type) )
if(variable=="luminosity")
A.SetLuminosity(new_value)
if(variable=="light_range")
A.set_light(new_value)
else
A.vars[variable] = O.vars[variable]
@@ -242,24 +242,24 @@
if(istype(O, /mob))
for(var/mob/M in mob_list)
if (M.type == O.type)
if(variable=="luminosity")
M.SetLuminosity(new_value)
if(variable=="light_range")
M.set_light(new_value)
else
M.vars[variable] = O.vars[variable]
else if(istype(O, /obj))
for(var/obj/A in world)
if (A.type == O.type)
if(variable=="luminosity")
A.SetLuminosity(new_value)
if(variable=="light_range")
A.set_light(new_value)
else
A.vars[variable] = O.vars[variable]
else if(istype(O, /turf))
for(var/turf/A in world)
if (A.type == O.type)
if(variable=="luminosity")
A.SetLuminosity(new_value)
if(variable=="light_range")
A.set_light(new_value)
else
A.vars[variable] = O.vars[variable]
@@ -372,4 +372,4 @@
A.vars[variable] = O.vars[variable]
log_admin("[key_name(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]")
message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]", 1)
message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]", 1)

View File

@@ -455,10 +455,10 @@ var/list/forbidden_varedit_object_types = list(
O.vars[variable] = var_new
if("num")
if(variable=="luminosity")
if(variable=="light_range")
var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num
if(var_new == null) return
O.SetLuminosity(var_new)
O.set_light(var_new)
else if(variable=="stat")
var/var_new = input("Enter new number:","Num",O.vars[variable]) as null|num
if(var_new == null) return

View File

@@ -18,6 +18,7 @@
var/list/sources = new() //List of sources triggering the alarm. Used to determine when the alarm should be cleared.
var/list/sources_assoc = new() //Associative list of source triggers. Used to efficiently acquire the alarm source.
var/list/cameras //List of cameras that can be switched to, if the player has that capability.
var/cache_id //ID for camera cache, changed by invalidateCameraCache().
var/area/last_area //The last acquired area, used should origin be lost (for example a destroyed borg containing an alarming camera).
var/area/last_name //The last acquired name, used should origin be lost
var/area/last_camera_area //The last area in which cameras where fetched, used to see if the camera list should be updated.
@@ -74,8 +75,12 @@
return last_name
/datum/alarm/proc/cameras()
// reset camera cache
if(camera_cache_id != cache_id)
cameras = null
cache_id = camera_cache_id
// If the alarm origin has changed area, for example a borg containing an alarming camera, reset the list of cameras
if(cameras && (last_camera_area != alarm_area()))
else if(cameras && (last_camera_area != alarm_area()))
cameras = null
// The list of cameras is also reset by /proc/invalidateCameraCache()
@@ -96,18 +101,17 @@
* Assisting procs *
******************/
/atom/proc/get_alarm_area()
var/area/A = get_area(src)
return A.master
return get_area(src)
/area/get_alarm_area()
return src.master
return src
/atom/proc/get_alarm_name()
var/area/A = get_area(src)
return A.master.name
return A.name
/area/get_alarm_name()
return master.name
return name
/mob/get_alarm_name()
return name

View File

@@ -84,8 +84,7 @@
return src
/turf/get_alarm_origin()
var/area/area = get_area(src)
return area.master // Very important to get area.master, as dynamic lightning can and will split areas.
return get_area(src)
/datum/alarm_handler/proc/register(var/object, var/procName)
listeners[object] = procName

View File

@@ -1447,7 +1447,7 @@ datum/preferences
rlimb_data[limb] = choice
organ_data[limb] = "cyborg"
if(second_limb)
organ_data[second_limb] = choice
rlimb_data[second_limb] = choice
organ_data[second_limb] = "cyborg"
if(third_limb && organ_data[third_limb] == "amputated")
organ_data[third_limb] = null

View File

@@ -264,37 +264,19 @@ BLIND // can't see anything
return
on = !on
user << "You [on ? "enable" : "disable"] the helmet light."
update_light(user)
update_flashlight(user)
else
return ..(user)
/obj/item/clothing/head/proc/update_light(var/mob/user = null)
/obj/item/clothing/head/proc/update_flashlight(var/mob/user = null)
if(on && !light_applied)
if(loc == user)
user.SetLuminosity(user.luminosity + brightness_on)
SetLuminosity(brightness_on)
set_light(brightness_on)
light_applied = 1
else if(!on && light_applied)
if(loc == user)
user.SetLuminosity(user.luminosity - brightness_on)
SetLuminosity(0)
set_light(0)
light_applied = 0
update_icon(user)
/obj/item/clothing/head/equipped(mob/user)
..()
spawn(1)
if(on && loc == user && !light_applied)
user.SetLuminosity(user.luminosity + brightness_on)
light_applied = 1
/obj/item/clothing/head/dropped(mob/user)
..()
spawn(1)
if(on && loc != user && light_applied)
user.SetLuminosity(user.luminosity - brightness_on)
light_applied = 0
/obj/item/clothing/head/update_icon(var/mob/user)
overlays.Cut()
@@ -308,18 +290,6 @@ BLIND // can't see anything
var/mob/living/carbon/human/H = user
H.update_inv_head()
/obj/item/clothing/head/equipped(mob/user)
..()
update_light(user)
/obj/item/clothing/head/pickup(mob/user)
..()
update_light(user)
/obj/item/clothing/head/dropped(mob/user)
..()
update_light(user)
/obj/item/clothing/head/update_clothing_icon()
if (ismob(src.loc))
var/mob/M = src.loc
@@ -357,6 +327,7 @@ BLIND // can't see anything
permeability_coefficient = 0.50
slowdown = SHOES_SLOWDOWN
force = 2
var/overshoes = 0
species_restricted = list("exclude","Unathi","Tajara")
sprite_sheets = list("Vox" = 'icons/mob/species/vox/shoes.dmi')

View File

@@ -43,7 +43,7 @@
item_state = "lgloves"
siemens_coefficient = 1.0 //thin latex gloves, much more conductive than fabric gloves (basically a capacitor for AC)
permeability_coefficient = 0.01
germ_level = 0
/obj/item/clothing/gloves/botanic_leather
desc = "These leather work gloves protect against thorns, barbs, prickles, spikes and other harmful objects of floral origin."
name = "botanist's leather gloves"

View File

@@ -1,31 +1,72 @@
/obj/item/clothing/shoes/magboots
desc = "Magnetic boots, often used during extravehicular activity to ensure the user remains safely attached to the vehicle."
desc = "Magnetic boots, often used during extravehicular activity to ensure the user remains safely attached to the vehicle. They're large enough to be worn over other footwear."
name = "magboots"
icon_state = "magboots0"
species_restricted = null
force = 3
overshoes = 1
var/magpulse = 0
var/icon_base = "magboots"
icon_action_button = "action_blank"
action_button_name = "Toggle the magboots"
var/obj/item/clothing/shoes/shoes = null //Undershoes
var/mob/living/carbon/human/wearer = null //For shoe procs
/obj/item/clothing/shoes/magboots/proc/set_slowdown()
slowdown = shoes? max(SHOES_SLOWDOWN, shoes.slowdown): SHOES_SLOWDOWN //So you can't put on magboots to make you walk faster.
if (magpulse)
slowdown += 3
/obj/item/clothing/shoes/magboots/attack_self(mob/user)
if(magpulse)
flags &= ~NOSLIP
slowdown = SHOES_SLOWDOWN
magpulse = 0
set_slowdown()
force = 3
if(icon_base) icon_state = "[icon_base]0"
user << "You disable the mag-pulse traction system."
else
flags |= NOSLIP
slowdown = 2
magpulse = 1
set_slowdown()
force = 5
if(icon_base) icon_state = "[icon_base]1"
user << "You enable the mag-pulse traction system."
user.update_inv_shoes() //so our mob-overlays update
/obj/item/clothing/shoes/magboots/mob_can_equip(mob/user)
var/mob/living/carbon/human/H = user
if(H.shoes)
shoes = H.shoes
if(shoes.overshoes)
user << "You are unable to wear \the [src] as \the [H.shoes] are in the way."
shoes = null
return 0
H.drop_from_inventory(shoes) //Remove the old shoes so you can put on the magboots.
shoes.loc = src
if(!..())
if(shoes) //Put the old shoes back on if the check fails.
if(H.equip_to_slot_if_possible(shoes, slot_shoes))
src.shoes = null
return 0
if (shoes)
user << "You slip \the [src] on over \the [shoes]."
set_slowdown()
wearer = H
return 1
/obj/item/clothing/shoes/magboots/dropped()
..()
var/mob/living/carbon/human/H = wearer
if(shoes)
if(!H.equip_to_slot_if_possible(shoes, slot_shoes))
shoes.loc = get_turf(src)
src.shoes = null
wearer = null
/obj/item/clothing/shoes/magboots/examine(mob/user)
..(user)
var/state = "disabled"

View File

@@ -96,10 +96,7 @@
helmet.canremove = 0
if(boots)
if(H.shoes)
M << "You are unable to deploy your suit's magboots as \the [H.shoes] are in the way."
else if (H.equip_to_slot_if_possible(boots, slot_shoes))
M << "Your suit's boots deploy with a hiss."
if (H.equip_to_slot_if_possible(boots, slot_shoes))
boots.canremove = 0
if(tank)
@@ -115,18 +112,18 @@
var/mob/living/carbon/human/H
if(helmet)
helmet.canremove = 1
H = helmet.loc
if(istype(H))
if(helmet && H.head == helmet)
helmet.canremove = 1
H.drop_from_inventory(helmet)
helmet.loc = src
if(boots)
boots.canremove = 1
H = boots.loc
if(istype(H))
if(boots && H.shoes == boots)
boots.canremove = 1
H.drop_from_inventory(boots)
boots.loc = src

View File

@@ -141,10 +141,11 @@
if("finalise_create_account")
var/account_name = href_list["holder_name"]
var/starting_funds = max(text2num(href_list["starting_funds"]), 0)
create_account(account_name, starting_funds, src)
starting_funds = Clamp(starting_funds, 0, station_account.money) // Not authorized to put the station in debt.
starting_funds = min(starting_funds, fund_cap) // Not authrorized to give more than the fund cap.
starting_funds = min(starting_funds, fund_cap) // Not authorized to give more than the fund cap.
create_account(account_name, starting_funds, src)
if(starting_funds > 0)
//subtract the money
station_account.money -= starting_funds

View File

@@ -63,11 +63,10 @@
//world << " checking [areapath]"
var/area/A = locate(areapath)
//world << " A: [A], contents.len: [A.contents.len]"
for(var/area/B in A.related)
//world << " B: [B], contents.len: [B.contents.len]"
for(var/turf/simulated/floor/F in B.contents)
if(!F.contents.len)
turfs += F
for(var/turf/simulated/floor/F in A.contents)
if(!F.contents.len)
turfs += F
var/list/spawn_types = list()
var/max_number
@@ -116,4 +115,4 @@
#undef VERM_MICE
#undef VERM_LIZARDS
#undef VERM_SPIDERS
#undef VERM_SPIDERS

View File

@@ -0,0 +1,21 @@
/obj/item/weapon/pen
description_info = {"This is an item for writing down your thoughts, on paper or elsewhere. The following special commands are available:
Pen and crayon commands
\[br\] : Creates a linebreak.
\[center\] - \[/center\] : Centers the text.
\[h1\] - \[/h1\] : Makes the text a first level heading.
\[h2\] - \[/h2\] : Makes the text a second level headin.
\[h3\] - \[/h3\] : Makes the text a third level heading.
\[b\] - \[/b\] : Makes the text bold.
\[i\] - \[/i\] : Makes the text italic.
\[u\] - \[/u\] : Makes the text underlined.
\[large\] - \[/large\] : Increases the size of the text.
\[sign\] : Inserts a signature of your name in a foolproof way.
\[field\] : Inserts an invisible field which lets you start type from there. Useful for forms.
\[date\] : Inserts today's station date.
\[time\] : Inserts the current station time.
Pen exclusive commands
\[small\] - \[/small\] : Decreases the size of the text.
\[list\] - \[/list\] : A list.
\[*\] : A dot used for lists.
\[hr\] : Adds a horizontal rule."}

View File

@@ -400,7 +400,7 @@
/mob/living/simple_animal/hostile/carp/holodeck/New()
..()
SetLuminosity(2) //hologram lighting
set_light(2) //hologram lighting
/mob/living/simple_animal/hostile/carp/holodeck/proc/set_safety(var/safe)
if (safe)

View File

@@ -341,9 +341,6 @@
..()
if(!seed)
return
if(seed.get_trait(TRAIT_BIOLUM))
user.SetLuminosity(user.luminosity + seed.get_trait(TRAIT_BIOLUM))
SetLuminosity(0)
if(seed.get_trait(TRAIT_STINGS))
var/mob/living/carbon/human/H = user
if(istype(H) && H.gloves)
@@ -354,12 +351,6 @@
seed.do_thorns(H,src)
seed.do_sting(H,src,pick("r_hand","l_hand"))
/obj/item/weapon/reagent_containers/food/snacks/grown/dropped(mob/user)
..()
if(seed && seed.get_trait(TRAIT_BIOLUM))
user.SetLuminosity(user.luminosity - seed.get_trait(TRAIT_BIOLUM))
SetLuminosity(seed.get_trait(TRAIT_BIOLUM))
// Predefined types for placing on the map.
/obj/item/weapon/reagent_containers/food/snacks/grown/mushroom/libertycap

View File

@@ -165,9 +165,10 @@
if(!istype(splat)) // Plants handle their own stuff.
splat.name = "[thrown.name] [pick("smear","smudge","splatter")]"
if(get_trait(TRAIT_BIOLUM))
var/clr
if(get_trait(TRAIT_BIOLUM_COLOUR))
splat.l_color = get_trait(TRAIT_BIOLUM_COLOUR)
splat.SetLuminosity(get_trait(TRAIT_BIOLUM))
clr = get_trait(TRAIT_BIOLUM_COLOUR)
splat.set_light(get_trait(TRAIT_BIOLUM), l_color = clr)
if(get_trait(TRAIT_PRODUCT_COLOUR))
splat.color = get_trait(TRAIT_PRODUCT_COLOUR)
@@ -276,12 +277,11 @@
// Handle light requirements.
if(!light_supplied)
var/area/A = get_area(current_turf)
if(A)
if(A.lighting_use_dynamic)
light_supplied = max(0,min(10,current_turf.lighting_lumcount)-5)
else
light_supplied = 5
var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in current_turf
if(L)
light_supplied = max(0,min(10,L.lum_r + L.lum_g + L.lum_b)-5)
else
light_supplied = 5
if(light_supplied)
if(abs(light_supplied - get_trait(TRAIT_IDEAL_LIGHT)) > get_trait(TRAIT_LIGHT_TOLERANCE))
health_change += rand(1,3) * HYDRO_SPEED_MULTIPLIER
@@ -696,9 +696,10 @@
product.desc += " On second thought, something about this one looks strange."
if(get_trait(TRAIT_BIOLUM))
var/clr
if(get_trait(TRAIT_BIOLUM_COLOUR))
product.l_color = get_trait(TRAIT_BIOLUM_COLOUR)
product.SetLuminosity(get_trait(TRAIT_BIOLUM))
clr = get_trait(TRAIT_BIOLUM_COLOUR)
product.set_light(get_trait(TRAIT_BIOLUM), l_color = clr)
//Handle spawning in living, mobile products (like dionaea).
if(istype(product,/mob/living))

View File

@@ -6,10 +6,9 @@
var/list/turf/simulated/floor/turfs = list() //list of all the empty floor turfs in the hallway areas
for(var/areapath in typesof(/area/hallway))
var/area/A = locate(areapath)
for(var/area/B in A.related)
for(var/turf/simulated/floor/F in B.contents)
if(!F.contents.len)
turfs += F
for(var/turf/simulated/floor/F in A.contents)
if(!F.contents.len)
turfs += F
if(turfs.len) //Pick a turf to spawn at if we can
var/turf/simulated/floor/T = pick(turfs)
@@ -146,14 +145,13 @@
color = icon_colour
// Apply colour and light from seed datum.
if(seed.get_trait(TRAIT_BIOLUM))
SetLuminosity(1+round(seed.get_trait(TRAIT_POTENCY)/20))
var/clr
if(seed.get_trait(TRAIT_BIOLUM_COLOUR))
l_color = seed.get_trait(TRAIT_BIOLUM_COLOUR)
else
l_color = null
clr = seed.get_trait(TRAIT_BIOLUM_COLOUR)
set_light(1+round(seed.get_trait(TRAIT_POTENCY)/20), l_color = clr)
return
else
SetLuminosity(0)
set_light(0)
/obj/effect/plant/proc/refresh_icon()
var/growth = min(max_growth,round(health/growth_threshold))
@@ -256,4 +254,4 @@
die_off()
/obj/effect/plant/proc/is_mature()
return (health >= (max_health/3))
return (health >= (max_health/3))

View File

@@ -350,7 +350,7 @@
usr << "There is no label to remove."
return
/obj/machinery/portable_atmospherics/hydroponics/verb/set_light()
/obj/machinery/portable_atmospherics/hydroponics/verb/setlight()
set name = "Set Light"
set category = "Object"
set src in view(1)
@@ -596,13 +596,12 @@
if(closed_system && mechanical)
light_string = "that the internal lights are set to [tray_light] lumens"
else
var/area/A = T.loc
var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T
var/light_available
if(A)
if(A.lighting_use_dynamic)
light_available = max(0,min(10,T.lighting_lumcount)-5)
else
light_available = 5
if(L)
light_available = max(0,min(10,L.lum_r + L.lum_g + L.lum_b)-5)
else
light_available = 5
light_string = "a light level of [light_available] lumens"
usr << "The tray's sensor suite is reporting [light_string] and a temperature of [environment.temperature]K."

View File

@@ -16,7 +16,7 @@
..()
verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/close_lid_verb
verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/remove_label
verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/set_light
verbs -= /obj/machinery/portable_atmospherics/hydroponics/verb/setlight
/obj/machinery/portable_atmospherics/hydroponics/soil/CanPass()
return 1

View File

@@ -73,12 +73,11 @@
// Update bioluminescence.
if(seed)
if(seed.get_trait(TRAIT_BIOLUM))
SetLuminosity(round(seed.get_trait(TRAIT_POTENCY)/10))
var/clr
if(seed.get_trait(TRAIT_BIOLUM_COLOUR))
l_color = seed.get_trait(TRAIT_BIOLUM_COLOUR)
else
l_color = null
clr = seed.get_trait(TRAIT_BIOLUM_COLOUR)
set_light(round(seed.get_trait(TRAIT_POTENCY)/10), l_color = clr)
return
SetLuminosity(0)
return
set_light(0)
return

View File

@@ -0,0 +1,67 @@
/*
BS12 object based lighting system
*/
/*
Changes from tg DAL:
- Lighting is done using objects instead of subareas.
- Animated transitions. (newer tg DAL has this)
- Full colours with mixing.
- Support for lights on shuttles.
- Code:
- Instead of one flat luminosity var, light is represented by 3 atom vars:
- light_range; range in tiles of the light, used for calculating falloff,
- light_power; multiplier for the brightness of lights,
- light_color; hex string representing the RGB colour of the light.
- SetLuminosity() is now set_light() and takes the three variables above.
- Variables can be left as null to not update them.
- SetOpacity() is now set_opacity().
- Areas have luminosity set to 1 permanently, no hard-lighting.
- Objects inside other objects can have lights and they properly affect the turf. (flashlights)
- area/master and area/list/related have been eviscerated since subareas aren't needed.
*/
/*
Relevant vars/procs:
atom: (lighting_atom.dm)
- var/light_range; range in tiles of the light, used for calculating falloff
- var/light_power; multiplier for the brightness of lights
- var/light_color; hex string representing the RGB colour of the light
- var/datum/light_source/light; light source datum for this atom, only present if light_range && light_power
- var/list/light_sources; light sources in contents that are shining through this object, including this object
- proc/set_light(l_range, l_power, l_color):
- Sets light_range/power/color to non-null args and calls update_light()
- proc/set_opacity(new_opacity):
- Sets opacity to new_opacity.
- If opacity has changed, call turf.reconsider_lights() to fix light occlusion
- proc/update_light():
- Updates the light var on this atom, deleting or creating as needed and calling .update()
turf: (lighting_turf.dm)
- var/list/affecting_lights; list of light sources that are shining onto this turf
- proc/reconsider_lights():
- Force all light sources shining onto this turf to update
- proc/lighting_clear_overlays():
- Delete (manual GC) all light overlays on this turf, used when changing turf to space
- proc/lighting_build_overlays():
- Create lighting overlays for this turf
atom/movable/lighting_overlay: (lighting_overlay.dm)
- var/lum_r, var/lum_g, var/lum_b; lumcounts of each colour
- var/needs_update; set on update_lumcount, checked by lighting process
- var/xoffset, var/yoffset; (only present when using sub-tile overlays) fractional offset of this overlay in the tile
- proc/update_lumcount(delta_r, delta_g, delta_b):
- Change the lumcount vars and queue the overlay for update
- proc/update_overlay()
- Called by the lighting process to update the color of the overlay
*/

View File

@@ -0,0 +1,10 @@
#define LIGHTING_INTERVAL 5 // frequency, in 1/10ths of a second, of the lighting process
#define LIGHTING_FALLOFF 1 // type of falloff to use for lighting; 1 for circular, 2 for square
#define LIGHTING_LAMBERTIAN 1 // use lambertian shading for light sources
#define LIGHTING_HEIGHT 1 // height off the ground of light sources on the pseudo-z-axis, you should probably leave this alone
#define LIGHTING_TRANSITIONS 1 // smooth, animated transitions, similar to /tg/station
#define LIGHTING_RESOLUTION 1 // resolution of the lighting overlays, powers of 2 only, max of 32
#define LIGHTING_LAYER 10 // drawing layer for lighting overlays
#define LIGHTING_ICON 'icons/effects/lighting_overlay.dmi' // icon used for lighting shading effects

View File

@@ -0,0 +1,169 @@
/datum/light_source
var/atom/top_atom
var/atom/source_atom
var/turf/source_turf
var/light_power
var/light_range
var/light_color // string, decomposed by parse_light_color()
var/lum_r
var/lum_g
var/lum_b
var/list/effect_r
var/list/effect_g
var/list/effect_b
var/list/effect_turf
var/applied
var/needs_update
var/destroyed
var/force_update
/datum/light_source/New(atom/owner, atom/top)
source_atom = owner
if(!source_atom.light_sources) source_atom.light_sources = list()
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
source_turf = top_atom
light_power = source_atom.light_power
light_range = source_atom.light_range
light_color = source_atom.light_color
parse_light_color()
effect_r = list()
effect_g = list()
effect_b = list()
effect_turf = list()
update()
return ..()
/datum/light_source/proc/destroy()
destroyed = 1
force_update()
if(source_atom) source_atom.light_sources -= src
if(top_atom) top_atom.light_sources -= src
/datum/light_source/proc/update(atom/new_top_atom)
if(new_top_atom && new_top_atom != top_atom)
if(top_atom != source_atom) top_atom.light_sources -= src
top_atom = new_top_atom
if(top_atom != source_atom)
if(!top_atom.light_sources) top_atom.light_sources = list()
top_atom.light_sources += src
lighting_update_lights += src
needs_update = 1
/datum/light_source/proc/force_update()
needs_update = 1
force_update = 1
lighting_update_lights += src
/datum/light_source/proc/check()
if(!source_atom)
destroy()
return 1
if(!top_atom)
top_atom = source_atom
. = 1
if(istype(top_atom, /turf))
if(source_turf != top_atom)
source_turf = top_atom
. = 1
else if(top_atom.loc != source_turf)
source_turf = top_atom.loc
. = 1
if(source_atom.light_power != light_power)
light_power = source_atom.light_power
. = 1
if(source_atom.light_range != light_range)
light_range = source_atom.light_range
. = 1
if(source_atom.light_color != light_color)
light_color = source_atom.light_color
parse_light_color()
. = 1
if(light_range && light_power && !applied)
. = 1
/datum/light_source/proc/parse_light_color()
if(light_color)
lum_r = GetRedPart(light_color) / 255
lum_g = GetGreenPart(light_color) / 255
lum_b = GetBluePart(light_color) / 255
else
lum_r = 1
lum_g = 1
lum_b = 1
/datum/light_source/proc/falloff(atom/movable/lighting_overlay/O)
#if LIGHTING_FALLOFF == 1 // circular
#if LIGHTING_RESOLUTION == 1
. = (O.x - source_turf.x)**2 + (O.y - source_turf.y)**2 + LIGHTING_HEIGHT
#else
. = (O.x - source_turf.x + O.xoffset)**2 + (O.y - source_turf.y + O.yoffset)**2 + LIGHTING_HEIGHT
#endif
#if LIGHTING_LAMBERTIAN == 1
. = CLAMP01((1 - CLAMP01(sqrt(.) / light_range)) * (1 / (sqrt(. + 1))))
#else
. = 1 - CLAMP01(sqrt(.) / light_range)
#endif
#elif LIGHTING_FALLOFF == 2 // square
#if LIGHTING_RESOLUTION == 1
. = abs(O.x - source_turf.x) + abs(O.y - source_turf.y) + LIGHTING_HEIGHT
#else
. = abs(O.x - source_turf.x + O.xoffset) + abs(O.y - source_turf.y + O.yoffset) + LIGHTING_HEIGHT
#endif
#if LIGHTING_LAMBERTIAN == 1
. = CLAMP01((1 - CLAMP01(. / light_range)) * (1 / (sqrt(.)**2 + )))
#else
. = 1 - CLAMP01(. / light_range)
#endif
#endif
/datum/light_source/proc/apply_lum()
applied = 1
if(istype(source_turf))
for(var/atom/movable/lighting_overlay/O in view(light_range, source_turf))
var/strength = light_power * falloff(O)
effect_r[O] = lum_r * strength
effect_g[O] = lum_g * strength
effect_b[O] = lum_b * strength
O.update_lumcount(lum_r * strength, lum_g * strength, lum_b * strength)
for(var/turf/T in view(light_range, source_turf))
if(!T.affecting_lights) T.affecting_lights = list()
T.affecting_lights += src
effect_turf += T
/datum/light_source/proc/remove_lum()
applied = 0
for(var/atom/movable/lighting_overlay/O in effect_r)
O.update_lumcount(-effect_r[O], -effect_g[O], -effect_b[O])
for(var/turf/T in effect_turf)
if(T.affecting_lights) T.affecting_lights -= src
effect_r.Cut()
effect_g.Cut()
effect_b.Cut()
effect_turf.Cut()

View File

@@ -0,0 +1,81 @@
/atom
var/light_power = 1 // intensity of the light
var/light_range = 0 // range in tiles of the light
var/light_color // RGB string representing the colour of the light
var/datum/light_source/light
var/list/light_sources
/atom/proc/set_light(l_range, l_power, l_color)
if(l_power != null) light_power = l_power
if(l_range != null) light_range = l_range
if(l_color != null) light_color = l_color
update_light()
/atom/proc/update_light()
if(!light_power || !light_range)
if(light)
light.destroy()
light = null
else
if(!istype(loc, /atom/movable))
. = src
else
. = loc
if(light)
light.update(.)
else
light = new /datum/light_source(src, .)
/atom/New()
. = ..()
if(light_power && light_range)
update_light()
/atom/Destroy()
if(light)
light.destroy()
light = null
return ..()
/atom/movable/Destroy()
var/turf/T = loc
if(opacity && istype(T))
T.reconsider_lights()
return ..()
/atom/movable/Move()
var/turf/old_loc = loc
. = ..()
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)
var/old_opacity = opacity
opacity = new_opacity
var/turf/T = loc
if(old_opacity != new_opacity && istype(T))
T.reconsider_lights()
/obj/item/equipped()
. = ..()
update_light()
/obj/item/pickup()
. = ..()
update_light()
/obj/item/dropped()
. = ..()
update_light()

View File

@@ -0,0 +1,48 @@
/atom/movable/lighting_overlay
name = ""
mouse_opacity = 0
simulated = 0
anchored = 1
icon = LIGHTING_ICON
layer = LIGHTING_LAYER
invisibility = INVISIBILITY_LIGHTING
blend_mode = BLEND_MULTIPLY
color = "#000000"
var/lum_r
var/lum_g
var/lum_b
#if LIGHTING_RESOLUTION != 1
var/xoffset
var/yoffset
#endif
var/needs_update
/atom/movable/lighting_overlay/New()
. = ..()
verbs.Cut()
/atom/movable/lighting_overlay/proc/update_lumcount(delta_r, delta_g, delta_b)
lum_r += delta_r
lum_g += delta_g
lum_b += delta_b
needs_update = 1
lighting_update_overlays += src
/atom/movable/lighting_overlay/proc/update_overlay()
var/mx = max(lum_r, lum_g, lum_b)
. = 1 // factor
if(mx > 1)
. = 1/mx
#if LIGHTING_TRANSITIONS == 1
animate(src,
color = rgb(lum_r * 255 * ., lum_g * 255 * ., lum_b * 255 * .),
LIGHTING_INTERVAL - 1
)
#else
color = rgb(lum_r * 255 * ., lum_g * 255 * ., lum_b * 255 * .)
#endif

View File

@@ -0,0 +1,29 @@
/datum/controller/process/lighting/setup()
name = "lighting"
schedule_interval = LIGHTING_INTERVAL
create_lighting_overlays()
/datum/controller/process/lighting/doWork()
for(var/datum/light_source/L in lighting_update_lights)
if(L.needs_update)
if(L.destroyed)
L.remove_lum()
else if(L.check() || L.force_update)
L.remove_lum()
L.apply_lum()
L.force_update = 0
L.needs_update = 0
scheck()
lighting_update_lights.Cut()
for(var/atom/movable/lighting_overlay/O in lighting_update_overlays)
if(O.needs_update)
O.update_overlay()
O.needs_update = 0
scheck()
lighting_update_overlays.Cut()

View File

@@ -0,0 +1,47 @@
/var/list/lighting_update_lights = list()
/var/list/lighting_update_overlays = list()
/area/var/lighting_use_dynamic = 1
// duplicates lots of code, but this proc needs to be as fast as possible.
/proc/create_lighting_overlays(zlevel = 0)
var/state = "light[LIGHTING_RESOLUTION]"
var/area/A
if(zlevel == 0) // populate all zlevels
for(var/turf/T in world)
if(T.dynamic_lighting)
A = T.loc
if(A.lighting_use_dynamic)
#if LIGHTING_RESOLUTION == 1
var/atom/movable/lighting_overlay/O = new(T)
O.icon_state = state
#else
for(var/i = 0; i < LIGHTING_RESOLUTION; i++)
for(var/j = 0; j < LIGHTING_RESOLUTION; j++)
var/atom/movable/lighting_overlay/O = new(T)
O.pixel_x = i * (32 / LIGHTING_RESOLUTION)
O.pixel_y = j * (32 / LIGHTING_RESOLUTION)
O.xoffset = (((2*i + 1) / (LIGHTING_RESOLUTION * 2)) - 0.5)
O.yoffset = (((2*j + 1) / (LIGHTING_RESOLUTION * 2)) - 0.5)
O.icon_state = state
#endif
else
for(var/x = 1; x <= world.maxx; x++)
for(var/y = 1; y <= world.maxy; y++)
var/turf/T = locate(x, y, zlevel)
if(T.dynamic_lighting)
A = T.loc
if(A.lighting_use_dynamic)
#if LIGHTING_RESOLUTION == 1
var/atom/movable/lighting_overlay/O = new(T)
O.icon_state = state
#else
for(var/i = 0; i < LIGHTING_RESOLUTION; i++)
for(var/j = 0; j < LIGHTING_RESOLUTION; j++)
var/atom/movable/lighting_overlay/O = new(T)
O.pixel_x = i * (32 / LIGHTING_RESOLUTION)
O.pixel_y = j * (32 / LIGHTING_RESOLUTION)
O.xoffset = (((2*i + 1) / (LIGHTING_RESOLUTION * 2)) - 0.5)
O.yoffset = (((2*j + 1) / (LIGHTING_RESOLUTION * 2)) - 0.5)
O.icon_state = state
#endif

View File

@@ -0,0 +1,29 @@
/turf
var/list/affecting_lights
/turf/proc/reconsider_lights()
for(var/datum/light_source/L in affecting_lights)
L.force_update()
/turf/proc/lighting_clear_overlays()
for(var/atom/movable/lighting_overlay/L in src)
L.loc = null
/turf/proc/lighting_build_overlays()
if(!locate(/atom/movable/lighting_overlay) in src)
var/state = "light[LIGHTING_RESOLUTION]"
var/area/A = loc
if(A.lighting_use_dynamic)
#if LIGHTING_RESOLUTION == 1
var/atom/movable/lighting_overlay/O = new(src)
O.icon_state = state
#else
for(var/i = 0; i < LIGHTING_RESOLUTION; i++)
for(var/j = 0; j < LIGHTING_RESOLUTION; j++)
var/atom/movable/lighting_overlay/O = new(src)
O.pixel_x = i * (32 / LIGHTING_RESOLUTION)
O.pixel_y = j * (32 / LIGHTING_RESOLUTION)
O.xoffset = (((2*i + 1) / (LIGHTING_RESOLUTION * 2)) - 0.5)
O.yoffset = (((2*j + 1) / (LIGHTING_RESOLUTION * 2)) - 0.5)
O.icon_state = state
#endif

View File

@@ -0,0 +1,10 @@
#undef LIGHTING_INTERVAL
#undef LIGHTING_FALLOFF
#undef LIGHTING_LAMBERTIAN
#undef LIGHTING_HEIGHT
#undef LIGHTING_TRANSITIONS
#undef LIGHTING_RESOLUTION
#undef LIGHTING_LAYER
#undef LIGHTING_ICON

View File

@@ -120,7 +120,7 @@
new/obj/item/clothing/mask/gas/clown_hat(src)
new/obj/item/weapon/bikehorn(src)
//new/obj/item/weapon/stamp/clown(src) I'd add it, but only clowns can use it
new/obj/item/toy/crayon/rainbow(src)
new/obj/item/weapon/pen/crayon/rainbow(src)
new/obj/item/toy/waterflower(src)
if(95)
new/obj/item/clothing/under/mime(src)
@@ -130,7 +130,7 @@
new/obj/item/clothing/mask/gas/mime(src)
new/obj/item/clothing/head/beret(src)
new/obj/item/clothing/suit/suspenders(src)
new/obj/item/toy/crayon/mime(src)
new/obj/item/weapon/pen/crayon/mime(src)
new/obj/item/weapon/reagent_containers/food/drinks/bottle/bottleofnothing(src)
if(96)
new/obj/item/weapon/vampiric(src)

View File

@@ -104,7 +104,7 @@
icon_state = "furnace"
density = 1
anchored = 1
luminosity = 3
light_range = 3
var/obj/machinery/mineral/input = null
var/obj/machinery/mineral/output = null
var/obj/machinery/mineral/console = null
@@ -231,4 +231,4 @@
else
continue
console.updateUsrDialog()
console.updateUsrDialog()

View File

@@ -5,7 +5,7 @@
name = "Light-emtter"
anchored = 1
unacidable = 1
luminosity = 8
light_range = 8
/**********************Miner Lockers**************************/

View File

@@ -28,7 +28,7 @@
if(src.can_use())
cameranet.addCamera(src)
else
src.SetLuminosity(0)
src.set_light(0)
cameranet.removeCamera(src)
/obj/machinery/camera/New()

View File

@@ -155,7 +155,7 @@ var/list/slot_equipment_priority = list( \
Target = loc
remove_from_mob(W)
if(!W) return 1 // self destroying objects (tk, grabs)
if(!(W && W.loc)) return 1 // self destroying objects (tk, grabs)
W.forceMove(Target)
update_icons()

View File

@@ -110,14 +110,14 @@
if(stat)
return 0
on = 1
SetLuminosity(light_strength)
set_light(light_strength)
update_icons()
return 1
/mob/living/bot/proc/turn_off()
on = 0
SetLuminosity(0)
set_light(0)
update_icons()
/mob/living/bot/proc/explode()
qdel(src)
qdel(src)

View File

@@ -226,7 +226,7 @@
beacon_freq = freq
if("screw")
screwloose = !screwloose
usr << "<span class='notice>You twiddle the screw.</span>"
usr << "<span class='notice'>You twiddle the screw.</span>"
if("oddbutton")
oddbutton = !oddbutton
usr << "<span class='notice'>You press the weird button.</span>"

View File

@@ -334,53 +334,13 @@
path = list()
/mob/living/bot/secbot/proc/check_threat(var/mob/living/M)
if(M.stat == DEAD)
if(!M || !istype(M) || M.stat)
return 0
if(emagged)
return 10
var/threatcount = 0
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.handcuffed)
return 0
var/obj/item/weapon/card/id/id = GetIdCard(H) //Agent cards lower threatlevel.
if(id && istype(id, /obj/item/weapon/card/id/syndicate))
threatcount -= 2
if(idcheck && !access_scanner.allowed(H))
if(istype(H.l_hand, /obj/item/weapon/gun) || istype(H.l_hand, /obj/item/weapon/melee))
threatcount += 4
if(istype(H.r_hand, /obj/item/weapon/gun) || istype(H.r_hand, /obj/item/weapon/melee))
threatcount += 4
if(istype(H.belt, /obj/item/weapon/gun) || istype(H.belt, /obj/item/weapon/melee))
threatcount += 2
if(H.species.name != "Human") //beepsky so racist.
threatcount += 2
if(check_records || check_arrest)
var/perpname = H.name
if(id)
perpname = id.registered_name
var/datum/data/record/R = find_security_record("name", perpname)
if(check_records && !R)
threatcount += 4
if(check_arrest && R && (R.fields["criminal"] == "*Arrest*"))
threatcount += 4
else if(isanimal(M))
if(istype(M, /mob/living/simple_animal/hostile) && !istype(M, /mob/living/simple_animal/hostile/retaliate/goat))
threatcount += 4
return threatcount
return M.assess_perp(access_scanner, idcheck, check_records, check_arrest)
/mob/living/bot/secbot/proc/patrol_step()
if(loc == patrol_target)

View File

@@ -4,10 +4,12 @@
var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing
if(isturf(loc)) //else, there's considered to be no light
var/turf/T = loc
var/area/A = T.loc
if(A)
if(A.lighting_use_dynamic) light_amount = min(10,T.lighting_lumcount) - 5 //hardcapped so it's not abused by having a ton of flashlights
else light_amount = 5
var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T
if(L)
light_amount = min(10,L.lum_r + L.lum_g + L.lum_b) - 5 //hardcapped so it's not abused by having a ton of flashlights
else
light_amount = 5
nutrition += light_amount

View File

@@ -1,7 +1,7 @@
mob/living/carbon/verb/give(var/mob/living/carbon/target in view(1)-usr)
set category = "IC"
set name = "Give"
if(target.stat == 2 || usr.stat == 2|| target.client == null)
if(!istype(target) || target.stat == 2 || usr.stat == 2|| target.client == null)
return
var/obj/item/I
if(!usr.hand && usr.r_hand == null)

View File

@@ -32,6 +32,7 @@
var/temperature_alert = 0
var/in_stasis = 0
var/heartbeat = 0
var/global/list/overlays_cache = null
/mob/living/carbon/human/Life()
@@ -876,10 +877,11 @@
var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing
if(isturf(loc)) //else, there's considered to be no light
var/turf/T = loc
var/area/A = T.loc
if(A)
if(A.lighting_use_dynamic) light_amount = min(10,T.lighting_lumcount) - 5 //hardcapped so it's not abused by having a ton of flashlights
else light_amount = 5
var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T
if(L)
light_amount = min(10,L.lum_r + L.lum_g + L.lum_b) - 5 //hardcapped so it's not abused by having a ton of flashlights
else
light_amount = 5
nutrition += light_amount
traumatic_shock -= light_amount
@@ -897,10 +899,11 @@
var/light_amount = 0
if(isturf(loc))
var/turf/T = loc
var/area/A = T.loc
if(A)
if(A.lighting_use_dynamic) light_amount = T.lighting_lumcount
else light_amount = 10
var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T
if(L)
light_amount = L.lum_r + L.lum_g + L.lum_b //hardcapped so it's not abused by having a ton of flashlights
else
light_amount = 10
if(light_amount > species.light_dam) //if there's enough light, start dying
take_overall_damage(1,1)
else //heal in the dark
@@ -1082,6 +1085,33 @@
return 1
proc/handle_regular_hud_updates()
if(!overlays_cache)
overlays_cache = list()
overlays_cache.len = 23
overlays_cache[1] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage1")
overlays_cache[2] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage2")
overlays_cache[3] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage3")
overlays_cache[4] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage4")
overlays_cache[5] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage5")
overlays_cache[6] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage6")
overlays_cache[7] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage7")
overlays_cache[8] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage8")
overlays_cache[9] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage9")
overlays_cache[10] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage10")
overlays_cache[11] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay1")
overlays_cache[12] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay2")
overlays_cache[13] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay3")
overlays_cache[14] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay4")
overlays_cache[15] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay5")
overlays_cache[16] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay6")
overlays_cache[17] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay7")
overlays_cache[18] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay1")
overlays_cache[19] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay2")
overlays_cache[20] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay3")
overlays_cache[21] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay4")
overlays_cache[22] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay5")
overlays_cache[23] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay6")
if(hud_updateflag) // update our mob's hud overlays, AKA what others see flaoting above our head
handle_hud_list()
@@ -1100,32 +1130,32 @@
if(damageoverlay.overlays)
damageoverlay.overlays = list()
if(stat == UNCONSCIOUS)
//Critical damage passage overlay
if(health <= 0)
var/image/I
switch(health)
if(-20 to -10)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "passage1")
I = overlays_cache[1]
if(-30 to -20)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "passage2")
I = overlays_cache[2]
if(-40 to -30)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "passage3")
I = overlays_cache[3]
if(-50 to -40)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "passage4")
I = overlays_cache[4]
if(-60 to -50)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "passage5")
I = overlays_cache[5]
if(-70 to -60)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "passage6")
I = overlays_cache[6]
if(-80 to -70)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "passage7")
I = overlays_cache[7]
if(-90 to -80)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "passage8")
I = overlays_cache[8]
if(-95 to -90)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "passage9")
I = overlays_cache[9]
if(-INFINITY to -95)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "passage10")
I = overlays_cache[10]
damageoverlay.overlays += I
else
//Oxygen damage overlay
@@ -1133,19 +1163,19 @@
var/image/I
switch(oxyloss)
if(10 to 20)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay1")
I = overlays_cache[11]
if(20 to 25)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay2")
I = overlays_cache[12]
if(25 to 30)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay3")
I = overlays_cache[13]
if(30 to 35)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay4")
I = overlays_cache[14]
if(35 to 40)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay5")
I = overlays_cache[15]
if(40 to 45)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay6")
I = overlays_cache[16]
if(45 to INFINITY)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay7")
I = overlays_cache[17]
damageoverlay.overlays += I
//Fire and Brute damage overlay (BSSR)
@@ -1155,17 +1185,17 @@
var/image/I
switch(hurtdamage)
if(10 to 25)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay1")
I = overlays_cache[18]
if(25 to 40)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay2")
I = overlays_cache[19]
if(40 to 55)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay3")
I = overlays_cache[20]
if(55 to 70)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay4")
I = overlays_cache[21]
if(70 to 85)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay5")
I = overlays_cache[22]
if(85 to INFINITY)
I = image("icon" = 'icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay6")
I = overlays_cache[23]
damageoverlay.overlays += I
if( stat == DEAD )
@@ -1390,8 +1420,9 @@
//0.1% chance of playing a scary sound to someone who's in complete darkness
if(isturf(loc) && rand(1,1000) == 1)
var/turf/currentTurf = loc
if(!currentTurf.lighting_lumcount)
var/turf/T = loc
var/atom/movable/lighting_overlay/L = locate(/atom/movable/lighting_overlay) in T
if(L && L.lum_r + L.lum_g + L.lum_b == 0)
playsound_local(src,pick(scarySounds),50, 1, -1)
proc/handle_stomach()

View File

@@ -360,7 +360,7 @@
src.Hatch()
/obj/item/weapon/reagent_containers/food/snacks/egg/slime/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype( W, /obj/item/toy/crayon ))
if(istype( W, /obj/item/weapon/pen/crayon ))
return
else
..()

View File

@@ -139,7 +139,7 @@
var/obj/item/I = O
mass = I.w_class/THROWNOBJ_KNOCKBACK_DIVISOR
var/momentum = speed*mass
if(O.throw_source && momentum >= THROWNOBJ_KNOCKBACK_SPEED)
var/dir = get_dir(O.throw_source, src)
@@ -200,14 +200,14 @@
/mob/living/proc/IgniteMob()
if(fire_stacks > 0 && !on_fire)
on_fire = 1
src.AddLuminosity(3)
set_light(light_range + 3)
update_fire()
/mob/living/proc/ExtinguishMob()
if(on_fire)
on_fire = 0
fire_stacks = 0
src.AddLuminosity(-3)
set_light(max(0, light_range - 3))
update_fire()
/mob/living/proc/update_fire()
@@ -219,18 +219,18 @@
/mob/living/proc/handle_fire()
if(fire_stacks < 0)
fire_stacks = max(0, fire_stacks++) //If we've doused ourselves in water to avoid fire, dry off slowly
if(!on_fire)
return 1
else if(fire_stacks <= 0)
ExtinguishMob() //Fire's been put out.
return 1
var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment
if(G.gas["oxygen"] < 1)
ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire
return 1
var/turf/location = get_turf(src)
location.hotspot_expose(fire_burn_temperature(), 50, 1)
@@ -242,6 +242,6 @@
/mob/living/proc/fire_burn_temperature()
if (fire_stacks <= 0)
return 0
//Scale quadratically so that single digit numbers of fire stacks don't burn ridiculously hot.
return round(FIRESUIT_MAX_HEAT_PROTECTION_TEMPERATURE*(fire_stacks/FIRE_MAX_FIRESUIT_STACKS)**2)

View File

@@ -455,13 +455,13 @@ var/list/ai_verbs_default = list(
/mob/living/silicon/ai/reset_view(atom/A)
if(camera)
camera.SetLuminosity(0)
camera.set_light(0)
if(istype(A,/obj/machinery/camera))
camera = A
..()
if(istype(A,/obj/machinery/camera))
if(camera_light_on) A.SetLuminosity(AI_CAMERA_LUMINOSITY)
else A.SetLuminosity(0)
if(camera_light_on) A.set_light(AI_CAMERA_LUMINOSITY)
else A.set_light(0)
/mob/living/silicon/ai/proc/switchCamera(var/obj/machinery/camera/C)
@@ -592,7 +592,7 @@ var/list/ai_verbs_default = list(
src << "Camera lights [camera_light_on ? "activated" : "deactivated"]."
if(!camera_light_on)
if(camera)
camera.SetLuminosity(0)
camera.set_light(0)
camera = null
else
lightNearbyCamera()
@@ -607,20 +607,20 @@ var/list/ai_verbs_default = list(
if(src.camera)
var/obj/machinery/camera/camera = near_range_camera(src.eyeobj)
if(camera && src.camera != camera)
src.camera.SetLuminosity(0)
src.camera.set_light(0)
if(!camera.light_disabled)
src.camera = camera
src.camera.SetLuminosity(AI_CAMERA_LUMINOSITY)
src.camera.set_light(AI_CAMERA_LUMINOSITY)
else
src.camera = null
else if(isnull(camera))
src.camera.SetLuminosity(0)
src.camera.set_light(0)
src.camera = null
else
var/obj/machinery/camera/camera = near_range_camera(src.eyeobj)
if(camera && !camera.light_disabled)
src.camera = camera
src.camera.SetLuminosity(AI_CAMERA_LUMINOSITY)
src.camera.set_light(AI_CAMERA_LUMINOSITY)
camera_light_on = world.timeofday + 1 * 20 // Update the light every 2 seconds.

View File

@@ -47,7 +47,7 @@
if (istype(T, /turf))
loc = T.loc
if (istype(loc, /area))
if (!loc.master.power_equip && !istype(src.loc,/obj/item) && !APU_power)
if (!loc.power_equip && !istype(src.loc,/obj/item) && !APU_power)
blind = 1
if (!blind)
@@ -96,7 +96,7 @@
spawn(20)
src << "Backup battery online. Scanners, camera, and radio interface offline. Beginning fault-detection."
sleep(50)
if (loc.master.power_equip)
if (loc.power_equip)
if (!istype(T, /turf/space))
src << "Alert cancelled. Power has been restored without our assistance."
src:aiRestorePowerRoutine = 0
@@ -116,18 +116,17 @@
var/PRP
for (PRP=1, PRP<=4, PRP++)
for(var/area/A in current_area.master.related)
for (var/obj/machinery/power/apc/APC in A)
if (!(APC.stat & BROKEN))
theAPC = APC
break
for (var/obj/machinery/power/apc/APC in current_area)
if (!(APC.stat & BROKEN))
theAPC = APC
break
if (!theAPC)
switch(PRP)
if (1) src << "Unable to locate APC!"
else src << "Lost connection with the APC!"
src:aiRestorePowerRoutine = 2
return
if (loc.master.power_equip)
if (loc.power_equip)
if (!istype(T, /turf/space))
src << "Alert cancelled. Power has been restored without our assistance."
src:aiRestorePowerRoutine = 0
@@ -164,7 +163,7 @@
return 1
var/turf/T = get_turf(src)
var/area/A = get_area(src)
return ((!A.master.power_equip) && A.requires_power == 1 || istype(T, /turf/space)) && !istype(src.loc,/obj/item)
return ((!A.power_equip) && A.requires_power == 1 || istype(T, /turf/space)) && !istype(src.loc,/obj/item)
/mob/living/silicon/ai/updatehealth()
if(status_flags & GODMODE)
@@ -176,4 +175,4 @@
/mob/living/silicon/ai/rejuvenate()
..()
add_ai_verbs(src)
add_ai_verbs(src)

View File

@@ -188,8 +188,8 @@
//Standard robots use config for crit, which is somewhat excessive for these guys.
//Drones killed by damage will gib.
/mob/living/silicon/robot/drone/handle_regular_status_updates()
if((health <= -35 || (master_fabricator && src.z != master_fabricator.z)) && src.stat != 2)
var/turf/T = get_turf(src)
if((!T || health <= -35 || (master_fabricator && T.z != master_fabricator.z)) && src.stat != DEAD)
timeofdeath = world.time
death() //Possibly redundant, having trouble making death() cooperate.
gib()

View File

@@ -58,7 +58,7 @@
src.has_power = 0
if(lights_on) // Light is on but there is no power!
lights_on = 0
SetLuminosity(0)
set_light(0)
/mob/living/silicon/robot/proc/handle_regular_status_updates()

View File

@@ -367,9 +367,9 @@
lights_on = !lights_on
usr << "You [lights_on ? "enable" : "disable"] your integrated light."
if(lights_on)
SetLuminosity(integrated_light_power) // 1.5x luminosity of flashlight
set_light(integrated_light_power) // 1.5x luminosity of flashlight
else
SetLuminosity(0)
set_light(0)
/mob/living/silicon/robot/verb/self_diagnosis_verb()
set category = "Robot Commands"

View File

@@ -36,27 +36,31 @@ var/global/list/robot_modules = list(
// Bookkeeping
var/list/added_languages = list()
var/list/added_networks = list()
var/obj/item/device/radio/borg/modified_radio = null
var/list/modified_key = null
var/list/original_radio_channels = list()
/obj/item/weapon/robot_module/New(var/mob/living/silicon/robot/R)
..()
add_camera_networks(R)
add_languages(R)
add_radio_channels(R)
add_subsystems(R)
apply_status_flags(R)
if(R.radio)
R.radio.recalculateChannels()
/obj/item/weapon/robot_module/proc/Reset(var/mob/living/silicon/robot/R)
..()
R.module = null
remove_camera_networks(R)
remove_languages(R)
remove_radio_channels(R)
remove_subsystems(R)
remove_status_flags(R)
/obj/item/weapon/robot_module/Destroy()
if(R.radio)
R.radio.recalculateChannels()
qdel(src)
/obj/item/weapon/robot_module/Destroy()
qdel(modules)
qdel(synths)
qdel(emag)
@@ -115,23 +119,6 @@ var/global/list/robot_modules = list(
R.camera.remove_networks(added_networks)
added_networks.Cut()
/obj/item/weapon/robot_module/proc/add_radio_channels(var/mob/living/silicon/robot/R)
if(!R.radio)
return
modified_radio = R.radio
modified_key = R.radio.keyslot
original_radio_channels = modified_radio.channels.Copy()
modified_radio.config(channels)
/obj/item/weapon/robot_module/proc/remove_radio_channels(var/mob/living/silicon/robot/R)
// Only reset if the original radio component hasn't been altered/replaced
if(!(R.radio && R.radio == modified_radio && R.radio.keyslot == modified_key))
return
modified_radio.config(original_radio_channels)
original_radio_channels.Cut()
/obj/item/weapon/robot_module/proc/add_subsystems(var/mob/living/silicon/robot/R)
R.verbs |= subsystems

View File

@@ -1,23 +1,19 @@
/mob/living/silicon
var/register_alarms = 1
var/obj/nano_module/alarm_monitor/alarm_monitor
var/obj/nano_module/alarm_monitor/all/alarm_monitor
var/obj/nano_module/atmos_control/atmos_control
var/obj/nano_module/crew_monitor/crew_monitor
var/obj/nano_module/law_manager/law_manager
var/obj/nano_module/power_monitor/power_monitor
var/obj/nano_module/rcon/rcon
var/alarm_monitor_type = /obj/nano_module/alarm_monitor/borg
/mob/living/silicon
alarm_monitor_type = /obj/nano_module/alarm_monitor/borg
var/list/silicon_subsystems = list(
/mob/living/silicon/proc/subsystem_alarm_monitor,
/mob/living/silicon/proc/subsystem_law_manager
)
/mob/living/silicon/ai
alarm_monitor_type = /obj/nano_module/alarm_monitor/ai
silicon_subsystems = list(
/mob/living/silicon/proc/subsystem_alarm_monitor,
/mob/living/silicon/proc/subsystem_atmos_control,
@@ -32,7 +28,7 @@
silicon_subsystems = list(/mob/living/silicon/proc/subsystem_law_manager)
/mob/living/silicon/proc/init_subsystems()
alarm_monitor = new alarm_monitor_type(src)
alarm_monitor = new(src)
atmos_control = new(src)
crew_monitor = new(src)
law_manager = new(src)

View File

@@ -240,7 +240,7 @@
////////////////Glow//////////////////
/mob/living/simple_animal/construct/proc/add_glow()
overlays = 0
var/overlay_layer = LIGHTING_LAYER+1
var/overlay_layer = 11
if(layer != MOB_LAYER)
overlay_layer=TURF_LAYER+0.2

View File

@@ -94,7 +94,7 @@
emote_hear = list("clicks")
emote_see = list("clacks")
desc = "Free crabs!"
src.sd_SetLuminosity(0)
src.sd_set_light(0)
inventory_head.loc = src.loc
inventory_head = null
else

View File

@@ -277,9 +277,9 @@
qdel(MED)
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("<span class='notice>[user] applies the [MED] on [src].</span>")
M.show_message("<span class='notice'>[user] applies the [MED] on [src].</span>")
else
user << "<span class='notice>\The [src] is dead, medical items won't bring it back to life.</span>"
user << "<span class='notice'>\The [src] is dead, medical items won't bring it back to life.</span>"
if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead.
if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch))
harvest(user)
@@ -300,7 +300,7 @@
usr << "<span class='danger>This weapon is ineffective, it does no damage.</span>"
for(var/mob/M in viewers(src, null))
if ((M.client && !( M.blinded )))
M.show_message("<span class='notice>[user] gently taps [src] with the [O].</span>")
M.show_message("<span class='notice'>[user] gently taps [src] with \the [O].</span>")
/mob/living/simple_animal/movement_delay()
var/tally = 0 //Incase I need to add stuff other than "speed" later

View File

@@ -24,7 +24,7 @@
assailant = user
affecting = victim
if(affecting.anchored)
if(affecting.anchored || !assailant.Adjacent(victim))
qdel(src)
return
@@ -36,7 +36,6 @@
hud.master = src
/obj/item/weapon/grab/Destroy()
//make sure the grabbed_by list doesn't fill up with nulls
if(affecting)
affecting.grabbed_by -= src
affecting = null
@@ -45,6 +44,7 @@
assailant.client.screen -= hud
assailant = null
qdel(hud)
hud = null
..()
//Used by throw code to hand over the mob, instead of throwing the grab. The grab is then deleted by the throw code.
@@ -68,6 +68,9 @@
/obj/item/weapon/grab/process()
confirm()
if(!assailant)
qdel(src)
return
if(assailant.client)
assailant.client.screen -= hud
@@ -227,8 +230,5 @@
/obj/item/weapon/grab/dropped()
loc = null
qdel(src)
/obj/item/weapon/grab/Destroy()
qdel(hud)
..()

View File

@@ -82,6 +82,7 @@
/mob/living/silicon/isSilicon()
return 1
/proc/isAI(A)
if(istype(A, /mob/living/silicon/ai))
return 1
@@ -93,10 +94,10 @@
/mob/living/silicon/ai/isAI()
return 1
/mob/proc/isRobot()
/mob/proc/isMobAI()
return 0
/mob/living/silicon/robot/isRobot()
/mob/living/silicon/ai/isMobAI()
return 1
/mob/proc/isSynthetic()
@@ -619,3 +620,61 @@ proc/is_blind(A)
// Returns true if the mob has a client which has been active in the last given X minutes.
/mob/proc/is_client_active(var/active = 1)
return client && client.inactivity < active MINUTES
#define SAFE_PERP -50
/mob/living/proc/assess_perp(var/auth_weapons, var/check_records, var/check_arrest)
if(stat == DEAD)
return SAFE_PERP
return 0
/mob/living/carbon/human/assess_perp(var/obj/access_obj, var/auth_weapons, var/check_records, var/check_arrest)
var/threatcount = ..()
if(. == SAFE_PERP)
return SAFE_PERP
//Agent cards lower threatlevel.
var/obj/item/weapon/card/id/id = GetIdCard(src)
if(id && istype(id, /obj/item/weapon/card/id/syndicate))
threatcount -= 2
// A proper CentCom id is hard currency.
else if(id && istype(id, /obj/item/weapon/card/id/centcom))
return SAFE_PERP
if(auth_weapons && !access_obj.allowed(src))
if(istype(l_hand, /obj/item/weapon/gun) || istype(l_hand, /obj/item/weapon/melee))
threatcount += 4
if(istype(r_hand, /obj/item/weapon/gun) || istype(r_hand, /obj/item/weapon/melee))
threatcount += 4
if(istype(belt, /obj/item/weapon/gun) || istype(belt, /obj/item/weapon/melee))
threatcount += 2
if(species.name != "Human")
threatcount += 2
if(check_records || check_arrest)
var/perpname = name
if(id)
perpname = id.registered_name
var/datum/data/record/R = find_security_record("name", perpname)
if(check_records && !R)
threatcount += 4
if(check_arrest && R && (R.fields["criminal"] == "*Arrest*"))
threatcount += 4
return threatcount
/mob/living/simple_animal/hostile/assess_perp(var/obj/access_obj, var/auth_weapons, var/check_records, var/check_arrest)
var/threatcount = ..()
if(. == SAFE_PERP)
return SAFE_PERP
if(!istype(src, /mob/living/simple_animal/hostile/retaliate/goat))
threatcount += 4
return threatcount
#undef SAFE_PERP

View File

@@ -3,14 +3,7 @@
var/list_cameras = 0 // Whether or not to list camera references. A future goal would be to merge this with the enginering/security camera console. Currently really only for AI-use.
var/list/datum/alarm_handler/alarm_handlers // The particular list of alarm handlers this alarm monitor should present to the user.
/obj/nano_module/alarm_monitor/ai
list_cameras = 1
/obj/nano_module/alarm_monitor/ai/New()
..()
alarm_handlers = alarm_manager.all_handlers
/obj/nano_module/alarm_monitor/borg/New()
/obj/nano_module/alarm_monitor/all/New()
..()
alarm_handlers = alarm_manager.all_handlers
@@ -73,7 +66,7 @@
var/cameras[0]
var/lost_sources[0]
if(list_cameras)
if(user.isMobAI())
for(var/obj/machinery/camera/C in A.cameras())
cameras[++cameras.len] = C.nano_structure()
for(var/datum/alarm_source/AS in A.sources)

View File

@@ -147,7 +147,7 @@
R << "<span class='danger'>Law Notice</span>"
R.laws.show_laws(R)
if(usr != owner)
usr << "<span class='notice>Laws displayed.</span>"
usr << "<span class='notice'>Laws displayed.</span>"
return 1
return 0

View File

@@ -280,31 +280,6 @@
return t
/obj/item/weapon/paper/proc/openhelp(mob/user as mob)
user << browse({"<HTML><HEAD><TITLE>Pen Help</TITLE></HEAD>
<BODY>
<b><center>Crayon&Pen commands</center></b><br>
<br>
\[br\] : Creates a linebreak.<br>
\[center\] - \[/center\] : Centers the text.<br>
\[h1\] - \[/h1\] : Makes the text a first level heading<br>
\[h2\] - \[/h2\] : Makes the text a second level heading<br>
\[h3\] - \[/h3\] : Makes the text a third level heading<br>
\[b\] - \[/b\] : Makes the text <b>bold</b>.<br>
\[i\] - \[/i\] : Makes the text <i>italic</i>.<br>
\[u\] - \[/u\] : Makes the text <u>underlined</u>.<br>
\[large\] - \[/large\] : Increases the <font size = \"4\">size</font> of the text.<br>
\[sign\] : Inserts a signature of your name in a foolproof way.<br>
\[field\] : Inserts an invisible field which lets you start type from there. Useful for forms.<br>
<br>
<b><center>Pen exclusive commands</center></b><br>
\[small\] - \[/small\] : Decreases the <font size = \"1\">size</font> of the text.<br>
\[list\] - \[/list\] : A list.<br>
\[*\] : A dot used for lists.<br>
\[hr\] : Adds a horizontal rule.
</BODY></HTML>"}, "window=paper_help")
/obj/item/weapon/paper/proc/burnpaper(obj/item/weapon/flame/P, mob/user)
var/class = "<span class='warning'>"
@@ -351,8 +326,8 @@
var/obj/item/i = usr.get_active_hand() // Check to see if he still got that darn pen, also check if he's using a crayon or pen.
var/iscrayon = 0
if(!istype(i, /obj/item/weapon/pen))
if(!istype(i, /obj/item/toy/crayon))
return
return
if(istype(i, /obj/item/weapon/pen/crayon))
iscrayon = 1
@@ -455,12 +430,12 @@
B.pages.Add(P)
B.update_icon()
else if(istype(P, /obj/item/weapon/pen) || istype(P, /obj/item/toy/crayon))
if ( istype(P, /obj/item/weapon/pen/robopen) && P:mode == 2 )
P:RenamePaper(user,src)
else if(istype(P, /obj/item/weapon/pen))
var/obj/item/weapon/pen/robopen/RP = P
if ( istype(RP) && RP.mode == 2 )
RP.RenamePaper(user,src)
else
user << browse("<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[info_links][stamps]</BODY></HTML>", "window=[name]")
//openhelp(user)
return
else if(istype(P, /obj/item/weapon/stamp))

View File

@@ -45,7 +45,7 @@
else
if(istype(W, /obj/item/weapon/tape_roll))
return 0
if(istype(W, /obj/item/weapon/pen) || istype(W, /obj/item/toy/crayon))
if(istype(W, /obj/item/weapon/pen))
usr << browse("", "window=[name]") //Closes the dialog
var/obj/P = pages[page]
P.attackby(W, user)

View File

@@ -167,3 +167,28 @@
colour = COLOR_BLACK
usr << "<span class='info'>You select the [lowertext(selected_type)] ink container.</span>"
/*
* Crayons
*/
/obj/item/weapon/pen/crayon
name = "crayon"
desc = "A colourful crayon. Please refrain from eating it or putting it in your nose."
icon = 'icons/obj/crayons.dmi'
icon_state = "crayonred"
w_class = 1.0
attack_verb = list("attacked", "coloured")
colour = "#FF0000" //RGB
var/shadeColour = "#220000" //RGB
var/uses = 30 //0 for unlimited uses
var/instant = 0
var/colourName = "red" //for updateIcon purposes
suicide_act(mob/user)
viewers(user) << "\red <b>[user] is jamming the [src.name] up \his nose and into \his brain. It looks like \he's trying to commit suicide.</b>"
return (BRUTELOSS|OXYLOSS)
New()
name = "[colourName] crayon"
..()

View File

@@ -42,7 +42,7 @@ var/global/photo_count = 0
user.examinate(src)
/obj/item/weapon/photo/attackby(obj/item/weapon/P as obj, mob/user as mob)
if(istype(P, /obj/item/weapon/pen) || istype(P, /obj/item/toy/crayon))
if(istype(P, /obj/item/weapon/pen))
var/txt = sanitize(input(user, "What would you like to write on the back?", "Photo Writing", null) as text, 128)
if(loc == user && user.stat == 0)
scribble = txt

View File

@@ -1224,11 +1224,10 @@ obj/machinery/power/apc/proc/autoset(var/val, var/on)
if( cell && cell.charge>=20)
cell.use(20);
spawn(0)
for(var/area/A in area.related)
for(var/obj/machinery/light/L in A)
L.on = 1
L.broken()
sleep(1)
for(var/obj/machinery/light/L in area)
L.on = 1
L.broken()
sleep(1)
/obj/machinery/power/apc/proc/setsubsystem(val)
if(cell && cell.charge > 0)

View File

@@ -11,6 +11,7 @@
icon_state = "gsmes"
var/cells_amount = 0
var/capacitors_amount = 0
var/global/list/br_cache = null
/obj/machinery/power/smes/batteryrack/New()
..()
@@ -48,15 +49,26 @@
/obj/machinery/power/smes/batteryrack/update_icon()
overlays.Cut()
if(stat & BROKEN) return
if(!br_cache)
br_cache = list()
br_cache.len = 7
br_cache[1] = image('icons/obj/power.dmi', "gsmes_outputting")
br_cache[2] = image('icons/obj/power.dmi', "gsmes_charging")
br_cache[3] = image('icons/obj/power.dmi', "gsmes_overcharge")
br_cache[4] = image('icons/obj/power.dmi', "gsmes_og1")
br_cache[5] = image('icons/obj/power.dmi', "gsmes_og2")
br_cache[6] = image('icons/obj/power.dmi', "gsmes_og3")
br_cache[7] = image('icons/obj/power.dmi', "gsmes_og4")
if (output_attempt)
overlays += image('icons/obj/power.dmi', "gsmes_outputting")
overlays += br_cache[1]
if(inputting)
overlays += image('icons/obj/power.dmi', "gsmes_charging")
overlays += br_cache[2]
var/clevel = chargedisplay()
if(clevel>0)
overlays += image('icons/obj/power.dmi', "gsmes_og[clevel]")
overlays += br_cache[3+clevel]
return
@@ -124,15 +136,15 @@
if(stat & BROKEN) return
if (output_attempt)
overlays += image('icons/obj/power.dmi', "gsmes_outputting")
overlays += br_cache[1]
if(inputting)
overlays += image('icons/obj/power.dmi', "gsmes_charging")
overlays += br_cache[2]
if (overcharge_percent > 100)
overlays += image('icons/obj/power.dmi', "gsmes_overcharge")
overlays += br_cache[3]
else
var/clevel = chargedisplay()
if(clevel>0)
overlays += image('icons/obj/power.dmi', "gsmes_og[clevel]")
overlays += br_cache[3+clevel]
return
//This mess of if-elses and magic numbers handles what happens if the engies don't pay attention and let it eat too much charge

View File

@@ -50,8 +50,8 @@
for(var/area/A in range(src,effectiverange))
if(A.name == "Space")
continue // No (de)gravitizing space.
if(A.master && !( A.master in localareas) )
localareas += A.master
if(!(A in localareas))
localareas += A
/obj/machinery/computer/gravity_control_computer/proc/findgenerator()
var/obj/machinery/gravity_generator/foundgenerator = null
@@ -125,7 +125,7 @@
for(var/area/A in gravity_generator:localareas)
var/obj/machinery/gravity_generator/G
for(G in machines)
if((A.master in G.localareas) && (G.on))
if((A in G.localareas) && (G.on))
break
if(!G)
A.gravitychange(0,A)
@@ -137,4 +137,4 @@
A.gravitychange(1,A)
src.updateUsrDialog()
return
return

View File

@@ -199,7 +199,9 @@
power_channel = LIGHT //Lights are calc'd via area so they dont need to be in the machine list
var/on = 0 // 1 if on, 0 if off
var/on_gs = 0
var/brightness = 8 // luminosity when on, also used in power calculation
var/brightness_range = 8 // luminosity when on, also used in power calculation
var/brightness_power = 3
var/brightness_color = null
var/status = LIGHT_OK // LIGHT_OK, _EMPTY, _BURNED or _BROKEN
var/flickering = 0
var/light_type = /obj/item/weapon/light/tube // the type of light item
@@ -215,7 +217,9 @@
icon_state = "bulb1"
base_state = "bulb"
fitting = "bulb"
brightness = 4
brightness_range = 4
brightness_power = 2
brightness_color = "#a0a080"
desc = "A small lighting fixture."
light_type = /obj/item/weapon/light/bulb
@@ -224,7 +228,8 @@
name = "spotlight"
fitting = "large tube"
light_type = /obj/item/weapon/light/tube/large
brightness = 12
brightness_range = 12
brightness_power = 4
/obj/machinery/light/built/New()
status = LIGHT_EMPTY
@@ -241,13 +246,20 @@
..()
spawn(2)
var/area/A = get_area(src)
if(A && !A.requires_power)
on = 1
switch(fitting)
if("tube")
brightness = 8
brightness_range = 8
brightness_power = 3
if(prob(2))
broken(1)
if("bulb")
brightness = 4
brightness_range = 4
brightness_power = 2
brightness_color = "#a0a080"
if(prob(5))
broken(1)
spawn(1)
@@ -281,7 +293,7 @@
update_icon()
if(on)
if(luminosity != brightness)
if(light_range != brightness_range || light_power != brightness_power || light_color != brightness_color)
switchcount++
if(rigged)
if(status == LIGHT_OK && trigger)
@@ -295,15 +307,15 @@
status = LIGHT_BURNED
icon_state = "[base_state]-burned"
on = 0
SetLuminosity(0)
set_light(0)
else
use_power = 2
SetLuminosity(brightness)
set_light(brightness_range, brightness_power, brightness_color)
else
use_power = 1
SetLuminosity(0)
set_light(0)
active_power_usage = (luminosity * 10)
active_power_usage = ((light_range + light_power) * 10)
if(on != on_gs)
on_gs = on
@@ -364,8 +376,9 @@
user << "You insert the [L.name]."
switchcount = L.switchcount
rigged = L.rigged
brightness = L.brightness
l_color = L.color
brightness_range = L.brightness_range
brightness_power = L.brightness_power
brightness_color = L.brightness_color
on = has_power()
update()
@@ -441,7 +454,7 @@
// true if area has power and lightswitch is on
/obj/machinery/light/proc/has_power()
var/area/A = src.loc.loc
return A.master.lightswitch && A.master.power_light
return A.lightswitch && A.power_light
/obj/machinery/light/proc/flicker(var/amount = rand(10, 20))
if(flickering) return
@@ -511,8 +524,9 @@
var/obj/item/weapon/light/L = new light_type()
L.status = status
L.rigged = rigged
L.brightness = src.brightness
L.color = l_color
L.brightness_range = brightness_range
L.brightness_power = brightness_power
L.brightness_color = brightness_color
// light item inherits the switchcount, then zero it
L.switchcount = switchcount
@@ -537,8 +551,9 @@
var/obj/item/weapon/light/L = new light_type()
L.status = status
L.rigged = rigged
L.brightness = brightness
L.color = l_color
L.brightness_range = brightness_range
L.brightness_power = brightness_power
L.brightness_color = brightness_color
// light item inherits the switchcount, then zero it
L.switchcount = switchcount
@@ -571,7 +586,6 @@
if(status == LIGHT_OK)
return
status = LIGHT_OK
brightness = initial(brightness)
on = 1
update()
@@ -606,14 +620,13 @@
/obj/machinery/light/process()
if(on)
use_power(luminosity * LIGHTING_POWER_FACTOR, LIGHT)
use_power(light_range * LIGHTING_POWER_FACTOR, LIGHT)
// called when area power state changes
/obj/machinery/light/power_change()
spawn(10)
var/area/A = src.loc.loc
A = A.master
seton(A.lightswitch && A.power_light)
// called when on fire
@@ -647,7 +660,9 @@
var/switchcount = 0 // number of times switched
matter = list("metal" = 60)
var/rigged = 0 // true if rigged to explode
var/brightness = 2 //how much light it gives off
var/brightness_range = 2 //how much light it gives off
var/brightness_power = 1
var/brightness_color = null
/obj/item/weapon/light/tube
name = "light tube"
@@ -656,12 +671,14 @@
base_state = "ltube"
item_state = "c_tube"
matter = list("glass" = 100)
brightness = 8
brightness_range = 8
brightness_power = 3
/obj/item/weapon/light/tube/large
w_class = 2
name = "large light tube"
brightness = 15
brightness_range = 15
brightness_power = 4
/obj/item/weapon/light/bulb
name = "light bulb"
@@ -670,7 +687,9 @@
base_state = "lbulb"
item_state = "contvapour"
matter = list("glass" = 100)
brightness = 5
brightness_range = 5
brightness_power = 2
brightness_color = "#a0a080"
/obj/item/weapon/light/throw_impact(atom/hit_atom)
..()
@@ -683,7 +702,8 @@
base_state = "fbulb"
item_state = "egg4"
matter = list("glass" = 100)
brightness = 5
brightness_range = 5
brightness_power = 2
// update the icon state and description of the light
@@ -704,9 +724,9 @@
..()
switch(name)
if("light tube")
brightness = rand(6,9)
brightness_range = rand(6,9)
if("light bulb")
brightness = rand(4,6)
brightness_range = rand(4,6)
update()

View File

@@ -69,20 +69,20 @@
// return 1
var/area/A = src.loc.loc // make sure it's in an area
if(!A || !isarea(A) || !A.master)
if(!A || !isarea(A))
return 0 // if not, then not powered
if(chan == -1)
chan = power_channel
return A.master.powered(chan) // return power status of the area
return A.powered(chan) // return power status of the area
// increment the power usage stats for an area
/obj/machinery/proc/use_power(var/amount, var/chan = -1) // defaults to power_channel
var/area/A = get_area(src) // make sure it's in an area
if(!A || !isarea(A) || !A.master)
if(!A || !isarea(A))
return
if(chan == -1)
chan = power_channel
A.master.use_power(amount, chan)
A.use_power(amount, chan)
/obj/machinery/proc/power_change() // called whenever the power settings of the containing area change
// by default, check equipment channel & set flag

View File

@@ -150,7 +150,6 @@
return null
/area/proc/get_apc()
for(var/area/RA in src.related)
var/obj/machinery/power/apc/FINDME = locate() in RA
if (FINDME)
return FINDME
var/obj/machinery/power/apc/FINDME = locate() in src
if (FINDME)
return FINDME

View File

@@ -8,6 +8,7 @@
desc = "Computer designed to remotely monitor power levels around the station"
icon = 'icons/obj/computer.dmi'
icon_state = "power"
light_color = "#ffcc33"
//computer stuff
density = 1

View File

@@ -38,17 +38,19 @@
..()
/obj/singularity_act()
ex_act(1)
if(src)
qdel(src)
return 2
if(simulated)
ex_act(1)
if(src)
qdel(src)
return 2
/obj/singularity_pull(S, current_size)
if(anchored)
if(current_size >= STAGE_FIVE)
if(simulated)
if(anchored)
if(current_size >= STAGE_FIVE)
step_towards(src, S)
else
step_towards(src, S)
else
step_towards(src, S)
/obj/effect/beam/singularity_pull()
return

View File

@@ -9,7 +9,7 @@
density = 0
unacidable = 1
use_power = 0
luminosity = 4
light_range = 4
var/obj/machinery/field_generator/FG1 = null
var/obj/machinery/field_generator/FG2 = null
var/hasShocked = 0 //Used to add a delay between shocks. In some cases this used to crash servers by spawning hundreds of sparks every second.

View File

@@ -31,8 +31,8 @@ var/global/list/narsie_list = list()
// Pixel stuff centers Narsie.
pixel_x = -236
pixel_y = -256
luminosity = 1
l_color = "#3e0000"
light_range = 1
light_color = "#3e0000"
current_size = 12
consume_range = 12 // How many tiles out do we eat.
@@ -144,7 +144,7 @@ var/global/list/narsie_list = list()
if(T.icon_state != "cult-narsie")
T.desc = "something that goes beyond your understanding went this way"
T.icon_state = "cult-narsie"
T.luminosity = 1
T.set_light(1)
/obj/singularity/narsie/proc/narsiewall(var/turf/T)
T.desc = "An opening has been made on that wall, but who can say if what you seek truly lies on the other side?"
@@ -152,7 +152,7 @@ var/global/list/narsie_list = list()
T.icon_state = "cult-narsie"
T.opacity = 0
T.density = 0
luminosity = 1
set_light(1)
/obj/singularity/narsie/large/consume(const/atom/A) //Has its own consume proc because it doesn't need energy and I don't want BoHs to explode it. --NEO
//NEW BEHAVIOUR

View File

@@ -8,7 +8,7 @@
anchored = 1
density = 1
layer = 6
luminosity = 6
light_range = 6
unacidable = 1 //Don't comment this out.
var/current_size = 1

View File

@@ -57,6 +57,7 @@
var/fire_sound_text = "gunshot"
var/recoil = 0 //screen shake
var/silenced = 0
var/muzzle_flash = 3
var/accuracy = 0 //accuracy is measured in tiles. +1 accuracy means that everything is effectively one tile closer for the purpose of miss chance, -1 means the opposite. launchers are not supported, at the moment.
var/scoped_accuracy = null
@@ -245,6 +246,12 @@
"You hear a [fire_sound_text]!"
)
if(muzzle_flash)
var/turf/T_user = get_turf(user)
var/turf/T_target = get_turf(target)
var/obj/effect/effect/smoke/illumination/I = new /obj/effect/effect/smoke/illumination(get_step(T_user, get_dir(T_user,T_target)), brightness=muzzle_flash, lifetime=8)
I.alpha = 0
if(recoil)
spawn()
shake_camera(user, recoil+1, recoil)

View File

@@ -18,7 +18,7 @@
var/projectile_type = /obj/item/projectile/beam/practice
var/modifystate
var/charge_meter = 1 //if set, the icon state will be chosen based on the current charge
//self-recharging
var/self_recharge = 0 //if set, the weapon will recharge itself
var/use_external_power = 0 //if set, the weapon will look for an external power source to draw from, otherwise it recharges magically
@@ -33,7 +33,7 @@
modifystate = isnull(current_mode.modifystate)? initial(modifystate) : current_mode.modifystate
charge_cost = isnull(current_mode.charge_cost)? initial(charge_cost) : current_mode.charge_cost
fire_sound = isnull(current_mode.fire_sound)? initial(fire_sound) : current_mode.fire_sound
update_icon()
update_held_icon()
@@ -60,15 +60,15 @@
charge_tick++
if(charge_tick < recharge_time) return 0
charge_tick = 0
if(!power_supply || power_supply.charge >= power_supply.maxcharge)
return 0 // check if we actually need to recharge
if(use_external_power)
var/obj/item/weapon/cell/external = get_external_power_supply()
if(!external || !external.use(charge_cost)) //Take power from the borg...
return 0
power_supply.give(charge_cost) //... to recharge the shot
update_icon()
return 1
@@ -93,16 +93,22 @@
return suit.cell
return null
/obj/item/weapon/gun/energy/examine(mob/user)
..(user)
var/shots_remaining = round(power_supply.charge / charge_cost)
user << "Has [shots_remaining] shot\s remaining."
return
/obj/item/weapon/gun/energy/update_icon()
if(charge_meter)
var/ratio = power_supply.charge / power_supply.maxcharge
//make sure that rounding down will not give us the empty state even if we have charge for a shot left.
if(power_supply.charge < charge_cost)
ratio = 0
else
ratio = max(round(ratio, 0.25) * 100, 25)
if(modifystate)
icon_state = "[modifystate][ratio]"
else

View File

@@ -7,6 +7,7 @@
var/release_force = 0
var/throw_distance = 10
muzzle_flash = 0
fire_sound_text = "a launcher firing"
//This normally uses a proc on projectiles and our ammo is not strictly speaking a projectile.

View File

@@ -487,8 +487,8 @@
qdel(src)
/obj/item/weapon/reagent_containers/food/snacks/egg/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype( W, /obj/item/toy/crayon ))
var/obj/item/toy/crayon/C = W
if(istype( W, /obj/item/weapon/pen/crayon ))
var/obj/item/weapon/pen/crayon/C = W
var/clr = C.colourName
if(!(clr in list("blue","green","mime","orange","purple","rainbow","red","yellow")))

View File

@@ -30,6 +30,7 @@ won't update every console in existence) but it's more of a hassle to do. Also,
/obj/machinery/computer/rdconsole
name = "R&D control console"
icon_state = "rdcomp"
light_color = "#a97faa"
circuit = /obj/item/weapon/circuitboard/rdconsole
var/datum/research/files //Stores all the collected research data.
var/obj/item/weapon/disk/tech_disk/t_disk = null //Stores the technology disk.

View File

@@ -196,6 +196,7 @@
/obj/machinery/computer/rdservercontrol
name = "R&D Server Controller"
icon_state = "rdcomp"
light_color = "#a97faa"
circuit = /obj/item/weapon/circuitboard/rdservercontrol
var/screen = 0
var/obj/machinery/r_n_d/server/temp_server
@@ -355,4 +356,4 @@
name = "Core R&D Server"
id_with_upload_string = "1"
id_with_download_string = "1"
server_id = 1
server_id = 1

View File

@@ -228,7 +228,7 @@
anchored = 1
density = 1
unacidable = 1
luminosity = 3
light_range = 3
var/needs_power = 0
var/active = 1
// var/power = 10

View File

@@ -130,8 +130,8 @@
name = "Juggerwall"
icon = 'icons/effects/effects.dmi'
icon_state = "m_shield_cult"
l_color = "#B40000"
luminosity = 2
light_color = "#B40000"
light_range = 2
/obj/effect/forcefield/cult/cultify()
return

View File

@@ -37,7 +37,7 @@
icon_state = "darkmatter"
density = 1
anchored = 0
luminosity = 4
light_range = 4
var/gasefficency = 0.25
@@ -54,7 +54,7 @@
var/emergency_alert = "CRYSTAL DELAMINATION IMMINENT."
var/explosion_point = 1000
l_color = "#8A8A00"
light_color = "#8A8A00"
var/warning_color = "#B8B800"
var/emergency_color = "#D9D900"
@@ -117,10 +117,8 @@
//Changes color and luminosity of the light to these values if they were not already set
/obj/machinery/power/supermatter/proc/shift_light(var/lum, var/clr)
if(l_color != clr)
l_color = clr
if(luminosity != lum)
SetLuminosity(lum)
if(lum != light_range || clr != light_color)
set_light(lum, l_color = clr)
/obj/machinery/power/supermatter/proc/announce_warning()
var/integrity = damage / explosion_point
@@ -174,7 +172,7 @@
if(!istype(L, /turf/space) && (world.timeofday - lastwarning) >= WARNING_DELAY * 10)
announce_warning()
else
shift_light(4,initial(l_color))
shift_light(4,initial(light_color))
if(grav_pulling)
supermatter_pull()

View File

@@ -11,7 +11,7 @@
density = 1
anchored = 1
animate_movement=1
luminosity = 3
light_range = 3
can_buckle = 1
buckle_movable = 1
@@ -181,13 +181,13 @@
if(powered && cell.charge < charge_use)
return 0
on = 1
luminosity = initial(luminosity)
set_light(initial(light_range))
update_icon()
return 1
/obj/vehicle/proc/turn_off()
on = 0
luminosity = 0
set_light(0)
update_icon()
/obj/vehicle/proc/Emag(mob/user as mob)
@@ -367,4 +367,4 @@
if(prob(10))
new /obj/effect/decal/cleanable/blood/oil(src.loc)
spawn(1) healthcheck()
return 1
return 1