Merge branch 'Ghommie-cit265' of https://github.com/Ghommie/Citadel-Station-13 into Ghommie-cit435

This commit is contained in:
Ghommie
2020-01-12 23:21:03 +01:00
2163 changed files with 249943 additions and 224792 deletions
+222 -221
View File
@@ -1,222 +1,223 @@
#define CAMERA_PICTURE_SIZE_HARD_LIMIT 21
/obj/item/camera
name = "camera"
icon = 'icons/obj/items_and_weapons.dmi'
desc = "A polaroid camera."
icon_state = "camera"
item_state = "camera"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
light_color = LIGHT_COLOR_WHITE
light_power = FLASH_LIGHT_POWER
w_class = WEIGHT_CLASS_SMALL
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_NECK
materials = list(MAT_METAL = 50, MAT_GLASS = 150)
var/flash_enabled = TRUE
var/state_on = "camera"
var/state_off = "camera_off"
var/pictures_max = 10
var/pictures_left = 10
var/on = TRUE
var/cooldown = 64
var/blending = FALSE //lets not take pictures while the previous is still processing!
var/see_ghosts = CAMERA_NO_GHOSTS //for the spoop of it
var/obj/item/disk/holodisk/disk
var/sound/custom_sound
var/silent = FALSE
var/picture_size_x = 2
var/picture_size_y = 2
var/picture_size_x_min = 1
var/picture_size_y_min = 1
var/picture_size_x_max = 4
var/picture_size_y_max = 4
var/can_customise = TRUE
var/default_picture_name
/obj/item/camera/attack_self(mob/user)
if(!disk)
return
to_chat(user, "<span class='notice'>You eject [disk] out the back of [src].</span>")
user.put_in_hands(disk)
disk = null
/obj/item/camera/examine(mob/user)
. = ..()
. += "<span class='notice'>Alt-click to change its focusing, allowing you to set how big of an area it will capture.</span>"
/obj/item/camera/AltClick(mob/user)
if(!user.canUseTopic(src, BE_CLOSE))
return
var/desired_x = input(user, "How high do you want the camera to shoot, between [picture_size_x_min] and [picture_size_x_max]?", "Zoom", picture_size_x) as num
var/desired_y = input(user, "How wide do you want the camera to shoot, between [picture_size_y_min] and [picture_size_y_max]?", "Zoom", picture_size_y) as num
picture_size_x = min(CLAMP(desired_x, picture_size_x_min, picture_size_x_max), CAMERA_PICTURE_SIZE_HARD_LIMIT)
picture_size_y = min(CLAMP(desired_y, picture_size_y_min, picture_size_y_max), CAMERA_PICTURE_SIZE_HARD_LIMIT)
/obj/item/camera/attack(mob/living/carbon/human/M, mob/user)
return
/obj/item/camera/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/camera_film))
if(pictures_left)
to_chat(user, "<span class='notice'>[src] still has some film in it!</span>")
return
if(!user.temporarilyRemoveItemFromInventory(I))
return
to_chat(user, "<span class='notice'>You insert [I] into [src].</span>")
qdel(I)
pictures_left = pictures_max
return
if(istype(I, /obj/item/disk/holodisk))
if (!disk)
if(!user.transferItemToLoc(I, src))
to_chat(user, "<span class='warning'>[I] is stuck to your hand!</span>")
return TRUE
to_chat(user, "<span class='notice'>You slide [I] into the back of [src].</span>")
disk = I
else
to_chat(user, "<span class='warning'>There's already a disk inside [src].</span>")
return TRUE //no afterattack
..()
/obj/item/camera/examine(mob/user)
. = ..()
. += "It has [pictures_left] photos left."
//user can be atom or mob
/obj/item/camera/proc/can_target(atom/target, mob/user, prox_flag)
if(!on || blending || !pictures_left)
return FALSE
var/turf/T = get_turf(target)
if(!T)
return FALSE
if(istype(user))
if(isAI(user) && !GLOB.cameranet.checkTurfVis(T))
return FALSE
else if(user.client && !(get_turf(target) in get_hear(user.client.view, user)))
return FALSE
else if(!(get_turf(target) in get_hear(world.view, user)))
return FALSE
else //user is an atom
if(!(get_turf(target) in view(world.view, user)))
return FALSE
return TRUE
/obj/item/camera/afterattack(atom/target, mob/user, flag)
if (disk)
if(ismob(target))
if (disk.record)
QDEL_NULL(disk.record)
disk.record = new
var/mob/M = target
disk.record.caller_name = M.name
disk.record.set_caller_image(M)
else
to_chat(user, "<span class='warning'>Invalid holodisk target.</span>")
return
if(!can_target(target, user, flag))
return
on = FALSE
var/realcooldown = cooldown
var/mob/living/carbon/human/H = user
if (HAS_TRAIT(H, TRAIT_PHOTOGRAPHER))
realcooldown *= 0.5
addtimer(CALLBACK(src, .proc/cooldown), realcooldown)
icon_state = state_off
INVOKE_ASYNC(src, .proc/captureimage, target, user, flag, picture_size_x - 1, picture_size_y - 1)
/obj/item/camera/proc/cooldown()
UNTIL(!blending)
icon_state = state_on
on = TRUE
/obj/item/camera/proc/show_picture(mob/user, datum/picture/selection)
var/obj/item/photo/P = new(src, selection)
P.show(user)
to_chat(user, P.desc)
qdel(P)
/obj/item/camera/proc/captureimage(atom/target, mob/user, flag, size_x = 1, size_y = 1)
if(flash_enabled)
flash_lighting_fx(8, light_power, light_color)
blending = TRUE
var/turf/target_turf = get_turf(target)
if(!isturf(target_turf))
blending = FALSE
return FALSE
size_x = CLAMP(size_x, 0, CAMERA_PICTURE_SIZE_HARD_LIMIT)
size_y = CLAMP(size_y, 0, CAMERA_PICTURE_SIZE_HARD_LIMIT)
var/list/desc = list("This is a photo of an area of [size_x+1] meters by [size_y+1] meters.")
var/ai_user = isAI(user)
var/list/seen
var/list/viewlist = (user && user.client)? getviewsize(user.client.view) : getviewsize(world.view)
var/viewr = max(viewlist[1], viewlist[2]) + max(size_x, size_y)
var/viewc = user.client? user.client.eye : target
seen = get_hear(viewr, viewc)
var/list/turfs = list()
var/list/mobs = list()
var/blueprints = FALSE
var/clone_area = SSmapping.RequestBlockReservation(size_x * 2 + 1, size_y * 2 + 1)
for(var/turf/T in block(locate(target_turf.x - size_x, target_turf.y - size_y, target_turf.z), locate(target_turf.x + size_x, target_turf.y + size_y, target_turf.z)))
if((ai_user && GLOB.cameranet.checkTurfVis(T)) || (T in seen))
turfs += T
for(var/mob/M in T)
mobs += M
if(locate(/obj/item/areaeditor/blueprints) in T)
blueprints = TRUE
for(var/i in mobs)
var/mob/M = i
desc += M.get_photo_description(src)
var/psize_x = (size_x * 2 + 1) * world.icon_size
var/psize_y = (size_y * 2 + 1) * world.icon_size
var/get_icon = camera_get_icon(turfs, target_turf, psize_x, psize_y, clone_area, size_x, size_y, (size_x * 2 + 1), (size_y * 2 + 1))
qdel(clone_area)
var/icon/temp = icon('icons/effects/96x96.dmi',"")
temp.Blend("#000", ICON_OVERLAY)
temp.Scale(psize_x, psize_y)
temp.Blend(get_icon, ICON_OVERLAY)
var/datum/picture/P = new("picture", desc.Join(" "), temp, null, psize_x, psize_y, blueprints)
after_picture(user, P, flag)
blending = FALSE
/obj/item/camera/proc/after_picture(mob/user, datum/picture/picture, proximity_flag)
printpicture(user, picture)
/obj/item/camera/proc/printpicture(mob/user, datum/picture/picture) //Normal camera proc for creating photos
var/obj/item/photo/p = new(get_turf(src), picture)
if(in_range(src, user)) //needed because of TK
user.put_in_hands(p)
pictures_left--
to_chat(user, "<span class='notice'>[pictures_left] photos left.</span>")
var/customise = "No"
if(can_customise)
customise = alert(user, "Do you want to customize the photo?", "Customization", "Yes", "No")
if(customise == "Yes")
var/name1 = stripped_input(user, "Set a name for this photo, or leave blank. 32 characters max.", "Name", max_length = 32)
var/desc1 = stripped_input(user, "Set a description to add to photo, or leave blank. 128 characters max.", "Caption", max_length = 128)
var/caption = stripped_input(user, "Set a caption for this photo, or leave blank. 256 characters max.", "Caption", max_length = 256)
if(name1)
picture.picture_name = name1
if(desc1)
picture.picture_desc = "[desc1] - [picture.picture_desc]"
if(caption)
picture.caption = caption
else
if(default_picture_name)
picture.picture_name = default_picture_name
p.set_picture(picture, TRUE, TRUE)
if(CONFIG_GET(flag/picture_logging_camera))
#define CAMERA_PICTURE_SIZE_HARD_LIMIT 21
/obj/item/camera
name = "camera"
icon = 'icons/obj/items_and_weapons.dmi'
desc = "A polaroid camera."
icon_state = "camera"
item_state = "camera"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
light_color = LIGHT_COLOR_WHITE
light_power = FLASH_LIGHT_POWER
w_class = WEIGHT_CLASS_SMALL
flags_1 = CONDUCT_1
slot_flags = ITEM_SLOT_NECK
materials = list(MAT_METAL = 50, MAT_GLASS = 150)
var/flash_enabled = TRUE
var/state_on = "camera"
var/state_off = "camera_off"
var/pictures_max = 10
var/pictures_left = 10
var/on = TRUE
var/cooldown = 64
var/blending = FALSE //lets not take pictures while the previous is still processing!
var/see_ghosts = CAMERA_NO_GHOSTS //for the spoop of it
var/obj/item/disk/holodisk/disk
var/sound/custom_sound
var/silent = FALSE
var/picture_size_x = 2
var/picture_size_y = 2
var/picture_size_x_min = 1
var/picture_size_y_min = 1
var/picture_size_x_max = 4
var/picture_size_y_max = 4
var/can_customise = TRUE
var/default_picture_name
/obj/item/camera/attack_self(mob/user)
if(!disk)
return
to_chat(user, "<span class='notice'>You eject [disk] out the back of [src].</span>")
user.put_in_hands(disk)
disk = null
/obj/item/camera/examine(mob/user)
. = ..()
. += "<span class='notice'>Alt-click to change its focusing, allowing you to set how big of an area it will capture.</span>"
/obj/item/camera/AltClick(mob/user)
. = ..()
if(!user.canUseTopic(src, BE_CLOSE))
return
var/desired_x = input(user, "How high do you want the camera to shoot, between [picture_size_x_min] and [picture_size_x_max]?", "Zoom", picture_size_x) as num
var/desired_y = input(user, "How wide do you want the camera to shoot, between [picture_size_y_min] and [picture_size_y_max]?", "Zoom", picture_size_y) as num
picture_size_x = min(CLAMP(desired_x, picture_size_x_min, picture_size_x_max), CAMERA_PICTURE_SIZE_HARD_LIMIT)
picture_size_y = min(CLAMP(desired_y, picture_size_y_min, picture_size_y_max), CAMERA_PICTURE_SIZE_HARD_LIMIT)
return TRUE
/obj/item/camera/attack(mob/living/carbon/human/M, mob/user)
return
/obj/item/camera/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/camera_film))
if(pictures_left)
to_chat(user, "<span class='notice'>[src] still has some film in it!</span>")
return
if(!user.temporarilyRemoveItemFromInventory(I))
return
to_chat(user, "<span class='notice'>You insert [I] into [src].</span>")
qdel(I)
pictures_left = pictures_max
return
if(istype(I, /obj/item/disk/holodisk))
if (!disk)
if(!user.transferItemToLoc(I, src))
to_chat(user, "<span class='warning'>[I] is stuck to your hand!</span>")
return TRUE
to_chat(user, "<span class='notice'>You slide [I] into the back of [src].</span>")
disk = I
else
to_chat(user, "<span class='warning'>There's already a disk inside [src].</span>")
return TRUE //no afterattack
..()
/obj/item/camera/examine(mob/user)
. = ..()
. += "It has [pictures_left] photos left."
//user can be atom or mob
/obj/item/camera/proc/can_target(atom/target, mob/user, prox_flag)
if(!on || blending || !pictures_left)
return FALSE
var/turf/T = get_turf(target)
if(!T)
return FALSE
if(istype(user))
if(isAI(user) && !GLOB.cameranet.checkTurfVis(T))
return FALSE
else if(user.client && !(get_turf(target) in get_hear(user.client.view, user)))
return FALSE
else if(!(get_turf(target) in get_hear(world.view, user)))
return FALSE
else //user is an atom
if(!(get_turf(target) in view(world.view, user)))
return FALSE
return TRUE
/obj/item/camera/afterattack(atom/target, mob/user, flag)
if (disk)
if(ismob(target))
if (disk.record)
QDEL_NULL(disk.record)
disk.record = new
var/mob/M = target
disk.record.caller_name = M.name
disk.record.set_caller_image(M)
else
to_chat(user, "<span class='warning'>Invalid holodisk target.</span>")
return
if(!can_target(target, user, flag))
return
on = FALSE
var/realcooldown = cooldown
var/mob/living/carbon/human/H = user
if (HAS_TRAIT(H, TRAIT_PHOTOGRAPHER))
realcooldown *= 0.5
addtimer(CALLBACK(src, .proc/cooldown), realcooldown)
icon_state = state_off
INVOKE_ASYNC(src, .proc/captureimage, target, user, flag, picture_size_x - 1, picture_size_y - 1)
/obj/item/camera/proc/cooldown()
UNTIL(!blending)
icon_state = state_on
on = TRUE
/obj/item/camera/proc/show_picture(mob/user, datum/picture/selection)
var/obj/item/photo/P = new(src, selection)
P.show(user)
to_chat(user, P.desc)
qdel(P)
/obj/item/camera/proc/captureimage(atom/target, mob/user, flag, size_x = 1, size_y = 1)
if(flash_enabled)
flash_lighting_fx(8, light_power, light_color)
blending = TRUE
var/turf/target_turf = get_turf(target)
if(!isturf(target_turf))
blending = FALSE
return FALSE
size_x = CLAMP(size_x, 0, CAMERA_PICTURE_SIZE_HARD_LIMIT)
size_y = CLAMP(size_y, 0, CAMERA_PICTURE_SIZE_HARD_LIMIT)
var/list/desc = list("This is a photo of an area of [size_x+1] meters by [size_y+1] meters.")
var/ai_user = isAI(user)
var/list/seen
var/list/viewlist = (user && user.client)? getviewsize(user.client.view) : getviewsize(world.view)
var/viewr = max(viewlist[1], viewlist[2]) + max(size_x, size_y)
var/viewc = user.client? user.client.eye : target
seen = get_hear(viewr, viewc)
var/list/turfs = list()
var/list/mobs = list()
var/blueprints = FALSE
var/clone_area = SSmapping.RequestBlockReservation(size_x * 2 + 1, size_y * 2 + 1)
for(var/turf/T in block(locate(target_turf.x - size_x, target_turf.y - size_y, target_turf.z), locate(target_turf.x + size_x, target_turf.y + size_y, target_turf.z)))
if((ai_user && GLOB.cameranet.checkTurfVis(T)) || (T in seen))
turfs += T
for(var/mob/M in T)
mobs += M
if(locate(/obj/item/areaeditor/blueprints) in T)
blueprints = TRUE
for(var/i in mobs)
var/mob/M = i
desc += M.get_photo_description(src)
var/psize_x = (size_x * 2 + 1) * world.icon_size
var/psize_y = (size_y * 2 + 1) * world.icon_size
var/get_icon = camera_get_icon(turfs, target_turf, psize_x, psize_y, clone_area, size_x, size_y, (size_x * 2 + 1), (size_y * 2 + 1))
qdel(clone_area)
var/icon/temp = icon('icons/effects/96x96.dmi',"")
temp.Blend("#000", ICON_OVERLAY)
temp.Scale(psize_x, psize_y)
temp.Blend(get_icon, ICON_OVERLAY)
var/datum/picture/P = new("picture", desc.Join(" "), temp, null, psize_x, psize_y, blueprints)
after_picture(user, P, flag)
blending = FALSE
/obj/item/camera/proc/after_picture(mob/user, datum/picture/picture, proximity_flag)
printpicture(user, picture)
/obj/item/camera/proc/printpicture(mob/user, datum/picture/picture) //Normal camera proc for creating photos
var/obj/item/photo/p = new(get_turf(src), picture)
if(in_range(src, user)) //needed because of TK
user.put_in_hands(p)
pictures_left--
to_chat(user, "<span class='notice'>[pictures_left] photos left.</span>")
var/customise = "No"
if(can_customise)
customise = alert(user, "Do you want to customize the photo?", "Customization", "Yes", "No")
if(customise == "Yes")
var/name1 = stripped_input(user, "Set a name for this photo, or leave blank. 32 characters max.", "Name", max_length = 32)
var/desc1 = stripped_input(user, "Set a description to add to photo, or leave blank. 128 characters max.", "Caption", max_length = 128)
var/caption = stripped_input(user, "Set a caption for this photo, or leave blank. 256 characters max.", "Caption", max_length = 256)
if(name1)
picture.picture_name = name1
if(desc1)
picture.picture_desc = "[desc1] - [picture.picture_desc]"
if(caption)
picture.caption = caption
else
if(default_picture_name)
picture.picture_name = default_picture_name
p.set_picture(picture, TRUE, TRUE)
if(CONFIG_GET(flag/picture_logging_camera))
picture.log_to_file()
@@ -1,89 +1,89 @@
/obj/effect/appearance_clone
/obj/effect/appearance_clone/New(loc, atom/A) //Intentionally not Initialize(), to make sure the clone assumes the intended appearance in time for the camera getFlatIcon.
if(istype(A))
appearance = A.appearance
dir = A.dir
if(ismovableatom(A))
var/atom/movable/AM = A
step_x = AM.step_x
step_y = AM.step_y
. = ..()
/obj/item/camera/proc/camera_get_icon(list/turfs, turf/center, psize_x = 96, psize_y = 96, datum/turf_reservation/clone_area, size_x, size_y, total_x, total_y)
var/list/atoms = list()
var/skip_normal = FALSE
var/wipe_atoms = FALSE
if(istype(clone_area) && total_x == clone_area.width && total_y == clone_area.height && size_x >= 0 && size_y > 0)
var/cloned_center_x = round(clone_area.bottom_left_coords[1] + ((total_x - 1) / 2))
var/cloned_center_y = round(clone_area.bottom_left_coords[2] + ((total_y - 1) / 2))
for(var/t in turfs)
var/turf/T = t
var/offset_x = T.x - center.x
var/offset_y = T.y - center.y
var/turf/newT = locate(cloned_center_x + offset_x, cloned_center_y + offset_y, clone_area.bottom_left_coords[3])
if(!(newT in clone_area.reserved_turfs)) //sanity check so we don't overwrite other areas somehow
continue
atoms += new /obj/effect/appearance_clone(newT, T)
if(T.loc.icon_state)
atoms += new /obj/effect/appearance_clone(newT, T.loc)
for(var/i in T.contents)
var/atom/A = i
if(!A.invisibility || (see_ghosts && isobserver(A)))
atoms += new /obj/effect/appearance_clone(newT, A)
skip_normal = TRUE
wipe_atoms = TRUE
center = locate(cloned_center_x, cloned_center_y, clone_area.bottom_left_coords[3])
if(!skip_normal)
for(var/i in turfs)
var/turf/T = i
atoms += T
for(var/atom/movable/A in T)
if(A.invisibility)
if(!(see_ghosts && isobserver(A)))
continue
atoms += A
CHECK_TICK
var/icon/res = icon('icons/effects/96x96.dmi', "")
res.Scale(psize_x, psize_y)
var/list/sorted = list()
var/j
for(var/i in 1 to atoms.len)
var/atom/c = atoms[i]
for(j = sorted.len, j > 0, --j)
var/atom/c2 = sorted[j]
if(c2.layer <= c.layer)
break
sorted.Insert(j+1, c)
CHECK_TICK
var/xcomp = FLOOR(psize_x / 2, 1) - 15
var/ycomp = FLOOR(psize_y / 2, 1) - 15
for(var/atom/A in sorted)
var/xo = (A.x - center.x) * world.icon_size + A.pixel_x + xcomp
var/yo = (A.y - center.y) * world.icon_size + A.pixel_y + ycomp
if(ismovableatom(A))
var/atom/movable/AM = A
xo += AM.step_x
yo += AM.step_y
var/icon/img = getFlatIcon(A)
if(img)
res.Blend(img, blendMode2iconMode(A.blend_mode), xo, yo)
CHECK_TICK
if(!silent)
if(istype(custom_sound)) //This is where the camera actually finishes its exposure.
playsound(loc, custom_sound, 75, 1, -3)
else
playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 75, 1, -3)
if(wipe_atoms)
QDEL_LIST(atoms)
return res
/obj/effect/appearance_clone
/obj/effect/appearance_clone/New(loc, atom/A) //Intentionally not Initialize(), to make sure the clone assumes the intended appearance in time for the camera getFlatIcon.
if(istype(A))
appearance = A.appearance
dir = A.dir
if(ismovableatom(A))
var/atom/movable/AM = A
step_x = AM.step_x
step_y = AM.step_y
. = ..()
/obj/item/camera/proc/camera_get_icon(list/turfs, turf/center, psize_x = 96, psize_y = 96, datum/turf_reservation/clone_area, size_x, size_y, total_x, total_y)
var/list/atoms = list()
var/skip_normal = FALSE
var/wipe_atoms = FALSE
if(istype(clone_area) && total_x == clone_area.width && total_y == clone_area.height && size_x >= 0 && size_y > 0)
var/cloned_center_x = round(clone_area.bottom_left_coords[1] + ((total_x - 1) / 2))
var/cloned_center_y = round(clone_area.bottom_left_coords[2] + ((total_y - 1) / 2))
for(var/t in turfs)
var/turf/T = t
var/offset_x = T.x - center.x
var/offset_y = T.y - center.y
var/turf/newT = locate(cloned_center_x + offset_x, cloned_center_y + offset_y, clone_area.bottom_left_coords[3])
if(!(newT in clone_area.reserved_turfs)) //sanity check so we don't overwrite other areas somehow
continue
atoms += new /obj/effect/appearance_clone(newT, T)
if(T.loc.icon_state)
atoms += new /obj/effect/appearance_clone(newT, T.loc)
for(var/i in T.contents)
var/atom/A = i
if(!A.invisibility || (see_ghosts && isobserver(A)))
atoms += new /obj/effect/appearance_clone(newT, A)
skip_normal = TRUE
wipe_atoms = TRUE
center = locate(cloned_center_x, cloned_center_y, clone_area.bottom_left_coords[3])
if(!skip_normal)
for(var/i in turfs)
var/turf/T = i
atoms += T
for(var/atom/movable/A in T)
if(A.invisibility)
if(!(see_ghosts && isobserver(A)))
continue
atoms += A
CHECK_TICK
var/icon/res = icon('icons/effects/96x96.dmi', "")
res.Scale(psize_x, psize_y)
var/list/sorted = list()
var/j
for(var/i in 1 to atoms.len)
var/atom/c = atoms[i]
for(j = sorted.len, j > 0, --j)
var/atom/c2 = sorted[j]
if(c2.layer <= c.layer)
break
sorted.Insert(j+1, c)
CHECK_TICK
var/xcomp = FLOOR(psize_x / 2, 1) - 15
var/ycomp = FLOOR(psize_y / 2, 1) - 15
for(var/atom/A in sorted)
var/xo = (A.x - center.x) * world.icon_size + A.pixel_x + xcomp
var/yo = (A.y - center.y) * world.icon_size + A.pixel_y + ycomp
if(ismovableatom(A))
var/atom/movable/AM = A
xo += AM.step_x
yo += AM.step_y
var/icon/img = getFlatIcon(A)
if(img)
res.Blend(img, blendMode2iconMode(A.blend_mode), xo, yo)
CHECK_TICK
if(!silent)
if(istype(custom_sound)) //This is where the camera actually finishes its exposure.
playsound(loc, custom_sound, 75, 1, -3)
else
playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 75, 1, -3)
if(wipe_atoms)
QDEL_LIST(atoms)
return res
+14 -14
View File
@@ -1,14 +1,14 @@
/*
* Film
*/
/obj/item/camera_film
name = "film cartridge"
icon = 'icons/obj/items_and_weapons.dmi'
desc = "A camera film cartridge. Insert it into a camera to reload it."
icon_state = "film"
item_state = "electropack"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
w_class = WEIGHT_CLASS_TINY
resistance_flags = FLAMMABLE
materials = list(MAT_METAL = 10, MAT_GLASS = 10)
/*
* Film
*/
/obj/item/camera_film
name = "film cartridge"
icon = 'icons/obj/items_and_weapons.dmi'
desc = "A camera film cartridge. Insert it into a camera to reload it."
icon_state = "film"
item_state = "electropack"
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
w_class = WEIGHT_CLASS_TINY
resistance_flags = FLAMMABLE
materials = list(MAT_METAL = 10, MAT_GLASS = 10)
+21 -21
View File
@@ -1,21 +1,21 @@
/obj/item/camera/spooky
name = "camera obscura"
desc = "A polaroid camera, some say it can see ghosts!"
see_ghosts = CAMERA_SEE_GHOSTS_BASIC
/obj/item/camera/spooky/badmin
desc = "A polaroid camera, some say it can see ghosts! It seems to have an extra magnifier on the end."
see_ghosts = CAMERA_SEE_GHOSTS_ORBIT
/obj/item/camera/detective
name = "Detective's camera"
desc = "A polaroid camera with extra capacity for crime investigations."
pictures_max = 30
pictures_left = 30
/obj/item/camera/spooky/family
name = "fancy camera"
desc = "A fancy camera that has the latest magnifier mods and double the film load! With a complex double lens set with holy water to be able to see the dead, at laest to the Chaplain..."
see_ghosts = CAMERA_SEE_GHOSTS_ORBIT
pictures_max = 30
pictures_left = 30
/obj/item/camera/spooky
name = "camera obscura"
desc = "A polaroid camera, some say it can see ghosts!"
see_ghosts = CAMERA_SEE_GHOSTS_BASIC
/obj/item/camera/spooky/badmin
desc = "A polaroid camera, some say it can see ghosts! It seems to have an extra magnifier on the end."
see_ghosts = CAMERA_SEE_GHOSTS_ORBIT
/obj/item/camera/detective
name = "Detective's camera"
desc = "A polaroid camera with extra capacity for crime investigations."
pictures_max = 30
pictures_left = 30
/obj/item/camera/spooky/family
name = "fancy camera"
desc = "A fancy camera that has the latest magnifier mods and double the film load! With a complex double lens set with holy water to be able to see the dead, at laest to the Chaplain..."
see_ghosts = CAMERA_SEE_GHOSTS_ORBIT
pictures_max = 30
pictures_left = 30
@@ -1,99 +1,99 @@
/obj/item/camera/siliconcam
name = "silicon photo camera"
var/in_camera_mode = FALSE
var/list/datum/picture/stored = list()
/obj/item/camera/siliconcam/ai_camera
name = "AI photo camera"
flash_enabled = FALSE
/obj/item/camera/siliconcam/proc/toggle_camera_mode(mob/user)
if(in_camera_mode)
camera_mode_off(user)
else
camera_mode_on(user)
/obj/item/camera/siliconcam/proc/camera_mode_off(mob/user)
in_camera_mode = FALSE
to_chat(user, "<B>Camera Mode deactivated</B>")
/obj/item/camera/siliconcam/proc/camera_mode_on(mob/user)
in_camera_mode = TRUE
to_chat(user, "<B>Camera Mode activated</B>")
/obj/item/camera/siliconcam/proc/selectpicture(mob/user)
var/list/nametemp = list()
var/find
if(!stored.len)
to_chat(usr, "<span class='boldannounce'>No images saved</span>")
return
var/list/temp = list()
for(var/i in stored)
var/datum/picture/p = i
nametemp += p.picture_name
temp[p.picture_name] = p
find = input(user, "Select image") in nametemp|null
if(!find)
return
return temp[find]
/obj/item/camera/siliconcam/proc/viewpictures(mob/user)
var/datum/picture/selection = selectpicture(user)
if(istype(selection))
show_picture(user, selection)
/obj/item/camera/siliconcam/ai_camera/after_picture(mob/user, datum/picture/picture, proximity_flag)
var/number = stored.len
picture.picture_name = "Image [number] (taken by [loc.name])"
stored[picture] = TRUE
to_chat(usr, "<span class='unconscious'>Image recorded</span>")
/obj/item/camera/siliconcam/robot_camera
name = "Cyborg photo camera"
var/printcost = 2
/obj/item/camera/siliconcam/robot_camera/after_picture(mob/user, datum/picture/picture, proximity_flag)
var/mob/living/silicon/robot/C = loc
if(istype(C) && istype(C.connected_ai))
var/number = C.connected_ai.aicamera.stored.len
picture.picture_name = "Image [number] (taken by [loc.name])"
C.connected_ai.aicamera.stored[picture] = TRUE
to_chat(usr, "<span class='unconscious'>Image recorded and saved to remote database</span>")
else
var/number = stored.len
picture.picture_name = "Image [number] (taken by [loc.name])"
stored[picture] = TRUE
to_chat(usr, "<span class='unconscious'>Image recorded and saved to local storage. Upload will happen automatically if unit is lawsynced.</span>")
/obj/item/camera/siliconcam/robot_camera/selectpicture(mob/user)
var/mob/living/silicon/robot/R = loc
if(istype(R) && R.connected_ai)
R.picturesync()
return R.connected_ai.aicamera.selectpicture(user)
else
return ..()
/obj/item/camera/siliconcam/robot_camera/verb/borgprinting()
set category ="Robot Commands"
set name = "Print Image"
set src in usr
if(usr.stat == DEAD)
return
borgprint(usr)
/obj/item/camera/siliconcam/robot_camera/proc/borgprint(mob/user)
var/mob/living/silicon/robot/C = loc
if(!istype(C) || C.toner < 20)
to_chat(user, "<span class='warning'>Insufficent toner to print image.</span>")
return
var/datum/picture/selection = selectpicture(user)
if(!istype(selection))
to_chat(user, "<span class='warning'>Invalid Image.</span>")
return
var/obj/item/photo/p = new /obj/item/photo(C.loc, selection)
p.pixel_x = rand(-10, 10)
p.pixel_y = rand(-10, 10)
C.toner -= printcost //All fun allowed.
visible_message("[C.name] spits out a photograph from a narrow slot on its chassis.")
to_chat(usr, "<span class='notice'>You print a photograph.</span>")
/obj/item/camera/siliconcam
name = "silicon photo camera"
var/in_camera_mode = FALSE
var/list/datum/picture/stored = list()
/obj/item/camera/siliconcam/ai_camera
name = "AI photo camera"
flash_enabled = FALSE
/obj/item/camera/siliconcam/proc/toggle_camera_mode(mob/user)
if(in_camera_mode)
camera_mode_off(user)
else
camera_mode_on(user)
/obj/item/camera/siliconcam/proc/camera_mode_off(mob/user)
in_camera_mode = FALSE
to_chat(user, "<B>Camera Mode deactivated</B>")
/obj/item/camera/siliconcam/proc/camera_mode_on(mob/user)
in_camera_mode = TRUE
to_chat(user, "<B>Camera Mode activated</B>")
/obj/item/camera/siliconcam/proc/selectpicture(mob/user)
var/list/nametemp = list()
var/find
if(!stored.len)
to_chat(usr, "<span class='boldannounce'>No images saved</span>")
return
var/list/temp = list()
for(var/i in stored)
var/datum/picture/p = i
nametemp += p.picture_name
temp[p.picture_name] = p
find = input(user, "Select image") in nametemp|null
if(!find)
return
return temp[find]
/obj/item/camera/siliconcam/proc/viewpictures(mob/user)
var/datum/picture/selection = selectpicture(user)
if(istype(selection))
show_picture(user, selection)
/obj/item/camera/siliconcam/ai_camera/after_picture(mob/user, datum/picture/picture, proximity_flag)
var/number = stored.len
picture.picture_name = "Image [number] (taken by [loc.name])"
stored[picture] = TRUE
to_chat(usr, "<span class='unconscious'>Image recorded</span>")
/obj/item/camera/siliconcam/robot_camera
name = "Cyborg photo camera"
var/printcost = 2
/obj/item/camera/siliconcam/robot_camera/after_picture(mob/user, datum/picture/picture, proximity_flag)
var/mob/living/silicon/robot/C = loc
if(istype(C) && istype(C.connected_ai))
var/number = C.connected_ai.aicamera.stored.len
picture.picture_name = "Image [number] (taken by [loc.name])"
C.connected_ai.aicamera.stored[picture] = TRUE
to_chat(usr, "<span class='unconscious'>Image recorded and saved to remote database</span>")
else
var/number = stored.len
picture.picture_name = "Image [number] (taken by [loc.name])"
stored[picture] = TRUE
to_chat(usr, "<span class='unconscious'>Image recorded and saved to local storage. Upload will happen automatically if unit is lawsynced.</span>")
/obj/item/camera/siliconcam/robot_camera/selectpicture(mob/user)
var/mob/living/silicon/robot/R = loc
if(istype(R) && R.connected_ai)
R.picturesync()
return R.connected_ai.aicamera.selectpicture(user)
else
return ..()
/obj/item/camera/siliconcam/robot_camera/verb/borgprinting()
set category ="Robot Commands"
set name = "Print Image"
set src in usr
if(usr.stat == DEAD)
return
borgprint(usr)
/obj/item/camera/siliconcam/robot_camera/proc/borgprint(mob/user)
var/mob/living/silicon/robot/C = loc
if(!istype(C) || C.toner < 20)
to_chat(user, "<span class='warning'>Insufficent toner to print image.</span>")
return
var/datum/picture/selection = selectpicture(user)
if(!istype(selection))
to_chat(user, "<span class='warning'>Invalid Image.</span>")
return
var/obj/item/photo/p = new /obj/item/photo(C.loc, selection)
p.pixel_x = rand(-10, 10)
p.pixel_y = rand(-10, 10)
C.toner -= printcost //All fun allowed.
visible_message("[C.name] spits out a photograph from a narrow slot on its chassis.")
to_chat(usr, "<span class='notice'>You print a photograph.</span>")