diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 2ae4de8d754..8f590d77a4e 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -347,11 +347,6 @@ bug.bugged_cameras[src.c_tag] = src return - else if(istype(I, /obj/item/pai_cable)) - var/obj/item/pai_cable/cable = I - cable.plugin(src, user) - return - return ..() diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm index a938d618b1a..68cf8d961f3 100644 --- a/code/game/objects/items/devices/aicard.dm +++ b/code/game/objects/items/devices/aicard.dm @@ -40,20 +40,20 @@ log_combat(user, AI, "carded", src) update_icon() //Whatever happened, update the card's state (icon, name) to match. -/obj/item/aicard/update_icon() - cut_overlays() - if(AI) - name = "[initial(name)] - [AI.name]" - if(AI.stat == DEAD) - icon_state = "[initial(icon_state)]-404" - else - icon_state = "[initial(icon_state)]-full" - if(!AI.control_disabled) - add_overlay("[initial(icon_state)]-on") - AI.cancel_camera() - else +/obj/item/aicard/update_icon_state() + if(!AI) name = initial(name) icon_state = initial(icon_state) + return + name = "[initial(name)] - [AI.name]" + icon_state = "[initial(icon_state)][AI.stat == DEAD ? "-404" : "-full"]" + AI.cancel_camera() + +/obj/item/aicard/update_overlays() + . = ..() + if(!AI || AI.control_disabled) + return + . += "[initial(icon_state)]-on" /obj/item/aicard/ui_state(mob/user) return GLOB.hands_state diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm index cde3702087e..283f3637758 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/game/objects/items/devices/paicard.dm @@ -9,6 +9,7 @@ w_class = WEIGHT_CLASS_SMALL slot_flags = ITEM_SLOT_BELT var/mob/living/silicon/pai/pai + var/emotion_icon = "off" ///what emotion icon we have. handled in /mob/living/silicon/pai/Topic() resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE /obj/item/paicard/suicide_act(mob/living/user) @@ -17,13 +18,31 @@ /obj/item/paicard/Initialize() SSpai.pai_card_list += src - add_overlay("pai-off") + . = ..() + update_icon() + +/obj/item/paicard/vv_edit_var(vname, vval) + . = ..() + if(vname == NAMEOF(src, emotion_icon)) + update_icon() + +/obj/item/paicard/handle_atom_del(atom/A) + if(A == pai) //double check /mob/living/silicon/pai/Destroy() if you change these. + pai = null + emotion_icon = initial(emotion_icon) + update_icon() return ..() +/obj/item/paicard/update_overlays() + . = ..() + . += "pai-[emotion_icon]" + if(pai?.hacking_cable) + . += "[initial(icon_state)]-connector" + /obj/item/paicard/Destroy() //Will stop people throwing friend pAIs into the singularity so they can respawn SSpai.pai_card_list -= src - if (!QDELETED(pai)) + if(!QDELETED(pai)) QDEL_NULL(pai) return ..() @@ -130,39 +149,13 @@ // WIRE_TRANSMIT = 4 /obj/item/paicard/proc/setPersonality(mob/living/silicon/pai/personality) - src.pai = personality - src.add_overlay("pai-null") + pai = personality + emotion_icon = "null" + update_icon() playsound(loc, 'sound/effects/pai_boot.ogg', 50, TRUE, -1) audible_message("\The [src] plays a cheerful startup noise!") -/obj/item/paicard/proc/setEmotion(emotion) - if(pai) - src.cut_overlays() - switch(emotion) - if(1) - src.add_overlay("pai-happy") - if(2) - src.add_overlay("pai-cat") - if(3) - src.add_overlay("pai-extremely-happy") - if(4) - src.add_overlay("pai-face") - if(5) - src.add_overlay("pai-laugh") - if(6) - src.add_overlay("pai-off") - if(7) - src.add_overlay("pai-sad") - if(8) - src.add_overlay("pai-angry") - if(9) - src.add_overlay("pai-what") - if(10) - src.add_overlay("pai-null") - if(11) - src.add_overlay("pai-sunglasses") - /obj/item/paicard/proc/alertUpdate() audible_message("[src] flashes a message across its screen, \"Additional personalities available for download.\"", "[src] vibrates with an alert.") diff --git a/code/game/objects/items/paiwire.dm b/code/game/objects/items/paiwire.dm index 0dbf23e937f..1e14be9a385 100644 --- a/code/game/objects/items/paiwire.dm +++ b/code/game/objects/items/paiwire.dm @@ -4,7 +4,12 @@ icon = 'icons/obj/power.dmi' icon_state = "wire1" item_flags = NOBLUDGEON - var/obj/machinery/machine + var/obj/machinery/machine //what machine we're currently hacking. + +/obj/item/pai_cable/machine/Destroy() + machine = null + return ..() + /obj/item/pai_cable/proc/plugin(obj/machinery/M, mob/living/user) if(!user.transferItemToLoc(src, M)) diff --git a/code/game/objects/structures/ai_core.dm b/code/game/objects/structures/ai_core.dm index 3dc69b1a592..cd6c285cebf 100644 --- a/code/game/objects/structures/ai_core.dm +++ b/code/game/objects/structures/ai_core.dm @@ -244,8 +244,7 @@ if(AI_READY_CORE) if(istype(P, /obj/item/aicard)) - P.transfer_ai("INACTIVE", "AICARD", src, user) - return + return //handled by /obj/structure/ai_core/transfer_ai() if(P.tool_behaviour == TOOL_SCREWDRIVER) P.play_tool_sound(src) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 4baf74fa5e1..4485e86e6a2 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -13,6 +13,9 @@ maxHealth = 500 layer = BELOW_MOB_LAYER can_be_held = TRUE + move_force = 0 + pull_force = 0 + move_resist = 0 worn_slot_flags = ITEM_SLOT_HEAD held_lh = 'icons/mob/pai_item_lh.dmi' held_rh = 'icons/mob/pai_item_rh.dmi' @@ -32,7 +35,7 @@ var/speakDoubleExclamation = "alarms" var/speakQuery = "queries" - var/obj/item/pai_cable/cable // The cable we produce and use when door or camera jacking + var/obj/item/pai_cable/hacking_cable // The cable we produce when hacking a door var/master // Name of the one who commands us var/master_dna // DNA string for owner verification @@ -66,7 +69,6 @@ var/canholo = TRUE var/can_transmit = TRUE var/can_receive = TRUE - var/obj/item/card/id/access_card = null var/chassis = "repairbot" var/list/possible_chassis = list("cat" = TRUE, "mouse" = TRUE, "monkey" = TRUE, "corgi" = FALSE, "fox" = FALSE, "repairbot" = TRUE, "rabbit" = TRUE, "bat" = FALSE, "butterfly" = FALSE, "hawk" = FALSE, "lizard" = FALSE, "duffel" = TRUE) //assoc value is whether it can be picked up. @@ -92,15 +94,32 @@ /mob/living/silicon/pai/add_sensors() //pAIs have to buy their HUDs return +/mob/living/silicon/pai/handle_atom_del(atom/A) + if(A == hacking_cable) + hacking_cable = null + if(!QDELETED(card)) + card.update_icon() + if(A == internal_instrument) + internal_instrument = null + if(A == newscaster) + newscaster = null + if(A == signaler) + signaler = null + if(A == hostscan) + hostscan = null + return ..() + /mob/living/silicon/pai/Destroy() QDEL_NULL(internal_instrument) - if(cable) - QDEL_NULL(cable) - if (loc != card) + QDEL_NULL(hacking_cable) + QDEL_NULL(newscaster) + QDEL_NULL(signaler) + QDEL_NULL(hostscan) + if(!QDELETED(card) && loc != card) card.forceMove(drop_location()) - card.pai = null - card.cut_overlays() - card.add_overlay("pai-off") + card.pai = null //these are otherwise handled by paicard/handle_atom_del() + card.emotion_icon = initial(card.emotion_icon) + card.update_icon() GLOB.pai_list -= src return ..() @@ -138,19 +157,24 @@ aiPDA.name = real_name + " (" + aiPDA.ownjob + ")" /mob/living/silicon/pai/proc/process_hack() - if(cable && cable.machine && istype(cable.machine, /obj/machinery/door) && cable.machine == hackdoor && get_dist(src, hackdoor) <= 1) + + + if(hacking_cable && hacking_cable.machine && istype(hacking_cable.machine, /obj/machinery/door) && hacking_cable.machine == hackdoor && get_dist(src, hackdoor) <= 1) hackprogress = clamp(hackprogress + 4, 0, 100) else temp = "Door Jack: Connection to airlock has been lost. Hack aborted." hackprogress = 0 hacking = FALSE hackdoor = null + QDEL_NULL(hacking_cable) + if(!QDELETED(card)) + card.update_icon() return if(screen == "doorjack" && subscreen == 0) // Update our view, if appropriate paiInterface() if(hackprogress >= 100) hackprogress = 0 - var/obj/machinery/door/D = cable.machine + var/obj/machinery/door/D = hacking_cable.machine D.open() hacking = FALSE @@ -272,13 +296,15 @@ . = ..() if(QDELETED(src) || stat == DEAD) return - if(cable) - if(get_dist(src, cable) > 1) + if(hacking_cable) + if(get_dist(src, hacking_cable) > 1) var/turf/T = get_turf(src) - T.visible_message("[cable] rapidly retracts back into its spool.", "You hear a click and the sound of wire spooling rapidly.") - QDEL_NULL(cable) - if(hacking) - process_hack() + T.visible_message("[hacking_cable] rapidly retracts back into its spool.", "You hear a click and the sound of wire spooling rapidly.") + QDEL_NULL(hacking_cable) + if(!QDELETED(card)) + card.update_icon() + else if(hacking) + process_hack() silent = max(silent - 1, 0) /mob/living/silicon/pai/updatehealth() @@ -291,12 +317,12 @@ emitterhealth = clamp((emitterhealth + emitterregen), -50, emittermaxhealth) /obj/item/paicard/attackby(obj/item/W, mob/user, params) - ..() - user.set_machine(src) - if(pai && pai.encryptmod == TRUE) - if(W.tool_behaviour == TOOL_SCREWDRIVER) - pai.radio.attackby(W, user, params) - else if(istype(W, /obj/item/encryptionkey)) - pai.radio.attackby(W, user, params) - else - to_chat(user, "Encryption Key ports not configured.") + if(pai && (istype(W, /obj/item/encryptionkey) || W.tool_behaviour == TOOL_SCREWDRIVER)) + if(!pai.encryptmod) + to_chat(user, "Encryption Key ports not configured.") + return + user.set_machine(src) + pai.radio.attackby(W, user, params) + return + + return ..() diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index a90b330c590..a2c4d999039 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -1,8 +1,6 @@ // TODO: // - Potentially roll HUDs and Records into one // - Shock collar/lock system for prisoner pAIs? -// - Put cable in user's hand instead of on the ground -// - Camera jack /mob/living/silicon/pai/var/list/available_software = list( @@ -20,9 +18,6 @@ "security records" = 10, "camera zoom" = 10, "host scan" = 10, - //"camera jack" = 10, - //"heartbeat sensor" = 10, - //"projection array" = 15, "medical HUD" = 20, "security HUD" = 20, "loudness booster" = 20, @@ -72,8 +67,6 @@ left_part = medicalAnalysis() if("doorjack") left_part = softwareDoor() - if("camerajack") - left_part = softwareCamera() if("signaller") left_part = softwareSignal() if("loudness") @@ -158,32 +151,14 @@ if("image") // Set pAI card display face var/newImage = input("Select your new display image.", "Display Image", "Happy") in sortList(list("Happy", "Cat", "Extremely Happy", "Face", "Laugh", "Off", "Sad", "Angry", "What", "Sunglasses")) - var/pID = 1 - switch(newImage) - if("Happy") - pID = 1 - if("Cat") - pID = 2 + if(null) + card.emotion_icon = "null" if("Extremely Happy") - pID = 3 - if("Face") - pID = 4 - if("Laugh") - pID = 5 - if("Off") - pID = 6 - if("Sad") - pID = 7 - if("Angry") - pID = 8 - if("What") - pID = 9 - if("Null") - pID = 10 - if("Sunglasses") - pID = 11 - card.setEmotion(pID) + card.emotion_icon = "extremely-happy" + else + card.emotion_icon = "[lowertext(newImage)]" + card.update_icon() if("news") newscaster.ui_interact(src) @@ -285,15 +260,25 @@ if("doorjack") if(href_list["jack"]) - if(cable && cable.machine) - hackdoor = cable.machine + if(hacking_cable?.machine) + hackdoor = hacking_cable.machine hackloop() if(href_list["cancel"]) hackdoor = null if(href_list["cable"]) - var/turf/T = get_turf(loc) - cable = new /obj/item/pai_cable(T) - T.visible_message("A port on [src] opens to reveal [cable], which promptly falls to the floor.", "You hear the soft click of something light and hard falling to the ground.") + qdel(hacking_cable) //clear any old cables + hacking_cable = new + var/transfered_to_mob + if(isliving(card.loc)) + var/mob/living/L = card.loc + if(L.put_in_hands(hacking_cable)) + transfered_to_mob = TRUE + L.visible_message("A port on [src] opens to reveal \a [hacking_cable], which you quickly grab hold of.", "You hear the soft click of something light and manage to catch hold of [hacking_cable].") + if(!transfered_to_mob) + hacking_cable.forceMove(drop_location()) + hacking_cable.visible_message("A port on [src] opens to reveal \a [hacking_cable], which promptly falls to the floor.", "You hear the soft click of something light and hard falling to the ground.") + + if("loudness") if(subscreen == 1) // Open Instrument @@ -329,8 +314,6 @@ dat += "Medical Records
" if(s == "security records") dat += "Security Records
" - if(s == "camera") - dat += "Camera Jack
" if(s == "remote signaller") dat += "Remote Signaller
" if(s == "loudness booster") @@ -344,8 +327,6 @@ dat += "Adjust Camera Zoom
" if(s == "atmosphere sensor") dat += "Atmospheric Sensor
" - if(s == "heartbeat sensor") - dat += "Heartbeat Sensor
" if(s == "security HUD") dat += "Facial Recognition Suite[(secHUD) ? " On" : " Off"]
" if(s == "medical HUD") @@ -355,10 +336,6 @@ if(s == "universal translator") var/datum/language_holder/H = get_language_holder() dat += "Universal Translator[H.omnitongue ? " On" : " Off"]
" - if(s == "projection array") - dat += "Projection Array
" - if(s == "camera jack") - dat += "Camera Jack
" if(s == "door jack") dat += "Door Jack
" dat += "
" @@ -576,41 +553,20 @@ dat += "Refresh Reading
" dat += "
" return dat - -// Camera Jack - Clearly not finished -/mob/living/silicon/pai/proc/softwareCamera() - var/dat = "

Camera Jack

" - dat += "Cable status : " - - if(!cable) - dat += "Retracted
" - return dat - if(!cable.machine) - dat += "Extended
" - return dat - - var/obj/machinery/machine = cable.machine - dat += "Connected
" - - if(!istype(machine, /obj/machinery/camera)) - to_chat(src, "DERP") - return dat - // Door Jack /mob/living/silicon/pai/proc/softwareDoor() var/dat = "

Airlock Jack

" dat += "Cable status : " - if(!cable) + if(!hacking_cable) dat += "Retracted
" - dat += "Extend Cable
" + dat += "Extend Cable
" return dat - if(!cable.machine) + if(!hacking_cable.machine) dat += "Extended
" return dat - var/obj/machinery/machine = cable.machine dat += "Connected
" - if(!istype(machine, /obj/machinery/door)) + if(!istype(hacking_cable.machine, /obj/machinery/door)) dat += "Connected device's firmware does not appear to be compatible with Airlock Jack protocols.
" return dat diff --git a/icons/obj/aicards.dmi b/icons/obj/aicards.dmi index 07bff4ad724..ccac1852a73 100644 Binary files a/icons/obj/aicards.dmi and b/icons/obj/aicards.dmi differ