From 63ab44accc9efeafa02f6031e85ea2761e1d8585 Mon Sep 17 00:00:00 2001 From: PsiOmega Date: Mon, 28 Jul 2014 17:30:51 +0200 Subject: [PATCH 1/3] Makes it possible for the AI to take and view images. --- baystation12.dme | 1 + baystation12.int | 5 ++ code/_onclick/ai.dm | 5 ++ code/modules/mob/living/silicon/ai/ai.dm | 5 +- code/modules/mob/transform_procs.dm | 2 + code/modules/paperwork/ai_photography.dm | 96 ++++++++++++++++++++++++ code/modules/paperwork/photography.dm | 47 +++++++----- 7 files changed, 142 insertions(+), 19 deletions(-) create mode 100644 code/modules/paperwork/ai_photography.dm diff --git a/baystation12.dme b/baystation12.dme index a820faad30..128c237d38 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1103,6 +1103,7 @@ #include "code\modules\organs\organ_internal.dm" #include "code\modules\organs\pain.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" diff --git a/baystation12.int b/baystation12.int index b82874fded..364c188ceb 100644 --- a/baystation12.int +++ b/baystation12.int @@ -1,6 +1,11 @@ // BEGIN_INTERNALS /* MAP_ICON_TYPE: 0 +LAST_COMPILE_VERSION: 503.1224 +WINDOW: code\modules\paperwork\photography.dm;code\modules\mob\living\silicon\ai\ai.dm;code\_onclick\click.dm;code\_onclick\ai.dm;code\modules\mob\transform_procs.dm;code\game\objects\items\blueprints.dm;code\modules\paperwork\ai_photography.dm +DIR: code code\_onclick code\game\gamemodes code\game\gamemodes\mutiny code\game\gamemodes\mutiny\directives code\game\objects code\game\objects\items code\modules code\modules\mob code\modules\mob\living code\modules\mob\living\silicon code\modules\mob\living\silicon\ai code\modules\paperwork code\WorkInProgress\AI_Visibility icons icons\mob icons\obj icons\obj\atmospherics sound sound\vox +FILE: code\modules\paperwork\ai_photography.dm +LAST_COMPILE_TIME: 1406556860 AUTO_FILE_DIR: OFF */ // END_INTERNALS diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 204f39e69c..64b35edbdf 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -53,6 +53,11 @@ return next_move = world.time + 9 + if(aicamera.in_camera_mode) + aicamera.camera_mode_off() + aicamera.captureimage(A, usr) + return + /* AI 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 a2b375d3be..660476f167 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -32,6 +32,7 @@ var/list/ai_list = list() var/obj/item/device/pda/ai/aiPDA = null var/obj/item/device/multitool/aiMulti = null var/obj/item/device/radio/headset/heads/ai_integrated/aiRadio = null + var/obj/item/device/camera/ai_camera/aicamera = null var/custom_sprite = 0 //For our custom sprites //Hud stuff @@ -92,6 +93,8 @@ var/list/ai_list = list() aiRadio = new(src) aiRadio.myAi = src + aicamera = new/obj/item/device/camera/ai_camera(src) + if (istype(loc, /turf)) verbs.Add(/mob/living/silicon/ai/proc/ai_call_shuttle,/mob/living/silicon/ai/proc/ai_camera_track, \ /mob/living/silicon/ai/proc/ai_camera_list, /mob/living/silicon/ai/proc/ai_network_change, \ @@ -756,4 +759,4 @@ var/list/ai_list = list() src << "Accessing Subspace Transceiver control..." if (src.aiRadio) - src.aiRadio.interact(src) + src.aiRadio.interact(src) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 6dbd8ffe0c..05dc648c70 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -130,6 +130,8 @@ O.verbs += /mob/living/silicon/ai/proc/ai_store_location O.verbs += /mob/living/silicon/ai/proc/ai_goto_location O.verbs += /mob/living/silicon/ai/proc/ai_remove_location + 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 new file mode 100644 index 0000000000..ea8bdeef0d --- /dev/null +++ b/code/modules/paperwork/ai_photography.dm @@ -0,0 +1,96 @@ +/************** +* 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 f0d39337b6..a61738691d 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -212,7 +212,31 @@ /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) + playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 75, 1, -3) + + pictures_left-- + desc = "A polaroid camera. It has [pictures_left] photos left." + user << "[pictures_left] photos left." + icon_state = icon_off + on = 0 + spawn(64) + icon_state = icon_on + on = 1 + +/obj/item/device/camera/proc/can_capture_turf(turf/T, mob/user) + var/mob/dummy = new(T) //Go go visibility check dummy + var/viewer = user + if(user.client) //To make shooting through security cameras possible + viewer = user.client.eye + var/can_see = (dummy in viewers(world.view, viewer)) != null + + dummy.loc = null + dummy = null //Alas, nameless creature //garbage collect it instead + return can_see + +/obj/item/device/camera/proc/captureimage(atom/target, mob/user, flag) var/x_c = target.x - 1 var/y_c = target.y + 1 var/z_c = target.z @@ -223,21 +247,18 @@ for(var/i = 1; i <= 3; i++) for(var/j = 1; j <= 3; j++) var/turf/T = locate(x_c, y_c, z_c) - var/mob/dummy = new(T) //Go go visibility check dummy - var/viewer = user - if(user.client) //To make shooting through security cameras possible - viewer = user.client.eye - if(dummy in viewers(world.view, viewer)) + if(can_capture_turf(T, user)) temp.Blend(get_icon(T), ICON_OVERLAY, 32 * (j-1-1), 32 - 32 * (i-1)) + mobs += get_mobs(T, user) else temp.Blend(black, ICON_OVERLAY, 32 * (j-1), 64 - 32 * (i-1)) - mobs += get_mobs(T) - dummy.loc = null - dummy = null //Alas, nameless creature //garbage collect it instead x_c++ y_c-- x_c = x_c - 3 + printpicture(user, temp, mobs, flag) + +/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()) @@ -256,13 +277,3 @@ P.desc = mobs P.pixel_x = rand(-10, 10) P.pixel_y = rand(-10, 10) - playsound(loc, pick('sound/items/polaroid1.ogg', 'sound/items/polaroid2.ogg'), 75, 1, -3) - - pictures_left-- - desc = "A polaroid camera. It has [pictures_left] photos left." - user << "[pictures_left] photos left." - icon_state = icon_off - on = 0 - spawn(64) - icon_state = icon_on - on = 1 \ No newline at end of file From a5f6d417a1df65106c596682ab804bf4d1014b11 Mon Sep 17 00:00:00 2001 From: PsiOmega Date: Mon, 28 Jul 2014 18:21:30 +0200 Subject: [PATCH 2/3] Expands the AI photo-camera so that it now has robot/cyborg support. Also implements DRY in practice. --- baystation12.dme | 3 +- code/_onclick/ai.dm | 6 +- code/_onclick/cyborg.dm | 8 + code/modules/mob/living/silicon/ai/ai.dm | 5 +- code/modules/mob/living/silicon/robot/laws.dm | 1 + .../mob/living/silicon/robot/photos.dm | 16 ++ .../modules/mob/living/silicon/robot/robot.dm | 3 +- .../modules/mob/living/silicon/robot/wires.dm | 1 + 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, 221 insertions(+), 119 deletions(-) create mode 100644 code/modules/mob/living/silicon/robot/photos.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 128c237d38..98fc485a45 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -1037,6 +1037,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" @@ -1103,7 +1104,6 @@ #include "code\modules\organs\organ_internal.dm" #include "code\modules\organs\pain.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" @@ -1115,6 +1115,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\batteryrack.dm" diff --git a/code/_onclick/ai.dm b/code/_onclick/ai.dm index 64b35edbdf..c6078c10ac 100644 --- a/code/_onclick/ai.dm +++ b/code/_onclick/ai.dm @@ -53,9 +53,9 @@ 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 d86faacbd1..04682c76ad 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 660476f167..b40a3fb6ad 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -32,7 +32,7 @@ var/list/ai_list = list() var/obj/item/device/pda/ai/aiPDA = null var/obj/item/device/multitool/aiMulti = null var/obj/item/device/radio/headset/heads/ai_integrated/aiRadio = 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 //Hud stuff @@ -92,8 +92,7 @@ var/list/ai_list = list() aiMulti = new(src) aiRadio = new(src) aiRadio.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_call_shuttle,/mob/living/silicon/ai/proc/ai_camera_track, \ diff --git a/code/modules/mob/living/silicon/robot/laws.dm b/code/modules/mob/living/silicon/robot/laws.dm index bff875a0d6..2d6a12e966 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." 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 0000000000..31b40cf60d --- /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 273df70dd9..15342d04b5 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -65,6 +65,7 @@ var/scrambledcodes = 0 // Used to determine if a borg shows up on the robotics console. Setting to one hides them. var/braintype = "Cyborg" var/pose + var/obj/item/device/camera/siliconcam/aiCamera = null //photography /mob/living/silicon/robot/New(loc,var/syndie = 0,var/unfinished = 0) spark_system = new /datum/effect/effect/system/spark_spread() @@ -97,6 +98,7 @@ if(connected_ai) connected_ai.connected_robots += src lawsync() + photosync() lawupdate = 1 else lawupdate = 0 @@ -138,7 +140,6 @@ hud_list[IMPTRACK_HUD] = image('icons/mob/hud.dmi', src, "hudblank") hud_list[SPECIALROLE_HUD] = image('icons/mob/hud.dmi', src, "hudblank") - if(istype(src,/mob/living/silicon/robot/drone)) playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) else diff --git a/code/modules/mob/living/silicon/robot/wires.dm b/code/modules/mob/living/silicon/robot/wires.dm index 10b6832fe4..9ed4320c84 100644 --- a/code/modules/mob/living/silicon/robot/wires.dm +++ b/code/modules/mob/living/silicon/robot/wires.dm @@ -74,6 +74,7 @@ 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) diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm index 05dc648c70..6dbd8ffe0c 100644 --- a/code/modules/mob/transform_procs.dm +++ b/code/modules/mob/transform_procs.dm @@ -130,8 +130,6 @@ O.verbs += /mob/living/silicon/ai/proc/ai_store_location O.verbs += /mob/living/silicon/ai/proc/ai_goto_location O.verbs += /mob/living/silicon/ai/proc/ai_remove_location - 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 ea8bdeef0d..0000000000 --- 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 a61738691d..d713390fd4 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,9 +267,29 @@ 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"] diff --git a/code/modules/paperwork/silicon_photography.dm b/code/modules/paperwork/silicon_photography.dm new file mode 100644 index 0000000000..e5041ab96a --- /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 From 2f8bb7e135c3bdbcccdfd055f19836c7bfc6421d Mon Sep 17 00:00:00 2001 From: PsiOmega Date: Tue, 29 Jul 2014 12:02:48 +0200 Subject: [PATCH 3/3] Fixes runtime errors. AIs and cyborgs can now attach their photos to newscasters as well as photocopy them. --- baystation12.int | 5 ---- code/game/machinery/newscaster.dm | 17 ++++++++++--- code/modules/mob/living/silicon/ai/ai.dm | 1 - .../mob/living/silicon/robot/drone/drone.dm | 4 +++ .../mob/living/silicon/robot/photos.dm | 3 --- .../modules/mob/living/silicon/robot/robot.dm | 9 +++---- code/modules/mob/living/silicon/silicon.dm | 2 ++ code/modules/paperwork/photocopier.dm | 23 +++++++++++++++++ code/modules/paperwork/silicon_photography.dm | 25 +++++++++++-------- 9 files changed, 62 insertions(+), 27 deletions(-) diff --git a/baystation12.int b/baystation12.int index 364c188ceb..b82874fded 100644 --- a/baystation12.int +++ b/baystation12.int @@ -1,11 +1,6 @@ // BEGIN_INTERNALS /* MAP_ICON_TYPE: 0 -LAST_COMPILE_VERSION: 503.1224 -WINDOW: code\modules\paperwork\photography.dm;code\modules\mob\living\silicon\ai\ai.dm;code\_onclick\click.dm;code\_onclick\ai.dm;code\modules\mob\transform_procs.dm;code\game\objects\items\blueprints.dm;code\modules\paperwork\ai_photography.dm -DIR: code code\_onclick code\game\gamemodes code\game\gamemodes\mutiny code\game\gamemodes\mutiny\directives code\game\objects code\game\objects\items code\modules code\modules\mob code\modules\mob\living code\modules\mob\living\silicon code\modules\mob\living\silicon\ai code\modules\paperwork code\WorkInProgress\AI_Visibility icons icons\mob icons\obj icons\obj\atmospherics sound sound\vox -FILE: code\modules\paperwork\ai_photography.dm -LAST_COMPILE_TIME: 1406556860 AUTO_FILE_DIR: OFF */ // END_INTERNALS diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index b1783b1707..fba4927947 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -748,16 +748,27 @@ var/list/obj/machinery/newscaster/allCasters = list() //Global list that will co /obj/machinery/newscaster/proc/AttachPhoto(mob/user as mob) if(photo) - photo.loc = src.loc - user.put_in_inactive_hand(photo) + if(!issilicon(user)) + photo.loc = src.loc + user.put_in_inactive_hand(photo) photo = null if(istype(user.get_active_hand(), /obj/item/weapon/photo)) photo = user.get_active_hand() user.drop_item() photo.loc = src + else if(istype(user,/mob/living/silicon)) + var/mob/living/silicon/tempAI = user + var/obj/item/device/camera/siliconcam/camera = tempAI.aiCamera + if(!camera) + return + var/datum/picture/selection = camera.selectpicture() + if (!selection) + return - + var/obj/item/weapon/photo/P = new/obj/item/weapon/photo() + P.construct(selection) + photo = P //######################################################################################################################## diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index b40a3fb6ad..0fe0ddc93d 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -32,7 +32,6 @@ var/list/ai_list = list() var/obj/item/device/pda/ai/aiPDA = null var/obj/item/device/multitool/aiMulti = null var/obj/item/device/radio/headset/heads/ai_integrated/aiRadio = null - var/obj/item/device/camera/siliconcam/aiCamera = null var/custom_sprite = 0 //For our custom sprites //Hud stuff diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm index 0ab4e42028..cd0cbc9e2c 100644 --- a/code/modules/mob/living/silicon/robot/drone/drone.dm +++ b/code/modules/mob/living/silicon/robot/drone/drone.dm @@ -61,6 +61,10 @@ flavor_text = "It's a tiny little repair drone. The casing is stamped with an NT logo and the subscript: 'NanoTrasen Recursive Repair Systems: Fixing Tomorrow's Problem, Today!'" updateicon() +/mob/living/silicon/robot/drone/init() + new/obj/item/device/camera/siliconcam/drone_camera(src) + playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) + //Redefining some robot procs... /mob/living/silicon/robot/drone/updatename() real_name = "maintenance drone ([rand(100,999)])" diff --git a/code/modules/mob/living/silicon/robot/photos.dm b/code/modules/mob/living/silicon/robot/photos.dm index 31b40cf60d..fbcc3bf484 100644 --- a/code/modules/mob/living/silicon/robot/photos.dm +++ b/code/modules/mob/living/silicon/robot/photos.dm @@ -3,9 +3,6 @@ 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) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 15342d04b5..4daa0f5cf8 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -65,7 +65,6 @@ var/scrambledcodes = 0 // Used to determine if a borg shows up on the robotics console. Setting to one hides them. var/braintype = "Cyborg" var/pose - var/obj/item/device/camera/siliconcam/aiCamera = null //photography /mob/living/silicon/robot/New(loc,var/syndie = 0,var/unfinished = 0) spark_system = new /datum/effect/effect/system/spark_spread() @@ -139,11 +138,11 @@ hud_list[IMPCHEM_HUD] = image('icons/mob/hud.dmi', src, "hudblank") hud_list[IMPTRACK_HUD] = image('icons/mob/hud.dmi', src, "hudblank") hud_list[SPECIALROLE_HUD] = image('icons/mob/hud.dmi', src, "hudblank") + init() - if(istype(src,/mob/living/silicon/robot/drone)) - playsound(src.loc, 'sound/machines/twobeep.ogg', 50, 0) - else - playsound(loc, 'sound/voice/liveagain.ogg', 75, 1) +/mob/living/silicon/robot/proc/init() + new/obj/item/device/camera/siliconcam/robot_camera(src) + playsound(loc, 'sound/voice/liveagain.ogg', 75, 1) // setup the PDA and its name /mob/living/silicon/robot/proc/setup_PDA() diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 99adb65ed0..d730bd9b5f 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -13,6 +13,8 @@ var/speak_exclamation = "declares" var/speak_query = "queries" + var/obj/item/device/camera/siliconcam/aiCamera = null //photography + /mob/living/silicon/proc/show_laws() return diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm index 7f006325e6..6963fe2f75 100644 --- a/code/modules/paperwork/photocopier.dm +++ b/code/modules/paperwork/photocopier.dm @@ -34,6 +34,8 @@ dat += "+

