From 6cbee92ec80c771a11d491d922e47a317b9b9cba Mon Sep 17 00:00:00 2001 From: PsiOmega Date: Mon, 28 Jul 2014 18:21:30 +0200 Subject: [PATCH] Expands the AI photo-camera so that it now has robot/cyborg support. Also implements DRY in practice. Conflicts: code/modules/mob/living/silicon/ai/ai.dm code/modules/mob/living/silicon/robot/robot.dm code/modules/mob/living/silicon/robot/wires.dm code/modules/mob/transform_procs.dm code/modules/paperwork/photography.dm --- baystation12.dme | 3 +- code/_onclick/ai.dm | 6 +- code/_onclick/cyborg.dm | 8 + code/modules/mob/living/silicon/ai/ai.dm | 4 +- code/modules/mob/living/silicon/robot/laws.dm | 3 +- .../mob/living/silicon/robot/photos.dm | 16 ++ .../modules/mob/living/silicon/robot/robot.dm | 2 + .../modules/mob/living/silicon/robot/wires.dm | 149 +++++++++++++++++ code/modules/mob/transform_procs.dm | 2 - code/modules/paperwork/ai_photography.dm | 96 ----------- code/modules/paperwork/photography.dm | 42 +++-- code/modules/paperwork/silicon_photography.dm | 157 ++++++++++++++++++ 12 files changed, 370 insertions(+), 118 deletions(-) create mode 100644 code/modules/mob/living/silicon/robot/photos.dm create mode 100644 code/modules/mob/living/silicon/robot/wires.dm delete mode 100644 code/modules/paperwork/ai_photography.dm create mode 100644 code/modules/paperwork/silicon_photography.dm diff --git a/baystation12.dme b/baystation12.dme index 141e1bcce0d..3d31968ca62 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1113,6 +1113,7 @@ #include "code\modules\mob\living\silicon\robot\laws.dm" #include "code\modules\mob\living\silicon\robot\life.dm" #include "code\modules\mob\living\silicon\robot\login.dm" +#include "code\modules\mob\living\silicon\robot\photos.dm" #include "code\modules\mob\living\silicon\robot\robot.dm" #include "code\modules\mob\living\silicon\robot\robot_damage.dm" #include "code\modules\mob\living\silicon\robot\robot_items.dm" @@ -1191,7 +1192,6 @@ #include "code\modules\organs\pain.dm" #include "code\modules\organs\skeleton.dm" #include "code\modules\organs\wound.dm" -#include "code\modules\paperwork\ai_photography.dm" #include "code\modules\paperwork\carbonpaper.dm" #include "code\modules\paperwork\clipboard.dm" #include "code\modules\paperwork\filingcabinet.dm" @@ -1203,6 +1203,7 @@ #include "code\modules\paperwork\pen.dm" #include "code\modules\paperwork\photocopier.dm" #include "code\modules\paperwork\photography.dm" +#include "code\modules\paperwork\silicon_photography.dm" #include "code\modules\paperwork\stamps.dm" #include "code\modules\power\apc.dm" #include "code\modules\power\cable.dm" diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index b25e05168d3..13f2ef40ba0 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -51,9 +51,9 @@ if(control_disabled || stat || world.time <= next_move) return next_move = world.time + 9 - if(aicamera.in_camera_mode) - aicamera.camera_mode_off() - aicamera.captureimage(A, usr) + if(aiCamera.in_camera_mode) + aiCamera.camera_mode_off() + aiCamera.captureimage(A, usr) return /* diff --git a/code/_onclick/cyborg.dm b/code/_onclick/cyborg.dm index d1f5f439c71..4dd6ae31655 100644 --- a/code/_onclick/cyborg.dm +++ b/code/_onclick/cyborg.dm @@ -37,6 +37,14 @@ face_atom(A) // change direction to face what you clicked on + if(aiCamera.in_camera_mode) + aiCamera.camera_mode_off() + if(is_component_functioning("camera")) + aiCamera.captureimage(A, usr) + else + src << "Your camera isn't functional." + return + /* cyborg restrained() currently does nothing if(restrained()) diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index dce72f27419..617d4dfc7d3 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -31,7 +31,7 @@ var/list/ai_list = list() var/icon/holo_icon//Default is assigned when AI is created. var/obj/item/device/pda/ai/aiPDA = null var/obj/item/device/multitool/aiMulti = null - var/obj/item/device/camera/ai_camera/aicamera = null + var/obj/item/device/camera/siliconcam/aiCamera = null var/custom_sprite = 0 //For our custom sprites var/alienAI = 0 @@ -95,7 +95,7 @@ var/list/ai_list = list() radio = new(src) radio.myAi = src - aicamera = new/obj/item/device/camera/ai_camera(src) + aiCamera = new/obj/item/device/camera/siliconcam/ai_camera(src) if (istype(loc, /turf)) verbs.Add(/mob/living/silicon/ai/proc/ai_network_change, \ diff --git a/code/modules/mob/living/silicon/robot/laws.dm b/code/modules/mob/living/silicon/robot/laws.dm index 42365844823..04961298fa2 100644 --- a/code/modules/mob/living/silicon/robot/laws.dm +++ b/code/modules/mob/living/silicon/robot/laws.dm @@ -18,6 +18,7 @@ else lawsync() + photosync() src << "Laws synced with AI, be sure to note any changes." if(mind && mind.special_role == "traitor" && mind.original == src) src << "Remember, your AI does NOT share or know about your law 0." @@ -106,4 +107,4 @@ if(1) laws = new /datum/ai_laws/custom() if(2) var/datum/ai_laws/lawtype = pick(typesof(/datum/ai_laws/default) - /datum/ai_laws/default) - laws = new lawtype() \ No newline at end of file + laws = new lawtype() diff --git a/code/modules/mob/living/silicon/robot/photos.dm b/code/modules/mob/living/silicon/robot/photos.dm new file mode 100644 index 00000000000..31b40cf60df --- /dev/null +++ b/code/modules/mob/living/silicon/robot/photos.dm @@ -0,0 +1,16 @@ +/mob/living/silicon/robot/proc/photosync() + var/obj/item/device/camera/siliconcam/master_cam = connected_ai ? connected_ai.aiCamera : null + if (!master_cam) + return + + if(!aiCamera) + aiCamera = new/obj/item/device/camera/siliconcam/robot_camera(src) + + var/synced + synced = 0 + for(var/datum/picture/z in aiCamera.aipictures) + if (!(master_cam.aipictures.Find(z))) + aiCamera.printpicture(null, z) + synced = 1 + if(synced) + src << "Locally saved images synced with AI. Images were retained in local database in case of loss of connection with the AI." diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 7916652d22c..da1c1c01045 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -70,6 +70,7 @@ var/pose var/base_icon = "" var/crisis = 0 + var/obj/item/device/camera/siliconcam/aiCamera = null //photography /mob/living/silicon/robot/New(loc,var/syndie = 0,var/unfinished = 0, var/alien = 0) spark_system = new /datum/effect/effect/system/spark_spread() @@ -114,6 +115,7 @@ if(connected_ai) connected_ai.connected_robots += src lawsync() + photosync() lawupdate = 1 else lawupdate = 0 diff --git a/code/modules/mob/living/silicon/robot/wires.dm b/code/modules/mob/living/silicon/robot/wires.dm new file mode 100644 index 00000000000..51d416c7f5d --- /dev/null +++ b/code/modules/mob/living/silicon/robot/wires.dm @@ -0,0 +1,149 @@ +#define BORG_WIRE_LAWCHECK 1 +#define BORG_WIRE_MAIN_POWER1 2 +#define BORG_WIRE_MAIN_POWER2 3 +#define BORG_WIRE_AI_CONTROL 4 +#define BORG_WIRE_CAMERA 5 + +/proc/RandomBorgWires() + //to make this not randomize the wires, just set index to 1 and increment it in the flag for loop (after doing everything else). + var/list/Borgwires = list(0, 0, 0, 0, 0) + BorgIndexToFlag = list(0, 0, 0, 0, 0) + BorgIndexToWireColor = list(0, 0, 0, 0, 0) + BorgWireColorToIndex = list(0, 0, 0, 0, 0) + var/flagIndex = 1 + //I think it's easier to read this way, also doesn't rely on the random number generator to land on a new wire. + var/list/colorIndexList = list(BORG_WIRE_LAWCHECK, BORG_WIRE_MAIN_POWER1, BORG_WIRE_MAIN_POWER2, BORG_WIRE_AI_CONTROL, BORG_WIRE_CAMERA) + for (var/flag=1, flag<=16, flag+=flag) + var/colorIndex = pick(colorIndexList) + if (Borgwires[colorIndex]==0) + Borgwires[colorIndex] = flag + BorgIndexToFlag[flagIndex] = flag + BorgIndexToWireColor[flagIndex] = colorIndex + BorgWireColorToIndex[colorIndex] = flagIndex + colorIndexList -= colorIndex // Shortens the list. + //world.log << "Flag: [flag], CIndex: [colorIndex], FIndex: [flagIndex]" + flagIndex+=1 + return Borgwires + +/mob/living/silicon/robot/proc/isWireColorCut(var/wireColor) + var/wireFlag = BorgWireColorToFlag[wireColor] + return ((src.borgwires & wireFlag) == 0) + +/mob/living/silicon/robot/proc/isWireCut(var/wireIndex) + var/wireFlag = BorgIndexToFlag[wireIndex] + return ((src.borgwires & wireFlag) == 0) + +/mob/living/silicon/robot/proc/cut(var/wireColor) + var/wireFlag = BorgWireColorToFlag[wireColor] + var/wireIndex = BorgWireColorToIndex[wireColor] + borgwires &= ~wireFlag + switch(wireIndex) + if(BORG_WIRE_LAWCHECK) //Cut the law wire, and the borg will no longer receive law updates from its AI + if (src.lawupdate == 1) + src << "LawSync protocol engaged." + src.show_laws() + if (BORG_WIRE_AI_CONTROL) //Cut the AI wire to reset AI control + if (src.connected_ai) + src.connected_ai = null + if (BORG_WIRE_CAMERA) + if(!isnull(src.camera) && !scrambledcodes) + src.camera.status = 0 + src.camera.deactivate(usr, 0) // Will kick anyone who is watching the Cyborg's camera. + + src.interact(usr) + +/mob/living/silicon/robot/proc/mend(var/wireColor) + var/wireFlag = BorgWireColorToFlag[wireColor] + var/wireIndex = BorgWireColorToIndex[wireColor] + borgwires |= wireFlag + switch(wireIndex) + if(BORG_WIRE_LAWCHECK) //turns law updates back on assuming the borg hasn't been emagged + if (src.lawupdate == 0 && !src.emagged) + src.lawupdate = 1 + if(BORG_WIRE_CAMERA) + if (!isnull(src.camera) && !scrambledcodes) + src.camera.status = 1 + src.camera.deactivate(usr, 0) // Will kick anyone who is watching the Cyborg's camera. + + src.interact(usr) + + +/mob/living/silicon/robot/proc/pulse(var/wireColor) + var/wireIndex = BorgWireColorToIndex[wireColor] + switch(wireIndex) + if(BORG_WIRE_LAWCHECK) //Forces a law update if the borg is set to receive them. Since an update would happen when the borg checks its laws anyway, not much use, but eh + if (src.lawupdate) + src.lawsync() + src.photosync() + + if (BORG_WIRE_AI_CONTROL) //pulse the AI wire to make the borg reselect an AI + if(!src.emagged) + src.connected_ai = select_active_ai() + + if (BORG_WIRE_CAMERA) + if(!isnull(src.camera) && src.camera.status && !scrambledcodes) + src.camera.deactivate(usr, 0) // Kick anyone watching the Cyborg's camera, doesn't display you disconnecting the camera. + usr << "[src]'s camera lens focuses loudly." + src << "Your camera lens focuses loudly." + + src.interact(usr) + +/mob/living/silicon/robot/proc/interact(mob/user) + if(wiresexposed && (!istype(user, /mob/living/silicon))) + user.set_machine(src) + var/t1 = text("Access Panel
\n") + var/list/Borgwires = list( + "Orange" = 1, + "Dark red" = 2, + "White" = 3, + "Yellow" = 4, + "Blue" = 5, + ) + for(var/wiredesc in Borgwires) + var/is_uncut = src.borgwires & BorgWireColorToFlag[Borgwires[wiredesc]] + t1 += "[wiredesc] wire: " + if(!is_uncut) + t1 += "Mend" + else + t1 += "Cut " + t1 += "Pulse " + t1 += "
" + t1 += text("
\n[(src.lawupdate ? "The LawSync light is on." : "The LawSync light is off.")]
\n[(src.connected_ai ? "The AI link light is on." : "The AI link light is off.")]") + t1 += text("
\n[((!isnull(src.camera) && src.camera.status == 1) ? "The Camera light is on." : "The Camera light is off.")]
\n") + t1 += text("

