diff --git a/code/game/machinery/computer/HolodeckControl.dm b/code/game/machinery/computer/HolodeckControl.dm index e4c6e621fee..431bb10cc4c 100644 --- a/code/game/machinery/computer/HolodeckControl.dm +++ b/code/game/machinery/computer/HolodeckControl.dm @@ -32,11 +32,11 @@ dat += "(Begin Wildlife Simulation)
" dat += "Ensure the holodeck is empty before testing.
" dat += "
" - if(issilicon(user)) + if(isaiorborg(user)) dat += "(Re-Enable Safety Protocols?)
" dat += "Safety Protocols are DISABLED
" else - if(issilicon(user)) + if(isaiorborg(user)) dat += "(Override Safety Protocols?)
" dat += "
" dat += "Safety Protocols are ENABLED
" diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 449bc3b3074..5331562c2ea 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -222,6 +222,9 @@ src.temp = "You have been drained! GAME OVER" if(emagged) feedback_inc("arcade_loss_mana_emagged") + if(ispAI(usr)) + var/mob/living/silicon/pai/pai = usr + pai.card.explode() usr.gib() else feedback_inc("arcade_loss_mana_normal") @@ -241,6 +244,9 @@ src.temp = "You have been crushed! GAME OVER" if(emagged) feedback_inc("arcade_loss_hp_emagged") + if(ispAI(usr)) + var/mob/living/silicon/pai/pai = usr + pai.card.explode() usr.gib() else feedback_inc("arcade_loss_hp_normal") diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 0d29218a025..5e8f7770730 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -35,6 +35,12 @@ if(..()) return + if(ispAI(usr)) + if(paired != usr) + user.reset_view() + user.unset_machine() + return + var/list/L = list() for (var/obj/machinery/camera/C in cameranet.cameras) L.Add(C) @@ -56,33 +62,41 @@ var/t = input(user, "Which camera should you change to?") as null|anything in D if(!t) + if(!isAI(user)) + user.reset_view() user.unset_machine() return 0 var/obj/machinery/camera/C = D[t] if(t == "Cancel") + if(!isAI(user)) + user.reset_view() user.unset_machine() return 0 if(C) - if ((get_dist(user, src) > 1 || user.machine != src || user.blinded || !( C.can_use() )) && (!istype(user, /mob/living/silicon/ai))) - if(!C.can_use() && !isAI(user)) - src.current = null + if(isAI(user)) + var/mob/living/silicon/ai/A = user + A.eyeobj.setLoc(get_turf(C)) + A.client.eye = A.eyeobj + if(ispAI(user)) + var/mob/living/silicon/pai/A = user + A.switchCamera(C) + else if ((get_dist(user, src) > 1) || (user.machine != src)|| user.blinded || !( C.can_use() )) + src.current = null return 0 else - if(isAI(user)) - var/mob/living/silicon/ai/A = user - A.eyeobj.setLoc(get_turf(C)) - A.client.eye = A.eyeobj - else - src.current = C - use_power(50) - - spawn(5) - attack_hand(user) + src.current = C + use_power(50) + spawn(5) + attack_hand(user) + return + else + if(!isAI(user)) + user.reset_view() + user.unset_machine() return - /obj/machinery/computer/security/telescreen @@ -93,6 +107,7 @@ network = list("thunder") density = 0 circuit = null + paiallowed = 0 //2retro /obj/machinery/computer/security/telescreen/update_icon() icon_state = initial(icon_state) @@ -114,6 +129,7 @@ name = "security camera monitor" desc = "An old TV hooked into the stations camera network." icon_state = "security_det" + paiallowed = 0 //2retro /obj/machinery/computer/security/mining diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index d387102becf..f3299e61f20 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -8,6 +8,7 @@ active_power_usage = 300 var/obj/item/weapon/circuitboard/circuit = null //if circuit==null, computer can't disassembly var/processing = 0 + paiallowed = 1 /obj/machinery/computer/New() ..() @@ -88,6 +89,8 @@ /obj/machinery/computer/proc/set_broken() if(circuit) //no circuit, no breaking + if(paired) + paired.unpair(0) stat |= BROKEN update_icon() return @@ -112,6 +115,17 @@ A.state = 4 A.icon_state = "4" qdel(src) + if(istype(I, /obj/item/device/paicard)) + var/obj/item/device/paicard/C = I + if(C.pai && (C.pai.stat != DEAD) && C.pai.pairing) + if(allowed(user)) + if(paiallowed) + C.pai.pair(src) + else + C.pai << "\[ERROR\] Remote device does not accept remote control connections." + else + user << "Access denied." + C.pai << "\[ERROR\] Handshake failed. User not authorised to connect remote devices." return /obj/machinery/computer/attack_hand(user) @@ -140,4 +154,4 @@ return user.visible_message("[user.name] smashes against the [src.name] with its claws.",\ "You smash against the [src.name] with your claws.",\ - "You hear a clicking sound.") + "You hear a clicking sound.") \ No newline at end of file diff --git a/code/game/machinery/computer/law.dm b/code/game/machinery/computer/law.dm index 58991352c91..959bbc67b45 100644 --- a/code/game/machinery/computer/law.dm +++ b/code/game/machinery/computer/law.dm @@ -3,6 +3,7 @@ /obj/machinery/computer/upload var/mob/living/silicon/current = null //The target of future law uploads icon_state = null //To make sure mappers understand THIS ISN'T A VALID TYPE + paiallowed = 0 /obj/machinery/computer/upload/attackby(obj/item/O as obj, mob/user as mob) if(istype(O, /obj/item/weapon/aiModule)) diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index b2a5436ef66..e1eed34cc29 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -133,12 +133,18 @@ src.active1 = null src.active2 = null else if (href_list["login"]) - if (istype(usr, /mob/living/silicon)) - src.active1 = null - src.active2 = null - src.authenticated = 1 - src.rank = "AI" - src.screen = 1 + if (isaiorborg(usr)) + active1 = null + active2 = null + authenticated = 1 + rank = "AI" + screen = 1 + else if (ispAI(usr)) + active1 = null + active2 = null + authenticated = usr.name + rank = "pAI" + screen = 1 else if (istype(src.scan, /obj/item/weapon/card/id)) src.active1 = null src.active2 = null @@ -453,3 +459,4 @@ name = "medical laptop" desc = "A cheap Nanotrasen medical laptop, it functions as a medical records computer. It's bolted to the table." icon_state = "medlaptop" + paiallowed = 0 //Go use a real computer diff --git a/code/game/machinery/computer/pod.dm b/code/game/machinery/computer/pod.dm index 5b93f9e6d53..a412954abfc 100644 --- a/code/game/machinery/computer/pod.dm +++ b/code/game/machinery/computer/pod.dm @@ -123,6 +123,7 @@ icon_state = "old" name = "\improper DoorMex control console" title = "Door Controls" + paiallowed = 0 //2retro /obj/machinery/computer/pod/old/syndicate diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index 5034a19f459..e9fabd91fb5 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -230,12 +230,18 @@ What a mess.*/ active2 = null if("Log In") - if (istype(usr, /mob/living/silicon)) + if (isaiorborg(usr)) active1 = null active2 = null authenticated = 1 rank = "AI" screen = 1 + else if (ispAI(usr)) + active1 = null + active2 = null + authenticated = usr.name + rank = "pAI" + screen = 1 else if (istype(scan, /obj/item/weapon/card/id)) active1 = null active2 = null @@ -556,3 +562,4 @@ What a mess.*/ /obj/machinery/computer/secure_data/detective_computer icon = 'icons/obj/computer.dmi' icon_state = "messyfiles" + paiallowed = 0 //2retro diff --git a/code/game/machinery/computer/shuttle.dm b/code/game/machinery/computer/shuttle.dm index d43833b955f..ee7ea2b1d81 100644 --- a/code/game/machinery/computer/shuttle.dm +++ b/code/game/machinery/computer/shuttle.dm @@ -4,6 +4,7 @@ icon_state = "shuttle" var/auth_need = 3.0 var/list/authorized = list( ) + paiallowed = 0 attackby(var/obj/item/weapon/card/W as obj, var/mob/user as mob) diff --git a/code/game/machinery/computer/telecrystalconsoles.dm b/code/game/machinery/computer/telecrystalconsoles.dm index 9f9c32260d2..682b79adcb5 100644 --- a/code/game/machinery/computer/telecrystalconsoles.dm +++ b/code/game/machinery/computer/telecrystalconsoles.dm @@ -1,221 +1,222 @@ -#define NUKESCALINGMODIFIER 0.5 - -var/list/possible_uplinker_IDs = list("Alfa","Bravo","Charlie","Delta","Echo","Foxtrot","Zero", "Niner") - - -/obj/machinery/computer/telecrystals - name = "\improper Telecrystal assignment station" - desc = "A device used to manage telecrystals during group operations. You shouldn't be looking at this particular one..." - icon_state = "tcstation" - -///////////////////////////////////////////// -/obj/machinery/computer/telecrystals/uplinker - name = "\improper Telecrystal upload/recieve station" - desc = "A device used to manage telecrystals during group operations. To use, simply insert your uplink. With your uplink installed \ - you can upload your telecrystals to the group's pool using the console, or be assigned additional telecrystals by your lieutenant." - icon_state = "tcstation" - var/obj/item/uplinkholder = null - var/obj/machinery/computer/telecrystals/boss/linkedboss = null - -/obj/machinery/computer/telecrystals/uplinker/New() - ..() - - var/ID - if(possible_uplinker_IDs.len) - ID = pick(possible_uplinker_IDs) - possible_uplinker_IDs -= ID - name = "[name] [ID]" - else - name = "[name] [rand(1,999)]" - - -/obj/machinery/computer/telecrystals/uplinker/attackby(var/obj/item/O as obj, var/mob/user as mob) - if(istype(O, /obj/item)) - - if(uplinkholder) - user << "The [src] already has an uplink in it." - return - - if(O.hidden_uplink) - var/obj/item/P = user.get_active_hand() - user.drop_item() - uplinkholder = P - P.loc = src - P.add_fingerprint(user) - update_icon() - updateUsrDialog() - else - user << "The [O] doesn't appear to be an uplink..." - - - -/obj/machinery/computer/telecrystals/uplinker/update_icon() - overlays.Cut() - if(uplinkholder) - overlays += "[initial(icon_state)]-closed" - - -/obj/machinery/computer/telecrystals/uplinker/proc/ejectuplink() - if(uplinkholder) - uplinkholder.loc = get_turf(src.loc) - uplinkholder = null - update_icon() - -/obj/machinery/computer/telecrystals/uplinker/proc/donateTC(var/amt, var/addLog = 1) - if(uplinkholder && linkedboss) - if(amt <= uplinkholder.hidden_uplink.uses) - uplinkholder.hidden_uplink.uses -= amt - linkedboss.storedcrystals += amt - if(addLog) - linkedboss.logTransfer("[src] donated [amt] telecrystals to [linkedboss].") - -/obj/machinery/computer/telecrystals/uplinker/proc/giveTC(var/amt, var/addLog = 1) - if(uplinkholder && linkedboss) - if(amt <= linkedboss.storedcrystals) - uplinkholder.hidden_uplink.uses += amt - linkedboss.storedcrystals -= amt - if(addLog) - linkedboss.logTransfer("[src] recieved [amt] telecrystals from [linkedboss].") - -/////// - -/obj/machinery/computer/telecrystals/uplinker/attack_hand(mob/user as mob) - if(..()) - return - src.add_fingerprint(user) - user.set_machine(src) - - var/dat = "" - if(linkedboss) - dat += "[linkedboss] has [linkedboss.storedcrystals] telecrystals available for distribution.

