/* Photography! * Contains: * Camera * Camera Film * Photos * Photo Albums * AI Photography */ /* * Film */ /obj/item/device/camera_film name = "film cartridge" icon = 'icons/obj/items.dmi' desc = "A camera film cartridge. Insert it into a camera to reload it." icon_state = "film" item_state = "electropack" w_class = 1 burn_state = FLAMMABLE /* * Photo */ /obj/item/weapon/photo name = "photo" icon = 'icons/obj/items.dmi' icon_state = "photo" item_state = "paper" w_class = 1 burn_state = FLAMMABLE burntime = 5 var/icon/img //Big photo image var/scribble //Scribble on the back. var/blueprints = 0 //Does it include the blueprints? var/sillynewscastervar //Photo objects with this set to 1 will not be ejected by a newscaster. Only gets set to 1 if a silicon puts one of their images into a newscaster /obj/item/weapon/photo/attack_self(mob/user) user.examinate(src) /obj/item/weapon/photo/attackby(obj/item/weapon/P, mob/user, params) if(istype(P, /obj/item/weapon/pen) || istype(P, /obj/item/toy/crayon)) var/txt = sanitize(input(user, "What would you like to write on the back?", "Photo Writing", null) as text) txt = copytext(txt, 1, 128) if(loc == user && user.stat == 0) scribble = txt ..() /obj/item/weapon/photo/examine(mob/user) ..() if(in_range(user, src)) show(user) else user << "You need to get closer to get a good look at this photo!" /obj/item/weapon/photo/proc/show(mob/user) user << browse_rsc(img, "tmp_photo.png") user << browse("[name]" \ + "" \ + "" \ + "[scribble ? "
Written on the back:
[scribble]" : ""]"\ + "", "window=book;size=192x[scribble ? 400 : 192]") onclose(user, "[name]") /obj/item/weapon/photo/verb/rename() set name = "Rename photo" set category = "Object" set src in usr var/n_name = copytext(sanitize(input(usr, "What would you like to label the photo?", "Photo Labelling", null) as text), 1, MAX_NAME_LEN) //loc.loc check is for making possible renaming photos in clipboards if((loc == usr || loc.loc && loc.loc == usr) && usr.stat == 0 && usr.canmove && !usr.restrained()) name = "photo[(n_name ? text("- '[n_name]'") : null)]" add_fingerprint(usr) /obj/item/weapon/photo/proc/photocreate(inicon, inimg, indesc, inblueprints) icon = inicon img = inimg desc = indesc blueprints = inblueprints /* * Photo album */ /obj/item/weapon/storage/photo_album name = "photo album" icon = 'icons/obj/items.dmi' icon_state = "album" item_state = "briefcase" can_hold = list(/obj/item/weapon/photo) burn_state = FLAMMABLE /* * Camera */ /obj/item/device/camera name = "camera" icon = 'icons/obj/items.dmi' desc = "A polaroid camera." icon_state = "camera" item_state = "electropack" w_class = 2 flags = CONDUCT slot_flags = SLOT_BELT materials = list(MAT_METAL=2000) var/pictures_max = 10 var/pictures_left = 10 var/on = 1 var/blueprints = 0 //are blueprints visible in the current photo being created? var/list/aipictures = list() //Allows for storage of pictures taken by AI, in a similar manner the datacore stores info. Keeping this here allows us to share some procs w/ regualar camera var/see_ghosts = 0 //for the spoop of it /obj/item/device/camera/CheckParts() var/obj/item/device/camera/C = locate(/obj/item/device/camera) in contents if(C) pictures_max = C.pictures_max pictures_left = C.pictures_left visible_message("[C] has been imbued with godlike power!") qdel(C) /obj/item/device/camera/spooky name = "camera obscura" desc = "A polaroid camera, some say it can see ghosts!" see_ghosts = 1 /obj/item/device/camera/detective name = "Detective's camera" desc = "A polaroid camera with extra capacity for crime investigations." pictures_max = 30 pictures_left = 30 /obj/item/device/camera/siliconcam //camera AI can take pictures with name = "silicon photo camera" var/in_camera_mode = 0 /obj/item/device/camera/siliconcam/ai_camera //camera AI can take pictures with name = "AI photo camera" /obj/item/device/camera/siliconcam/robot_camera //camera cyborgs can take pictures with.. needs it's own because of verb CATEGORY >.> name = "Cyborg photo camera" /obj/item/device/camera/siliconcam/robot_camera/verb/borgprinting() set category ="Robot Commands" set name = "Print Image" set src in usr if(usr.stat == DEAD) return //won't work if dead borgprint() /obj/item/device/camera/attack(mob/living/carbon/human/M, mob/user) return /obj/item/device/camera/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/device/camera_film)) if(pictures_left) user << "[src] still has some film in it!" return if(!user.unEquip(I)) return user << "You insert [I] into [src]." qdel(I) pictures_left = pictures_max return ..() /obj/item/device/camera/examine(mob/user) ..() user << "It has [pictures_left] photos left." /obj/item/device/camera/proc/camera_get_icon(list/turfs, turf/center) var/atoms[] = list() for(var/turf/T in turfs) atoms.Add(T) for(var/atom/movable/A in T) if(A.invisibility) if(see_ghosts) if(istype(A, /mob/dead/observer)) var/mob/dead/observer/O = A if(O.orbiting) //so you dont see ghosts following people like antags, etc. continue else continue atoms.Add(A) var/list/sorted = list() var/j for(var/i = 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) var/icon/res = icon('icons/effects/96x96.dmi', "") for(var/atom/A in sorted) var/icon/img = getFlatIcon(A) if(istype(A, /mob/living) && A:lying) img.Turn(A:lying) var/offX = 32 * (A.x - center.x) + A.pixel_x + 33 var/offY = 32 * (A.y - center.y) + A.pixel_y + 33 if(istype(A, /atom/movable)) offX += A:step_x offY += A:step_y res.Blend(img, blendMode2iconMode(A.blend_mode), offX, offY) if(istype(A, /obj/item/areaeditor/blueprints)) blueprints = 1 for(var/turf/T in turfs) res.Blend(getFlatIcon(T.loc), blendMode2iconMode(T.blend_mode), 32 * (T.x - center.x) + 33, 32 * (T.y - center.y) + 33) return res /obj/item/device/camera/proc/camera_get_mobs(turf/the_turf) var/mob_detail for(var/mob/M in the_turf) if(M.invisibility) if(see_ghosts && istype(M,/mob/dead/observer)) var/mob/dead/observer/O = M if(O.orbiting) continue if(!mob_detail) mob_detail = "You can see a g-g-g-g-ghooooost! " else mob_detail += "You can also see a g-g-g-g-ghooooost!" else continue var/holding = null if(istype(M, /mob/living)) var/mob/living/L = M if(L.l_hand || L.r_hand) if(L.l_hand) holding = "They are holding \a [L.l_hand]" if(L.r_hand) if(holding) holding += " and \a [L.r_hand]" else holding = "They are holding \a [L.r_hand]" if(!mob_detail) mob_detail = "You can see [L] on the photo[L.health < 75 ? " - [L] looks hurt":""].[holding ? " [holding]":"."]. " else mob_detail += "You can also see [L] on the photo[L.health < 75 ? " - [L] looks hurt":""].[holding ? " [holding]":"."]." return mob_detail /obj/item/device/camera/proc/captureimage(atom/target, mob/user, flag) //Proc for both regular and AI-based camera to take the image var/mobs = "" var/isAi = istype(user, /mob/living/silicon/ai) var/list/seen if(!isAi) //crappy check, but without it AI photos would be subject to line of sight from the AI Eye object. Made the best of it by moving the sec camera check inside if(user.client) //To make shooting through security cameras possible seen = get_hear(world.view, user.client.eye) //To make shooting through security cameras possible else seen = get_hear(world.view, user) else seen = get_hear(world.view, target) var/list/turfs = list() for(var/turf/T in range(1, target)) if(T in seen) if(isAi && !cameranet.checkTurfVis(T)) continue else turfs += T mobs += camera_get_mobs(T) var/icon/temp = icon('icons/effects/96x96.dmi',"") temp.Blend("#000", ICON_OVERLAY) temp.Blend(camera_get_icon(turfs, target), ICON_OVERLAY) if(!issilicon(user)) printpicture(user, temp, mobs, flag) else aipicture(user, temp, mobs, isAi, blueprints) /obj/item/device/camera/proc/printpicture(mob/user, icon/temp, mobs, flag) //Normal camera proc for creating photos var/obj/item/weapon/photo/P = new/obj/item/weapon/photo(get_turf(src)) if(Adjacent(user)) //needed because of TK user.put_in_hands(P) var/icon/small_img = icon(temp) var/icon/ic = icon('icons/obj/items.dmi',"photo") small_img.Scale(8, 8) ic.Blend(small_img,ICON_OVERLAY, 10, 13) P.icon = ic P.img = temp P.desc = mobs P.pixel_x = rand(-10, 10) P.pixel_y = rand(-10, 10) if(blueprints) P.blueprints = 1 blueprints = 0 /obj/item/device/camera/proc/aipicture(mob/user, icon/temp, mobs, isAi) //instead of printing a picture like a regular camera would, we do this instead for the AI var/icon/small_img = icon(temp) var/icon/ic = icon('icons/obj/items.dmi',"photo") small_img.Scale(8, 8) ic.Blend(small_img,ICON_OVERLAY, 10, 13) var/icon = ic var/img = temp var/desc = mobs var/pixel_x = rand(-10, 10) var/pixel_y = rand(-10, 10) var/injectblueprints = 1 if(blueprints) injectblueprints = 1 blueprints = 0 if(isAi) injectaialbum(icon, img, desc, pixel_x, pixel_y, injectblueprints) else injectmasteralbum(icon, img, desc, pixel_x, pixel_y, injectblueprints) /datum/picture var/name = "image" var/list/fields = list() /obj/item/device/camera/proc/injectaialbum(icon, img, desc, pixel_x, pixel_y, blueprintsinject) //stores image information to a list similar to that of the datacore var/numberer = 1 for(var/datum/picture in src.aipictures) numberer++ var/datum/picture/P = new() P.fields["name"] = "Image [numberer] (taken by [src.loc.name])" P.fields["icon"] = icon P.fields["img"] = img P.fields["desc"] = desc P.fields["pixel_x"] = pixel_x P.fields["pixel_y"] = pixel_y P.fields["blueprints"] = blueprintsinject aipictures += P usr << "Image recorded" //feedback to the AI player that the picture was taken /obj/item/device/camera/proc/injectmasteralbum(icon, img, desc, pixel_x, pixel_y, blueprintsinject) //stores image information to a list similar to that of the datacore var/numberer = 1 var/mob/living/silicon/robot/C = src.loc if(C.connected_ai) for(var/datum/picture in C.connected_ai.aicamera.aipictures) numberer++ var/datum/picture/P = new() P.fields["name"] = "Image [numberer] (taken by [src.loc.name])" P.fields["icon"] = icon P.fields["img"] = img P.fields["desc"] = desc P.fields["pixel_x"] = pixel_x P.fields["pixel_y"] = pixel_y P.fields["blueprints"] = blueprintsinject C.connected_ai.aicamera.aipictures += P usr << "Image recorded and saved to remote database" //feedback to the Cyborg player that the picture was taken else injectaialbum(icon, img, desc, pixel_x, pixel_y, blueprintsinject) /obj/item/device/camera/siliconcam/proc/selectpicture(obj/item/device/camera/siliconcam/targetloc) var/list/nametemp = list() var/find if(targetloc.aipictures.len == 0) usr << "No images saved" return for(var/datum/picture/t in targetloc.aipictures) nametemp += t.fields["name"] find = input("Select image (numbered in order taken)") in nametemp for(var/datum/picture/q in targetloc.aipictures) if(q.fields["name"] == find) return q /obj/item/device/camera/siliconcam/proc/viewpichelper(obj/item/device/camera/siliconcam/targetloc) var/obj/item/weapon/photo/P = new/obj/item/weapon/photo() var/datum/picture/selection = selectpicture(targetloc) if(selection) P.photocreate(selection.fields["icon"], selection.fields["img"], selection.fields["desc"]) P.pixel_x = selection.fields["pixel_x"] P.pixel_y = selection.fields["pixel_y"] P.show(usr) usr << P.desc qdel(P) //so 10 thousand picture items are not left in memory should an AI take them and then view them all /obj/item/device/camera/siliconcam/proc/viewpictures(user) if(isrobot(user)) // Cyborg var/mob/living/silicon/robot/C = src.loc var/obj/item/device/camera/siliconcam/Cinfo if(C.connected_ai) Cinfo = C.connected_ai.aicamera viewpichelper(Cinfo) else Cinfo = C.aicamera viewpichelper(Cinfo) else // AI var/Ainfo = src viewpichelper(Ainfo) /obj/item/device/camera/afterattack(atom/target, mob/user, flag) if(!on || !pictures_left || ismob(target.loc) || !isturf(target.loc)) return if(user.Adjacent(target)) var/list/bad_targets = list(/obj/structure, /obj/item/weapon/storage) if(is_type_in_list(target, bad_targets)) return captureimage(target, user, flag) playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 75, 1, -3) pictures_left-- user << "[pictures_left] photos left." icon_state = "camera_off" on = 0 spawn(64) icon_state = "camera" on = 1 /obj/item/device/camera/siliconcam/proc/toggle_camera_mode() if(in_camera_mode) camera_mode_off() else camera_mode_on() /obj/item/device/camera/siliconcam/proc/camera_mode_off() src.in_camera_mode = 0 usr << "Camera Mode deactivated" /obj/item/device/camera/siliconcam/proc/camera_mode_on() src.in_camera_mode = 1 usr << "Camera Mode activated" /obj/item/device/camera/siliconcam/robot_camera/proc/borgprint() var/list/nametemp = list() var/find var/datum/picture/selection var/mob/living/silicon/robot/C = src.loc var/obj/item/device/camera/siliconcam/targetcam = null if(C.toner < 20) usr << "Insufficent toner to print image." return if(C.connected_ai) targetcam = C.connected_ai.aicamera else targetcam = C.aicamera if(targetcam.aipictures.len == 0) usr << "No images saved" return for(var/datum/picture/t in targetcam.aipictures) nametemp += t.fields["name"] find = input("Select image (numbered in order taken)") in nametemp for(var/datum/picture/q in targetcam.aipictures) if(q.fields["name"] == find) selection = q break var/obj/item/weapon/photo/p = new /obj/item/weapon/photo(C.loc) p.photocreate(selection.fields["icon"], selection.fields["img"], selection.fields["desc"], selection.fields["blueprints"]) p.pixel_x = rand(-10, 10) p.pixel_y = rand(-10, 10) C.toner -= 20 //Cyborgs are very ineffeicient at printing an image visible_message("[C.name] spits out a photograph from a narrow slot on it's chassis.") usr << "You print a photograph."