Close

\n") + user << browse(t1, "window=borgwires") + onclose(user, "borgwires") + +/mob/living/silicon/robot/Topic(href, href_list) + ..() + if (((in_range(src, usr) && istype(src.loc, /turf))) && !istype(usr, /mob/living/silicon)) + usr.set_machine(src) + if (href_list["borgwires"]) + var/t1 = text2num(href_list["borgwires"]) + if (!( istype(usr.get_active_hand(), /obj/item/weapon/wirecutters) )) + usr << "You need wirecutters!" + return + if (src.isWireColorCut(t1)) + src.mend(t1) + else + src.cut(t1) + else if (href_list["pulse"]) + var/t1 = text2num(href_list["pulse"]) + if (!istype(usr.get_active_hand(), /obj/item/device/multitool)) + usr << "You need a multitool!" + return + if (src.isWireColorCut(t1)) + usr << "You can't pulse a cut wire." + return + else + src.pulse(t1) + else if (href_list["close2"]) + usr << browse(null, "window=borgwires") + usr.unset_machine() + return + +#undef BORG_WIRE_LAWCHECK +#undef BORG_WIRE_MAIN_POWER1 +#undef BORG_WIRE_MAIN_POWER2 +#undef BORG_WIRE_AI_CONTROL +#undef BORG_WIRE_CAMERA \ No newline at end of file diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 0831b75a3f1..b7f9a04a98d 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -127,8 +127,6 @@ O.verbs += /mob/living/silicon/ai/proc/show_laws_verb O.verbs += /mob/living/silicon/ai/proc/ai_statuschange - O.verbs += /mob/living/silicon/ai/proc/ai_take_image - O.verbs += /mob/living/silicon/ai/proc/ai_view_images O.job = "AI" diff --git a/code/modules/paperwork/ai_photography.dm b/code/modules/paperwork/ai_photography.dm deleted file mode 100644 index ea8bdeef0df..00000000000 --- a/code/modules/paperwork/ai_photography.dm +++ /dev/null @@ -1,96 +0,0 @@ -/************** -* AI-specific * -**************/ -/datum/picture - var/name = "image" - var/list/fields = list() - -obj/item/device/camera/ai_camera //camera AI can take pictures with - name = "AI photo camera" - var/in_camera_mode = 0 - var/list/aipictures = list() - -/obj/item/device/camera/ai_camera/proc/injectaialbum(var/icon, var/img, var/desc, var/pixel_x, var/pixel_y) //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]" - P.fields["icon"] = icon - P.fields["img"] = img - P.fields["desc"] = desc - P.fields["pixel_x"] = pixel_x - P.fields["pixel_y"] = pixel_y - - aipictures += P - usr << "Image recorded" - -/obj/item/device/camera/ai_camera/proc/viewpictures() - var/list/nametemp = list() - var/find - var/datum/picture/selection - if(src.aipictures.len == 0) - usr << "No images saved" - return - for(var/datum/picture/t in src.aipictures) - nametemp += t.fields["name"] - find = input("Select image (numbered in order taken)") in nametemp - var/obj/item/weapon/photo/P = new/obj/item/weapon/photo() - for(var/datum/picture/q in src.aipictures) - if(q.fields["name"] == find) - selection = q - break - P.icon = selection.fields["icon"] - P.img = selection.fields["img"] - P.desc = selection.fields["desc"] - P.pixel_x = selection.fields["pixel_x"] - P.pixel_y = selection.fields["pixel_y"] - - P.show(usr) - usr << P.desc - - // TG uses a special garbage collector.. qdel(P) - del(P) //so 10 thousand pictures items are not left in memory should an AI take them and then view them all. - -/obj/item/device/camera/ai_camera/printpicture(mob/user, icon/temp, mobs, flag) - 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) - - injectaialbum(icon, img, desc, pixel_x, pixel_y) - -/obj/item/device/camera/ai_camera/can_capture_turf(turf/T, mob/user) - var/mob/living/silicon/ai = user - return ai.TurfAdjacent(T) - -/obj/item/device/camera/ai_camera/proc/toggle_camera_mode() - if(in_camera_mode) - camera_mode_off() - else - camera_mode_on() - -/obj/item/device/camera/ai_camera/proc/camera_mode_off() - src.in_camera_mode = 0 - usr << "Camera Mode deactivated" - -/obj/item/device/camera/ai_camera/proc/camera_mode_on() - src.in_camera_mode = 1 - usr << "Camera Mode activated" - -/mob/living/silicon/ai/proc/ai_take_image() - set category = "AI Commands" - set name = "Take Image" - set desc = "Takes an image" - aicamera.toggle_camera_mode() - -/mob/living/silicon/ai/proc/ai_view_images() - set category = "AI Commands" - set name = "View Images" - set desc = "View images" - aicamera.viewpictures() \ No newline at end of file diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index 01c654cce36..3d56957830c 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -209,7 +209,6 @@ mob_detail += "You can also see [A] on the photo[A:health < 75 ? " - [A] looks hurt":""].[holding ? " [holding]":"."]." return mob_detail - /obj/item/device/camera/afterattack(atom/target as mob|obj|turf|area, mob/user as mob, flag) if(!on || !pictures_left || ismob(target.loc)) return captureimage(target, user, flag) @@ -256,13 +255,10 @@ y_c-- x_c = x_c - 3 - printpicture(user, temp, mobs, flag) + var/datum/picture/P = createpicture(user, temp, mobs, flag) + printpicture(user, P) -/obj/item/device/camera/proc/printpicture(mob/user, icon/temp, mobs, flag) - var/obj/item/weapon/photo/P = new/obj/item/weapon/photo() - P.loc = user.loc - if(!user.get_inactive_hand()) - user.put_in_inactive_hand(P) +/obj/item/device/camera/proc/createpicture(mob/user, icon/temp, mobs, flag) var/icon/small_img = icon(temp) var/icon/tiny_img = icon(temp) var/icon/ic = icon('icons/obj/items.dmi',"photo") @@ -271,12 +267,32 @@ tiny_img.Scale(4, 4) ic.Blend(small_img,ICON_OVERLAY, 10, 13) pc.Blend(tiny_img,ICON_OVERLAY, 12, 19) - P.icon = ic - P.tiny = pc - P.img = temp - P.desc = mobs - P.pixel_x = rand(-10, 10) - P.pixel_y = rand(-10, 10) + + var/datum/picture/P = new() + P.fields["author"] = user + P.fields["icon"] = ic + P.fields["tiny"] = pc + P.fields["img"] = temp + P.fields["desc"] = mobs + P.fields["pixel_x"] = rand(-10, 10) + P.fields["pixel_y"] = rand(-10, 10) + + return P + +/obj/item/device/camera/proc/printpicture(mob/user, var/datum/picture/P) + var/obj/item/weapon/photo/Photo = new/obj/item/weapon/photo() + Photo.loc = user.loc + if(!user.get_inactive_hand()) + user.put_in_inactive_hand(Photo) + Photo.construct(P) + +/obj/item/weapon/photo/proc/construct(var/datum/picture/P) + icon = P.fields["icon"] + tiny = P.fields["tiny"] + img = P.fields["img"] + desc = P.fields["desc"] + pixel_x = P.fields["pixel_x"] + pixel_y = P.fields["pixel_y"] /************** *video camera * diff --git a/code/modules/paperwork/silicon_photography.dm b/code/modules/paperwork/silicon_photography.dm new file mode 100644 index 00000000000..e5041ab96a4 --- /dev/null +++ b/code/modules/paperwork/silicon_photography.dm @@ -0,0 +1,157 @@ +/************** +* AI-specific * +**************/ +/datum/picture + var/name = "image" + var/list/fields = list() + +/datum/inject + var/name = "image" + var/list/fields = list() + +/obj/item/device/camera/siliconcam + var/in_camera_mode = 0 + var/photos_taken = 0 + var/list/aipictures = list() + +/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 + name = "Cyborg photo camera" + +/obj/item/device/camera/siliconcam/proc/injectaialbum(var/datum/picture/P, var/sufix = "") //stores image information to a list similar to that of the datacore + photos_taken++ + P.fields["name"] = "Image [photos_taken][sufix]" + aipictures += P + +/obj/item/device/camera/siliconcam/proc/injectmasteralbum(var/datum/picture/P) //stores image information to a list similar to that of the datacore + var/mob/living/silicon/robot/C = src.loc + if(C.connected_ai) + var/mob/A = P.fields["author"] + C.connected_ai.aiCamera.injectaialbum(P, " (taken by [A.name])") + C.connected_ai << "Image recorded and saved by [name]" + usr << "Image recorded and saved to remote database" //feedback to the Cyborg player that the picture was taken + else + injectaialbum(P) + usr << "Image recorded" + +/obj/item/device/camera/siliconcam/proc/selectpicture(obj/item/device/camera/siliconcam/cam) + var/list/nametemp = list() + var/find + if(cam.aipictures.len == 0) + usr << "No images saved" + return + for(var/datum/picture/t in cam.aipictures) + nametemp += t.fields["name"] + find = input("Select image (numbered in order taken)") in nametemp + + for(var/datum/picture/q in cam.aipictures) + if(q.fields["name"] == find) + return q + +/obj/item/device/camera/siliconcam/proc/viewpictures(obj/item/device/camera/siliconcam/cam) + var/datum/picture/selection = selectpicture(cam) + + if(!selection) + return + + var/obj/item/weapon/photo/P = new/obj/item/weapon/photo() + P.construct(selection) + P.show(usr) + usr << P.desc + + // TG uses a special garbage collector.. qdel(P) + del(P) //so 10 thousand pictures items are not left in memory should an AI take them and then view them all. + +/obj/item/device/camera/siliconcam/proc/deletepicture(obj/item/device/camera/siliconcam/cam) + var/datum/picture/selection = selectpicture(cam) + + if(!selection) + return + + cam.aipictures -= selection + usr << "Image deleted" + +/obj/item/device/camera/siliconcam/ai_camera/can_capture_turf(turf/T, mob/user) + var/mob/living/silicon/ai = user + return ai.TurfAdjacent(T) + +/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/ai_camera/printpicture(mob/user, datum/picture/P) + injectaialbum(P) + usr << "Image recorded" + +/obj/item/device/camera/siliconcam/robot_camera/printpicture(mob/user, datum/picture/P) + injectmasteralbum(P) + +/obj/item/device/camera/siliconcam/ai_camera/verb/take_image() + set category = "AI Commands" + set name = "Take Image" + set desc = "Takes an image" + set src in usr + + toggle_camera_mode() + +/obj/item/device/camera/siliconcam/ai_camera/verb/view_images() + set category = "AI Commands" + set name = "View Images" + set desc = "View images" + set src in usr + + viewpictures(src) + +/obj/item/device/camera/siliconcam/ai_camera/verb/delete_images() + set category = "AI Commands" + set name = "Delete Image" + set desc = "Delete image" + set src in usr + + deletepicture(src) + +/obj/item/device/camera/siliconcam/robot_camera/verb/take_image() + set category ="Robot Commands" + set name = "Take Image" + set desc = "Takes an image" + set src in usr + + toggle_camera_mode() + +/obj/item/device/camera/siliconcam/robot_camera/verb/view_images() + set category ="Robot Commands" + set name = "View Images" + set desc = "View images" + set src in usr + + var/obj/item/device/camera/siliconcam/cam = getsource() + viewpictures(cam) + +/obj/item/device/camera/siliconcam/robot_camera/verb/delete_images() + set category = "Robot Commands" + set name = "Delete Image" + set desc = "Delete a local image" + set src in usr + + deletepicture(src) + +obj/item/device/camera/siliconcam/proc/getsource() + var/mob/living/silicon/robot/C = src.loc + var/obj/item/device/camera/siliconcam/Cinfo + if(C.connected_ai) + Cinfo = C.connected_ai.aiCamera + else + Cinfo = src + return Cinfo