" - else - dat += "No linked management consoles detected. Scan for uplink stations using the management console.

" - - if(uplinkholder) - dat += "[uplinkholder.hidden_uplink.uses] telecrystals remain in this uplink.
" - if(linkedboss) - dat += "Donate TC: 1 | 5" - dat += "
Eject Uplink" - - - var/datum/browser/popup = new(user, "computer", "Telecrystal Upload/Recieve Station", 700, 500) - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() - return - -/obj/machinery/computer/telecrystals/uplinker/Topic(href, href_list) - if(..()) - return - - if(href_list["donate1"]) - donateTC(1) - - if(href_list["donate5"]) - donateTC(5) - - if(href_list["eject"]) - ejectuplink() - - src.updateUsrDialog() - - -///////////////////////////////////////// -/obj/machinery/computer/telecrystals/boss - name = "team Telecrystal management console" - desc = "A device used to manage telecrystals during group operations. To use, simply initialize the machine by scanning for nearby uplink stations. \ - Once the consoles are linked up, you can assign any telecrystals amongst your operatives; be they donated by your agents or rationed to the squad \ - based on the danger rating of the mission." - icon_state = "tcboss" - var/virgin = 1 - var/scanrange = 10 - var/storedcrystals = 0 - var/list/TCstations = list() - var/list/transferlog = list() - -/obj/machinery/computer/telecrystals/boss/proc/logTransfer(var/logmessage) - transferlog += ("[worldtime2text()] [logmessage]") - -/obj/machinery/computer/telecrystals/boss/proc/scanUplinkers() - for(var/obj/machinery/computer/telecrystals/uplinker/A in range(scanrange, src.loc)) - if(!A.linkedboss) - TCstations += A - A.linkedboss = src - if(virgin) - getDangerous() - virgin = 0 - -/obj/machinery/computer/telecrystals/boss/proc/getDangerous()//This scales the TC assigned with the round population. - ..() - var/danger - danger = player_list.len - while(!IsMultiple(++danger,10))//Just round up to the nearest multiple of ten. - scaleTC(danger) - -/obj/machinery/computer/telecrystals/boss/proc/scaleTC(var/amt)//Its own proc, since it'll probably need a lot of tweaks for balance, use a fancier algorhithm, etc. - storedcrystals += amt * NUKESCALINGMODIFIER - -///////// - -/obj/machinery/computer/telecrystals/boss/attack_hand(var/mob/user as mob) - if(..()) - return - src.add_fingerprint(user) - user.set_machine(src) - - - var/dat = "" - dat += "Scan for TC stations.
" - dat += "This [src] has [storedcrystals] telecrystals available for distribution.
" - dat += "

