diff --git a/code/game/machinery/newscaster/newscaster_machine.dm b/code/game/machinery/newscaster/newscaster_machine.dm index ad08823981b..98cce390010 100644 --- a/code/game/machinery/newscaster/newscaster_machine.dm +++ b/code/game/machinery/newscaster/newscaster_machine.dm @@ -578,7 +578,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30) targetcam = R.aicamera else if(ispAI(user)) var/mob/living/silicon/pai/R = user - targetcam = R.camera + if(R.aicamera) + targetcam = R.aicamera else if(iscyborg(user)) var/mob/living/silicon/robot/R = user if(R.connected_ai) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 5fda090dd9f..5cb45e8b089 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1252,7 +1252,7 @@ to_chat(src, span_warning("You don't have the physical ability to do this!")) return FALSE - if(!Adjacent(target) && (target.loc != src)) + if(!Adjacent(target) && (target.loc != src) && !recursive_loc_check(src, target)) if(issilicon(src) && !ispAI(src)) if(!(action_bitflags & ALLOW_SILICON_REACH)) // silicons can ignore range checks (except pAIs) to_chat(src, span_warning("You are too far away!")) diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index 18a17311c3f..da83445a641 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -200,10 +200,7 @@ return TRUE if(istype(inserted_pai)) // Remove pAI - user.put_in_hands(inserted_pai) - balloon_alert(user, "removed pAI") - inserted_pai = null - update_appearance(UPDATE_ICON) + remove_pai(user) return TRUE // Gets IDs/access levels from card slot. Would be useful when/if PDAs would become modular PCs. //guess what @@ -414,7 +411,7 @@ var/mob/living/carbon/human/human_wearer = loc human_wearer.sec_hud_set_ID() if(inserted_pai == gone) - inserted_pai = null + update_appearance(UPDATE_ICON) if(inserted_disk == gone) inserted_disk = null update_appearance(UPDATE_ICON) @@ -713,12 +710,7 @@ return // Inserting a pAI - if(istype(attacking_item, /obj/item/pai_card) && !inserted_pai) - if(!user.transferItemToLoc(attacking_item, src)) - return - inserted_pai = attacking_item - balloon_alert(user, "inserted pai") - update_appearance(UPDATE_ICON) + if(istype(attacking_item, /obj/item/pai_card) && insert_pai(user, attacking_item)) return if(istype(attacking_item, /obj/item/stock_parts/cell)) @@ -792,7 +784,7 @@ internal_cell?.forceMove(drop_location()) computer_id_slot?.forceMove(drop_location()) inserted_disk?.forceMove(drop_location()) - inserted_pai?.forceMove(drop_location()) + remove_pai() new /obj/item/stack/sheet/iron(get_turf(loc), steel_sheet_cost) user.balloon_alert(user, "disassembled") relay_qdel() @@ -840,3 +832,30 @@ ///Returns a string of what to send at the end of messenger's messages. /obj/item/modular_computer/proc/get_messenger_ending() return "Sent from my PDA" + +/obj/item/modular_computer/proc/insert_pai(mob/user, obj/item/pai_card/card) + if(inserted_pai) + return FALSE + if(!user.transferItemToLoc(card, src)) + return FALSE + inserted_pai = card + balloon_alert(user, "inserted pai") + var/datum/action/innate/pai/messenger/messenger_ability = new(inserted_pai.pai) + messenger_ability.Grant(inserted_pai.pai) + update_appearance(UPDATE_ICON) + return TRUE + +/obj/item/modular_computer/proc/remove_pai(mob/user) + if(!inserted_pai) + return FALSE + var/datum/action/innate/pai/messenger/messenger_ability = locate() in inserted_pai.pai.actions + messenger_ability.Remove(inserted_pai.pai) + qdel(messenger_ability) + if(user) + user.put_in_hands(inserted_pai) + balloon_alert(user, "removed pAI") + else + inserted_pai.forceMove(drop_location()) + inserted_pai = null + update_appearance(UPDATE_ICON) + return TRUE diff --git a/code/modules/modular_computers/computers/item/computer_ui.dm b/code/modules/modular_computers/computers/item/computer_ui.dm index 11c12ea0c47..d5dcf98c623 100644 --- a/code/modules/modular_computers/computers/item/computer_ui.dm +++ b/code/modules/modular_computers/computers/item/computer_ui.dm @@ -20,15 +20,21 @@ active_ui = new(user, src, "NtosMain") return active_ui.open() - if(active_program) - active_ui.interface = active_program.tgui_id - active_ui.title = active_program.filedesc - active_program.ui_interact(user, active_ui) - else - active_ui.interface = "NtosMain" + for (var/datum/tgui/window as anything in open_uis) + if(active_program) + window.interface = active_program.tgui_id + window.title = active_program.filedesc + active_program.ui_interact(user, window) + else + window.interface = "NtosMain" + window.send_assets() + update_static_data_for_all_viewers() - update_static_data(user, active_ui) - active_ui.send_assets() + +/obj/item/modular_computer/ui_state(mob/user) + if(inserted_pai && (user == inserted_pai.pai)) + return GLOB.contained_state + return ..() /obj/item/modular_computer/interact(mob/user) if(enabled) @@ -206,10 +212,9 @@ if("PC_Pai_Interact") switch(params["option"]) if("eject") - usr.put_in_hands(inserted_pai) - to_chat(usr, span_notice("You remove [inserted_pai] from the [name].")) - inserted_pai = null - update_appearance(UPDATE_ICON) + if(!ishuman(usr)) + return + remove_pai(usr) if("interact") inserted_pai.attack_self(usr) return TRUE diff --git a/code/modules/modular_computers/computers/item/pda.dm b/code/modules/modular_computers/computers/item/pda.dm index 9728e8c6f7f..1a766c3de7d 100644 --- a/code/modules/modular_computers/computers/item/pda.dm +++ b/code/modules/modular_computers/computers/item/pda.dm @@ -83,7 +83,7 @@ /obj/item/modular_computer/pda/interact(mob/user) . = ..() if(HAS_TRAIT(src, TRAIT_PDA_MESSAGE_MENU_RIGGED)) - explode(usr, from_message_menu = TRUE) + explode(user, from_message_menu = TRUE) /obj/item/modular_computer/pda/attack_self(mob/user) // bypass literacy checks to access syndicate uplink diff --git a/code/modules/modular_computers/file_system/program.dm b/code/modules/modular_computers/file_system/program.dm index 59ef183f6d6..1f36713380d 100644 --- a/code/modules/modular_computers/file_system/program.dm +++ b/code/modules/modular_computers/file_system/program.dm @@ -120,7 +120,7 @@ *access can contain a list of access numbers to check against. If access is not empty, it will be used istead of checking any inserted ID. */ /datum/computer_file/program/proc/can_run(mob/user, loud = FALSE, access_to_check, transfer = FALSE, list/access) - if(issilicon(user)) + if(issilicon(user) && !ispAI(user)) return TRUE if(isAdminGhostAI(user)) diff --git a/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm b/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm index e77e876c648..423f9c32dec 100644 --- a/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm +++ b/code/modules/modular_computers/file_system/programs/messenger/messenger_program.dm @@ -651,17 +651,17 @@ if(!isnull(viewing_messages_of) && viewing_messages_of == sender_ref) viewing_messages_of = REF(chat) - var/mob/living/receiver_mob = null - //Check our immediate loc - if(isliving(computer.loc)) - receiver_mob = computer.loc - //Maybe they are a silicon! - else - receiver_mob = get(computer, /mob/living/silicon) + var/list/mob/living/receievers = list() + if(computer.inserted_pai) + receievers += computer.inserted_pai.pai + if(computer.loc && isliving(computer.loc)) + receievers += computer.loc - var/should_ring = !alert_silenced || is_rigged - - if(should_ring && istype(receiver_mob) && receiver_mob.is_literate() && (receiver_mob.stat == CONSCIOUS || receiver_mob.stat == SOFT_CRIT)) + for(var/mob/living/messaged_mob as anything in receievers) + if(messaged_mob.stat >= UNCONSCIOUS) + continue + if(!messaged_mob.is_literate()) + continue var/reply_href = signal.data["rigged"] ? "explode" : "message" var/photo_href = signal.data["rigged"] ? "explode" : "open" var/reply @@ -676,16 +676,16 @@ var/sender_title = is_fake_user ? STRINGIFY_PDA_TARGET(fake_name, fake_job) : get_messenger_name(sender_messenger) var/sender_name = is_fake_user ? fake_name : sender_messenger.computer.saved_identification - if (isAI(receiver_mob)) - sender_title = "[sender_title]" + if (isAI(messaged_mob)) + sender_title = "[sender_title]" var/inbound_message = "[signal.format_message()]" inbound_message = emoji_parse(inbound_message) var/photo_message = signal.data["photo"] ? " (Photo Attached)" : "" - to_chat(receiver_mob, span_infoplain("[icon2html(computer, receiver_mob)] PDA message from [sender_title], \"[inbound_message]\"[photo_message] [reply]")) + to_chat(messaged_mob, span_infoplain("[icon2html(computer, messaged_mob)] PDA message from [sender_title], \"[inbound_message]\"[photo_message] [reply]")) - if (alert_able && should_ring) + if (alert_able && (!alert_silenced || is_rigged)) computer.ring(ringtone) SStgui.update_uis(computer) diff --git a/code/modules/pai/actions.dm b/code/modules/pai/actions.dm index 0d22d828382..e067cca01e9 100644 --- a/code/modules/pai/actions.dm +++ b/code/modules/pai/actions.dm @@ -61,3 +61,18 @@ /datum/action/innate/pai/light/Trigger(trigger_flags) ..() pai_owner.toggle_integrated_light() + +/datum/action/innate/pai/messenger + name = "Interact with PDA" + button_icon_state = "pda" + background_icon_state = "bg_tech" + overlay_icon_state = "bg_tech_border" + +/datum/action/innate/pai/messenger/Trigger(trigger_flags) + . = ..() + var/obj/item/pai_card/pai_holder = owner.loc + if(!istype(pai_holder.loc, /obj/item/modular_computer)) + owner.balloon_alert(owner, "not in a pda!") + return + var/obj/item/modular_computer/computer_host = pai_holder.loc + computer_host.interact(owner) diff --git a/code/modules/pai/camera.dm b/code/modules/pai/camera.dm index 30b1918651e..a091b208638 100644 --- a/code/modules/pai/camera.dm +++ b/code/modules/pai/camera.dm @@ -1,10 +1,8 @@ /mob/living/silicon/pai/ClickOn(atom/target, params) - ..() - if(!camera?.in_camera_mode) - return FALSE - //pAI picture taking - camera.toggle_camera_mode(sound = FALSE) - camera.captureimage(target, usr, camera.picture_size_x - 1, camera.picture_size_y - 1) + . = ..() + if(aicamera && aicamera.in_camera_mode) + aicamera.toggle_camera_mode(sound = FALSE) + aicamera.captureimage(target, usr) return TRUE /obj/item/camera/siliconcam/pai_camera @@ -46,13 +44,14 @@ * @returns {boolean} - TRUE if the camera worked. */ /mob/living/silicon/pai/proc/use_camera(mob/user, mode) - if(!camera || isnull(mode)) + if(!aicamera || isnull(mode)) return FALSE switch(mode) if(PAI_PHOTO_MODE_CAMERA) - camera.toggle_camera_mode(user) + aicamera.toggle_camera_mode(user) if(PAI_PHOTO_MODE_PRINTER) - camera.pai_print(user) + var/obj/item/camera/siliconcam/pai_camera/paicam = aicamera + paicam.pai_print(user) if(PAI_PHOTO_MODE_ZOOM) - camera.adjust_zoom(user) + aicamera.adjust_zoom(user) return TRUE diff --git a/code/modules/pai/hud.dm b/code/modules/pai/hud.dm index 057a199cdad..530780758d2 100644 --- a/code/modules/pai/hud.dm +++ b/code/modules/pai/hud.dm @@ -150,7 +150,7 @@ if(!..()) return var/mob/living/silicon/pai/pAI = usr - pAI.camera.toggle_camera_mode(usr) + pAI.aicamera.toggle_camera_mode(usr) /atom/movable/screen/pai/image_view name = "View Images" @@ -161,7 +161,7 @@ if(!..()) return var/mob/living/silicon/pai/pAI = usr - pAI.camera.viewpictures(usr) + pAI.aicamera.viewpictures(usr) /atom/movable/screen/pai/radio name = "radio" @@ -177,7 +177,6 @@ /datum/hud/pai/New(mob/living/silicon/pai/owner) ..() var/atom/movable/screen/using - var/mob/living/silicon/pai/mypai = mymob // Software menu using = new /atom/movable/screen/pai/software(null, src) @@ -238,9 +237,8 @@ using = new /atom/movable/screen/pai/modpc(null, src) using.screen_loc = ui_pai_mod_int static_inventory += using - mypai.pda_button = using var/atom/movable/screen/pai/modpc/tablet_button = using - tablet_button.pAI = mypai + tablet_button.pAI = mymob // Internal GPS using = new /atom/movable/screen/pai/internal_gps(null, src) diff --git a/code/modules/pai/pai.dm b/code/modules/pai/pai.dm index f8476339468..490e614b51f 100644 --- a/code/modules/pai/pai.dm +++ b/code/modules/pai/pai.dm @@ -79,10 +79,6 @@ var/obj/item/instrument/piano_synth/instrument /// Newscaster var/obj/machinery/newscaster/pai/newscaster - /// PDA - var/atom/movable/screen/ai/modpc/pda_button - /// Photography module - var/obj/item/camera/siliconcam/pai_camera/camera /// Remote signaler var/obj/item/assembly/signaler/internal/signaler @@ -155,7 +151,6 @@ /mob/living/silicon/pai/Destroy() QDEL_NULL(atmos_analyzer) - QDEL_NULL(camera) QDEL_NULL(hacking_cable) QDEL_NULL(host_scan) QDEL_NULL(instrument) @@ -195,8 +190,8 @@ /mob/living/silicon/pai/Exited(atom/movable/gone, direction) if(gone == atmos_analyzer) atmos_analyzer = null - else if(gone == camera) - camera = null + else if(gone == aicamera) + aicamera = null else if(gone == host_scan) host_scan = null else if(gone == internal_gps) diff --git a/code/modules/pai/software.dm b/code/modules/pai/software.dm index 85f952c43eb..103056a5535 100644 --- a/code/modules/pai/software.dm +++ b/code/modules/pai/software.dm @@ -125,7 +125,7 @@ if("Newscaster") newscaster = new(src) if("Photography Module") - camera = new(src) + aicamera = new /obj/item/camera/siliconcam/pai_camera(src) if("Remote Signaler") signaler = new(src) return TRUE diff --git a/icons/mob/actions/actions_silicon.dmi b/icons/mob/actions/actions_silicon.dmi index 7be634e9f6c..9c4b7ec7fbe 100644 Binary files a/icons/mob/actions/actions_silicon.dmi and b/icons/mob/actions/actions_silicon.dmi differ