" else if(toner) dat += "Please insert paper to copy.

" + if(istype(user,/mob/living/silicon)) + dat += "Print photo from database

" dat += "Current toner level: [toner]" if(!toner) dat +="
Please insert a new toner cartridge!" @@ -112,6 +114,27 @@ if(copies < maxcopies) copies++ updateUsrDialog() + else if(href_list["aipic"]) + if(!istype(usr,/mob/living/silicon)) return + if(toner >= 5) + var/mob/living/silicon/tempAI = usr + var/obj/item/device/camera/siliconcam/camera = tempAI.aiCamera + + if(!camera) + return + var/datum/picture/selection = camera.selectpicture() + if (!selection) + return + + var/obj/item/weapon/photo/p = new /obj/item/weapon/photo (src.loc) + p.construct(selection) + if (p.desc == "") + p.desc += "Copied by [tempAI.name]" + else + p.desc += " - Copied by [tempAI.name]" + toner -= 5 + sleep(15) + updateUsrDialog() attackby(obj/item/O as obj, mob/user as mob) if(istype(O, /obj/item/weapon/paper)) diff --git a/code/modules/paperwork/silicon_photography.dm b/code/modules/paperwork/silicon_photography.dm index e5041ab96a..4fbe953d72 100644 --- a/code/modules/paperwork/silicon_photography.dm +++ b/code/modules/paperwork/silicon_photography.dm @@ -5,10 +5,6 @@ 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 @@ -20,6 +16,9 @@ /obj/item/device/camera/siliconcam/robot_camera //camera cyborgs can take pictures with name = "Cyborg photo camera" +/obj/item/device/camera/siliconcam/drone_camera //currently doesn't offer the verbs, thus cannot be used + name = "Drone 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]" @@ -37,6 +36,9 @@ usr << "Image recorded" /obj/item/device/camera/siliconcam/proc/selectpicture(obj/item/device/camera/siliconcam/cam) + if(!cam) + cam = getsource() + var/list/nametemp = list() var/find if(cam.aipictures.len == 0) @@ -50,8 +52,8 @@ 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) +/obj/item/device/camera/siliconcam/proc/viewpictures() + var/datum/picture/selection = selectpicture() if(!selection) return @@ -112,7 +114,7 @@ set desc = "View images" set src in usr - viewpictures(src) + viewpictures() /obj/item/device/camera/siliconcam/ai_camera/verb/delete_images() set category = "AI Commands" @@ -120,7 +122,7 @@ set desc = "Delete image" set src in usr - deletepicture(src) + deletepicture() /obj/item/device/camera/siliconcam/robot_camera/verb/take_image() set category ="Robot Commands" @@ -136,8 +138,7 @@ set desc = "View images" set src in usr - var/obj/item/device/camera/siliconcam/cam = getsource() - viewpictures(cam) + viewpictures() /obj/item/device/camera/siliconcam/robot_camera/verb/delete_images() set category = "Robot Commands" @@ -145,9 +146,13 @@ set desc = "Delete a local image" set src in usr + // Explicitly only allow deletion from the local camera deletepicture(src) obj/item/device/camera/siliconcam/proc/getsource() + if(istype(src.loc, /mob/living/silicon/ai)) + return src + var/mob/living/silicon/robot/C = src.loc var/obj/item/device/camera/siliconcam/Cinfo if(C.connected_ai)