" - - - for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations) - dat += "[A.name] | " - if(A.uplinkholder) - dat += "[A.uplinkholder.hidden_uplink.uses] telecrystals." - if(storedcrystals) - dat+= "
Add TC: 1 | 5" - dat += "
" - - if(TCstations.len) - dat += "

Evenly distribute remaining TC.

" - - - for(var/entry in transferlog) - dat += "[entry]
" - - - var/datum/browser/popup = new(user, "computer", "Team Telecrystal Management Console", 700, 500) - popup.set_content(dat) - popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) - popup.open() - return - -/obj/machinery/computer/telecrystals/boss/Topic(href, href_list) - if(..()) - return - - if(href_list["scan"]) - scanUplinkers() - - if(href_list["give1"]) - var/obj/machinery/computer/telecrystals/uplinker/A = locate(href_list["give1"]) - A.giveTC(1) - - if(href_list["give5"]) - var/obj/machinery/computer/telecrystals/uplinker/A = locate(href_list["give5"]) - A.giveTC(5) - - if(href_list["distrib"]) - var/sanity = 0 - while(storedcrystals && sanity < 100) - for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations) - A.giveTC(1,0) - sanity++ - logTransfer("[src] evenly distributed telecrystals.") - - src.updateUsrDialog() - return - +#define NUKESCALINGMODIFIER 0.5 + +var/list/possible_uplinker_IDs = list("Alfa","Bravo","Charlie","Delta","Echo","Foxtrot","Zero", "Niner") + + +/obj/machinery/computer/telecrystals + name = "\improper Telecrystal assignment station" + desc = "A device used to manage telecrystals during group operations. You shouldn't be looking at this particular one..." + icon_state = "tcstation" + paiallowed = 0 + +///////////////////////////////////////////// +/obj/machinery/computer/telecrystals/uplinker + name = "\improper Telecrystal upload/recieve station" + desc = "A device used to manage telecrystals during group operations. To use, simply insert your uplink. With your uplink installed \ + you can upload your telecrystals to the group's pool using the console, or be assigned additional telecrystals by your lieutenant." + icon_state = "tcstation" + var/obj/item/uplinkholder = null + var/obj/machinery/computer/telecrystals/boss/linkedboss = null + +/obj/machinery/computer/telecrystals/uplinker/New() + ..() + + var/ID + if(possible_uplinker_IDs.len) + ID = pick(possible_uplinker_IDs) + possible_uplinker_IDs -= ID + name = "[name] [ID]" + else + name = "[name] [rand(1,999)]" + + +/obj/machinery/computer/telecrystals/uplinker/attackby(var/obj/item/O as obj, var/mob/user as mob) + if(istype(O, /obj/item)) + + if(uplinkholder) + user << "The [src] already has an uplink in it." + return + + if(O.hidden_uplink) + var/obj/item/P = user.get_active_hand() + user.drop_item() + uplinkholder = P + P.loc = src + P.add_fingerprint(user) + update_icon() + updateUsrDialog() + else + user << "The [O] doesn't appear to be an uplink..." + + + +/obj/machinery/computer/telecrystals/uplinker/update_icon() + overlays.Cut() + if(uplinkholder) + overlays += "[initial(icon_state)]-closed" + + +/obj/machinery/computer/telecrystals/uplinker/proc/ejectuplink() + if(uplinkholder) + uplinkholder.loc = get_turf(src.loc) + uplinkholder = null + update_icon() + +/obj/machinery/computer/telecrystals/uplinker/proc/donateTC(var/amt, var/addLog = 1) + if(uplinkholder && linkedboss) + if(amt <= uplinkholder.hidden_uplink.uses) + uplinkholder.hidden_uplink.uses -= amt + linkedboss.storedcrystals += amt + if(addLog) + linkedboss.logTransfer("[src] donated [amt] telecrystals to [linkedboss].") + +/obj/machinery/computer/telecrystals/uplinker/proc/giveTC(var/amt, var/addLog = 1) + if(uplinkholder && linkedboss) + if(amt <= linkedboss.storedcrystals) + uplinkholder.hidden_uplink.uses += amt + linkedboss.storedcrystals -= amt + if(addLog) + linkedboss.logTransfer("[src] recieved [amt] telecrystals from [linkedboss].") + +/////// + +/obj/machinery/computer/telecrystals/uplinker/attack_hand(mob/user as mob) + if(..()) + return + src.add_fingerprint(user) + user.set_machine(src) + + var/dat = "" + if(linkedboss) + dat += "[linkedboss] has [linkedboss.storedcrystals] telecrystals available for distribution.

" + else + dat += "No linked management consoles detected. Scan for uplink stations using the management console.

" + + if(uplinkholder) + dat += "[uplinkholder.hidden_uplink.uses] telecrystals remain in this uplink.
" + if(linkedboss) + dat += "Donate TC: 1 | 5" + dat += "
Eject Uplink" + + + var/datum/browser/popup = new(user, "computer", "Telecrystal Upload/Recieve Station", 700, 500) + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() + return + +/obj/machinery/computer/telecrystals/uplinker/Topic(href, href_list) + if(..()) + return + + if(href_list["donate1"]) + donateTC(1) + + if(href_list["donate5"]) + donateTC(5) + + if(href_list["eject"]) + ejectuplink() + + src.updateUsrDialog() + + +///////////////////////////////////////// +/obj/machinery/computer/telecrystals/boss + name = "team Telecrystal management console" + desc = "A device used to manage telecrystals during group operations. To use, simply initialize the machine by scanning for nearby uplink stations. \ + Once the consoles are linked up, you can assign any telecrystals amongst your operatives; be they donated by your agents or rationed to the squad \ + based on the danger rating of the mission." + icon_state = "tcboss" + var/virgin = 1 + var/scanrange = 10 + var/storedcrystals = 0 + var/list/TCstations = list() + var/list/transferlog = list() + +/obj/machinery/computer/telecrystals/boss/proc/logTransfer(var/logmessage) + transferlog += ("[worldtime2text()] [logmessage]") + +/obj/machinery/computer/telecrystals/boss/proc/scanUplinkers() + for(var/obj/machinery/computer/telecrystals/uplinker/A in range(scanrange, src.loc)) + if(!A.linkedboss) + TCstations += A + A.linkedboss = src + if(virgin) + getDangerous() + virgin = 0 + +/obj/machinery/computer/telecrystals/boss/proc/getDangerous()//This scales the TC assigned with the round population. + ..() + var/danger + danger = player_list.len + while(!IsMultiple(++danger,10))//Just round up to the nearest multiple of ten. + scaleTC(danger) + +/obj/machinery/computer/telecrystals/boss/proc/scaleTC(var/amt)//Its own proc, since it'll probably need a lot of tweaks for balance, use a fancier algorhithm, etc. + storedcrystals += amt * NUKESCALINGMODIFIER + +///////// + +/obj/machinery/computer/telecrystals/boss/attack_hand(var/mob/user as mob) + if(..()) + return + src.add_fingerprint(user) + user.set_machine(src) + + + var/dat = "" + dat += "Scan for TC stations.
" + dat += "This [src] has [storedcrystals] telecrystals available for distribution.
" + dat += "

" + + + for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations) + dat += "[A.name] | " + if(A.uplinkholder) + dat += "[A.uplinkholder.hidden_uplink.uses] telecrystals." + if(storedcrystals) + dat+= "
Add TC: 1 | 5" + dat += "
" + + if(TCstations.len) + dat += "

Evenly distribute remaining TC.

" + + + for(var/entry in transferlog) + dat += "[entry]
" + + + var/datum/browser/popup = new(user, "computer", "Team Telecrystal Management Console", 700, 500) + popup.set_content(dat) + popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state)) + popup.open() + return + +/obj/machinery/computer/telecrystals/boss/Topic(href, href_list) + if(..()) + return + + if(href_list["scan"]) + scanUplinkers() + + if(href_list["give1"]) + var/obj/machinery/computer/telecrystals/uplinker/A = locate(href_list["give1"]) + A.giveTC(1) + + if(href_list["give5"]) + var/obj/machinery/computer/telecrystals/uplinker/A = locate(href_list["give5"]) + A.giveTC(5) + + if(href_list["distrib"]) + var/sanity = 0 + while(storedcrystals && sanity < 100) + for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations) + A.giveTC(1,0) + sanity++ + logTransfer("[src] evenly distributed telecrystals.") + + src.updateUsrDialog() + return + #undef NUKESCALINGMODIFIER \ No newline at end of file diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index db84ff75a83..662bea6800d 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -109,12 +109,16 @@ Class Procs: var/mob/living/occupant = null var/unsecuring_tool = /obj/item/weapon/wrench var/interact_offline = 0 // Can the machine be interacted with while de-powered. + var/mob/living/silicon/pai/paired + var/paiallowed = 0 /obj/machinery/New() ..() machines += src /obj/machinery/Destroy() + if(paired) + paired.unpair(0) machines.Remove(src) ..() @@ -208,6 +212,10 @@ Class Procs: usr << "You don't have the dexterity to do this!" return 1 + if(ispAI(usr)) + if(paired != usr) + return 1 + var/norange = 0 if(istype(usr, /mob/living/carbon/human)) var/mob/living/carbon/human/H = usr diff --git a/code/game/machinery/telecomms/traffic_control.dm b/code/game/machinery/telecomms/traffic_control.dm index 9a6f87c8d17..1fc91644fea 100644 --- a/code/game/machinery/telecomms/traffic_control.dm +++ b/code/game/machinery/telecomms/traffic_control.dm @@ -142,8 +142,10 @@ /obj/machinery/computer/telecomms/traffic/proc/create_log(var/entry, var/mob/user) var/id = null - if(issilicon(user)) + if(isaiorborg(user)) id = "System Administrator" + else if(ispAI(user)) + id = "[user.name] (pAI)" else if(auth) id = "[auth.registered_name] ([auth.assignment])" diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm index 3fa8f1593f8..f4acf51399d 100644 --- a/code/game/objects/items/devices/paicard.dm +++ b/code/game/objects/items/devices/paicard.dm @@ -134,3 +134,22 @@ pai.emp_act(severity) ..() +/obj/item/device/paicard/proc/explode() + var/turf/T = get_turf(src.loc) + + if (ismob(loc)) + var/mob/M = loc + M.show_message("\red Your [src] explodes!", 1) + else if(istype(loc, /obj/item/device/pda)) + var/obj/item/device/pda/P = loc + if(P.detonate) + P.explode() + qdel(src) + return + if(T) + T.hotspot_expose(700,125) + + explosion(T, -1, -1, 2, 3) + + qdel(src) + return \ No newline at end of file diff --git a/code/modules/awaymissions/bluespaceartillery.dm b/code/modules/awaymissions/bluespaceartillery.dm index 32fadf2eef7..da6add53782 100644 --- a/code/modules/awaymissions/bluespaceartillery.dm +++ b/code/modules/awaymissions/bluespaceartillery.dm @@ -6,6 +6,7 @@ icon = 'icons/obj/machines/particle_accelerator.dmi' density = 1 anchored = 1 + paiallowed = 1 /obj/machinery/artillerycontrol/process() if(src.reload<180) @@ -20,6 +21,12 @@ /obj/structure/artilleryplaceholder/decorative density = 0 +/obj/machinery/artillerycontrol/attackby(I as obj, user as mob) + if(istype(I, /obj/item/device/paicard)) + var/obj/item/device/paicard/C = I + if(C.pai && (C.pai.stat != DEAD) && C.pai.pairing) + C.pai.pair(src) + /obj/machinery/artillerycontrol/attack_hand(mob/user as mob) user.set_machine(src) var/dat = "Bluespace Artillery Control:
" diff --git a/code/modules/mob/living/silicon/pai/death.dm b/code/modules/mob/living/silicon/pai/death.dm index 75e30dda3f9..8d30f3b20d3 100644 --- a/code/modules/mob/living/silicon/pai/death.dm +++ b/code/modules/mob/living/silicon/pai/death.dm @@ -1,5 +1,6 @@ /mob/living/silicon/pai/death(gibbed) if(stat == DEAD) return + unpair(1) stat = DEAD canmove = 0 if(blind) blind.layer = 0 diff --git a/code/modules/mob/living/silicon/pai/life.dm b/code/modules/mob/living/silicon/pai/life.dm index 385c0ae6760..9166e7ba855 100644 --- a/code/modules/mob/living/silicon/pai/life.dm +++ b/code/modules/mob/living/silicon/pai/life.dm @@ -29,5 +29,7 @@ /mob/living/silicon/pai/proc/follow_pai() while(card) loc = get_turf(card) + if(paired && (loc.z != paired.z)) + unpair(0) //Limit remote control to same z-level sleep(5) qdel(src) //if there's no pAI we shouldn't exist diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 89fb455c19d..160c0bebbda 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -52,6 +52,9 @@ var/obj/item/radio/integrated/signal/sradio // AI's signaller + var/obj/machinery/paired + var/pairing = 0 + /mob/living/silicon/pai/New(var/obj/item/device/paicard) canmove = 0 @@ -191,6 +194,40 @@ /mob/living/silicon/pai/UnarmedAttack(var/atom/A)//Stops runtimes due to attack_animal being the default return +/mob/living/silicon/pai/proc/unpair(var/silent = 0) + if(!paired) + return + if(!(paired.paired == src)) + return + src.unset_machine() + paired.overlays -= image('icons/obj/computer.dmi', "paipaired") + paired.paired = null + paired = null + if(!silent) + src << "\[ERROR\] Network timeout. Remote control connection severed." + return + +/mob/living/silicon/pai/proc/pair(var/obj/machinery/P) + if(!pairing) + return + if(!P) + return + if(P.stat & (BROKEN|NOPOWER)) + src << "\[ERROR\] Remote device not responding to remote control handshake. Cannot establish connection." + return + if(!P.paiallowed) + src << "\[ERROR\] Remote device does not accept remote control connections." + return + pairing = 0 + unpair(1) + if(P.paired && (P.paired != src)) + P.paired.unpair(0) + P.paired = src + paired = P + paired.overlays += image('icons/obj/computer.dmi', "paipaired") + src << "Handshake complete. Remote control connection established." + return + //Addition by Mord_Sith to define AI's network change ability /* /mob/living/silicon/pai/proc/pai_network_change() diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index cd797cb9ab3..aba8ab06ab1 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -13,6 +13,7 @@ "security records" = 15, //"camera jack" = 10, "door jack" = 30, + "remote control" = 60, "atmosphere sensor" = 5, //"heartbeat sensor" = 10, "security HUD" = 20, @@ -60,6 +61,8 @@ left_part = src.facialRecognition() if("medicalhud") left_part = src.medicalAnalysis() + if("remote") + left_part = src.remoteControl() if("doorjack") left_part = src.softwareDoor() if("camerajack") @@ -243,6 +246,19 @@ if("translator") if(href_list["toggle"]) src.universal_speak = !src.universal_speak + if("remote") + if(href_list["pair"]) + if(!paired) + pairing = 1 + if(href_list["abort"]) + if(!paired) + pairing = 0 + if(href_list["control"]) + if(paired && (paired.paired == src)) + paired.attack_hand(src) + if(href_list["disconnect"]) + unpair(1) + pairing = 0 if("doorjack") if(href_list["jack"]) if(src.cable && src.cable.machine) @@ -306,6 +322,8 @@ dat += "Projection Array
" if(s == "camera jack") dat += "Camera Jack
" + if(s == "remote control") + dat += "Remote Control
" if(s == "door jack") dat += "Door Jack
" dat += "
" @@ -561,6 +579,26 @@ src << "DERP" return dat +// Computer remote control +/mob/living/silicon/pai/proc/remoteControl() + var/dat = "

Remote control

" + dat += "Connection status : " + if(!paired) + if(!pairing) + dat += "Disconnected
" + dat += "Initiate connection
" + return dat + else + dat += "Waiting for connection...
" + dat += "Abort
" + dat += "Request to be swiped near the computer's network card to begin remote control handshake.
" + return dat + + dat += "Connected to [paired.name]
" + dat += "Access remote interface
" + dat += "Disconnect
" + return dat + // Door Jack /mob/living/silicon/pai/proc/softwareDoor() var/dat = "

Airlock Jack

" diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index 63d292b63c4..dc3946fafba 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -100,6 +100,11 @@ return 1 return 0 +/proc/isaiorborg(A) + if(istype(A, /mob/living/silicon/ai) || istype(A, /mob/living/silicon/robot)) + return 1 + return 0 + /proc/isliving(A) if(istype(A, /mob/living)) return 1 diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm index f07cd84d7b6..f88084ee433 100644 --- a/code/modules/power/power.dm +++ b/code/modules/power/power.dm @@ -71,7 +71,8 @@ if(powered(power_channel)) stat &= ~NOPOWER else - + if(paired) + paired.unpair(0) stat |= NOPOWER return diff --git a/code/modules/power/singularity/particle_accelerator/particle_control.dm b/code/modules/power/singularity/particle_accelerator/particle_control.dm index afaac0be300..4cee0645ae4 100644 --- a/code/modules/power/singularity/particle_accelerator/particle_control.dm +++ b/code/modules/power/singularity/particle_accelerator/particle_control.dm @@ -20,6 +20,7 @@ var/assembled = 0 var/parts = null var/datum/wires/particle_acc/control_box/wires = null + paiallowed = 1 /obj/machinery/particle_accelerator/control_box/New() wires = new(src) @@ -34,11 +35,21 @@ /obj/machinery/particle_accelerator/control_box/attack_hand(mob/user as mob) if(construction_state >= 3) interact(user) - else if(construction_state == 2) // Wires exposed + else if(construction_state == 2 && (get_dist(src, user) <= 1)) // Wires exposed wires.Interact(user) +/obj/machinery/particle_accelerator/control_box/attackby(obj/item/W, mob/user) + if(istype(W, /obj/item/device/paicard)) + var/obj/item/device/paicard/C = W + if(C.pai && (C.pai.stat != DEAD) && C.pai.pairing) + C.pai.pair(src) + else + ..() + /obj/machinery/particle_accelerator/control_box/update_state() if(construction_state < 3) + if(paired) + paired.unpair() use_power = 0 assembled = 0 active = 0 @@ -136,6 +147,8 @@ /obj/machinery/particle_accelerator/control_box/power_change() ..() if(stat & NOPOWER) + if(paired) + paired.unpair() active = 0 use_power = 0 else if(!stat && construction_state <= 3) diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index ae5cf652a07..bb3b34c5f2f 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -270,6 +270,7 @@ var/list/solars_list = list() var/trackrate = 600 // 300-900 seconds var/trackdir = 1 // 0 =CCW, 1=CW var/nexttime = 0 + paiallowed = 1 /obj/machinery/power/solar_control/New() @@ -360,6 +361,10 @@ var/list/solars_list = list() A.icon_state = "4" A.anchored = 1 qdel(src) + else if(istype(I, /obj/item/device/paicard)) + var/obj/item/device/paicard/C = I + if(C.pai && (C.pai.stat != DEAD) && C.pai.pairing) + C.pai.pair(src) else src.attack_hand(user) return @@ -443,6 +448,8 @@ var/list/solars_list = list() /obj/machinery/power/solar_control/proc/broken() + if(paired) + paired.unpair() stat |= BROKEN update_icon() diff --git a/icons/obj/computer.dmi b/icons/obj/computer.dmi index 9557a1472da..2b5896d9ce6 100644 Binary files a/icons/obj/computer.dmi and b/icons/obj/computer.dmi differ