Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DNM][WIP] I am afraid I can't do that Dave. || AI Interaction Rework #8659

Closed
wants to merge 13 commits into from
6 changes: 6 additions & 0 deletions code/__DEFINES/ai.dm
@@ -0,0 +1,6 @@
//Bitflags for AI relay stuff
#define POWER_MANIPULATION (1<<0)
#define ENVIROMENTAL_CONTROL (1<<1)
#define DOOR_CONTROL (1<<2)
#define TELECOMMS_CONTROL (1<<3)
#define MACHINE_INTERACTION (1<<4)
29 changes: 28 additions & 1 deletion code/_onclick/ai.dm
Expand Up @@ -133,14 +133,20 @@
/obj/machinery/door/airlock/AICtrlClick() // Bolts doors
if(obj_flags & EMAGGED)
return

if(!ai_can_use(DOOR_CONTROL, usr))
to_chat(usr, "<span class='warning'>No Door Control relay detected. Unable to interface with airlock.</span>")
return
toggle_bolt(usr)
add_hiddenprint(usr)

/obj/machinery/door/airlock/AIAltClick() // Eletrifies doors.
if(obj_flags & EMAGGED)
return

if(!ai_can_use(DOOR_CONTROL, usr))
to_chat(usr, "<span class='warning'>No Door Control relay detected. Unable to interface with airlock.</span>")
return

if(!secondsElectrified)
shock_perm(usr)
else
Expand All @@ -150,34 +156,55 @@
if(obj_flags & EMAGGED)
return

if(!ai_can_use(DOOR_CONTROL, usr))
to_chat(usr, "<span class='warning'>No Door Control relay detected. Unable to interface with airlock.</span>")
return

user_toggle_open(usr)
add_hiddenprint(usr)

/obj/machinery/door/airlock/AICtrlShiftClick() // Sets/Unsets Emergency Access Override
if(obj_flags & EMAGGED)
return

if(!ai_can_use(DOOR_CONTROL, usr))
to_chat(usr, "<span class='warning'>No Door Control relay detected. Unable to interface with airlock.</span>")
return

toggle_emergency(usr)
add_hiddenprint(usr)

/* APC */
/obj/machinery/power/apc/AICtrlClick() // turns off/on APCs.
if(!ai_can_use(POWER_MANIPULATION, usr))
to_chat(usr, "<span class='warning'>No Power Manipulation relay detected. Unable to interface with APC.</span>")
return

if(can_use(usr, 1))
toggle_breaker(usr)

/* AI Turrets */
/obj/machinery/turretid/AIAltClick() //toggles lethal on turrets
if(!ai_can_use(MACHINE_INTERACTION, usr))
to_chat(usr, "<span class='warning'>No Machine Interaction relay detected. Unable to interface with turret.</span>")
return
if(ailock)
return
toggle_lethal(usr)

/obj/machinery/turretid/AICtrlClick() //turns off/on Turrets
if(!ai_can_use(MACHINE_INTERACTION, usr))
to_chat(usr, "<span class='warning'>No Machine Interaction relay detected. Unable to interface with turret.</span>")
return
if(ailock)
return
toggle_on(usr)

/* Holopads */
/obj/machinery/holopad/AIAltClick(mob/living/silicon/ai/user)
if(!ai_can_use(MACHINE_INTERACTION, user))
to_chat(user, "<span class='warning'>No Machine Interaction relay detected. Unable to interface with holopad.</span>")
return
hangup_all_calls()
add_hiddenprint(usr)

Expand Down
3 changes: 3 additions & 0 deletions code/game/machinery/_machinery.dm
Expand Up @@ -322,6 +322,9 @@ Class Procs:
if(iscyborg(user))// For some reason attack_robot doesn't work
return attack_robot(user)
else
if(!ai_can_use(MACHINE_INTERACTION, user))
to_chat(user, "<span class='warning'>No Machine Interaction relay detected. Unable to interface with machine.</span>")
return
return _try_interact(user)

/obj/machinery/_try_interact(mob/user)
Expand Down
176 changes: 176 additions & 0 deletions code/game/machinery/ai_relay.dm
@@ -0,0 +1,176 @@
GLOBAL_LIST_EMPTY(ai_relays)

#define AI_RELAY_HACK_TIME 600
#define FLIP_DELAY 150

/obj/machinery/ai_relay
name = "processing relay"
desc = "A mighty piece of hardware used to process massive amounts of data. It allows the AI to interface with various machines on the station."

icon = 'icons/obj/machines/telecomms.dmi'
icon_state = "hub"

critical_machine = TRUE
density = TRUE

use_power = IDLE_POWER_USE
idle_power_usage = 500
active_power_usage = 5000 //10x

var/on = FALSE

var/list/linked_ais = list()
TheGamerdk marked this conversation as resolved.
Show resolved Hide resolved

var/list/hacked_ais = list()

var/module_door_open = FALSE
var/obj/item/ai_relay_module/inserted_module

var/last_flipped

circuit = /obj/item/circuitboard/machine/ai_relay

/obj/machinery/ai_relay/Initialize()
GLOB.ai_relays += src
name += " ([num2hex(rand(1,65535), -1)])"
TheGamerdk marked this conversation as resolved.
Show resolved Hide resolved
. = ..()

/obj/machinery/ai_relay/Destroy()
GLOB.ai_relays -= src
reset_connected_ais()
. = ..()

/obj/machinery/ai_relay/attack_hand(mob/user)
. = ..()
if(stat & NOPOWER)
to_chat(user, "<span class='warning'>Nothing happens...</span>")
return

if(panel_open)
to_chat(user, "<span class='warning'>You need to close the maintenance hatch first!</span>")
return

if(module_door_open && inserted_module)
inserted_module.forceMove(get_turf(src))
user.visible_message("[user] removes [inserted_module].", "<span class='notice'>You remove [inserted_module].</span>")
inserted_module = null
return

if(on)
if(last_flipped > world.time)
to_chat(user, "<span class='warning'>The breaker won't budge! The relay has locked it for [(last_flipped - world.time) / 10] seconds!</span>")
return
last_flipped = world.time + FLIP_DELAY
on = FALSE
user.visible_message("[user] switches [src] off.", "<span class='warning'>You flip the breaker to the OFF position.</span>")
use_power = IDLE_POWER_USE
message_ais("<span class='warning'>[src] has been turned manually off!</span>")
update_icon()
else
if(last_flipped > world.time)
to_chat(user, "<span class='warning'>The breaker won't budge! The relay has locked it for [(last_flipped - world.time) / 10] seconds!</span>")
return
last_flipped = world.time + FLIP_DELAY
on = TRUE
user.visible_message("[user] switches [src] on.", "<span class='warning'>You flip the breaker to the ON position.</span>")
use_power = ACTIVE_POWER_USE
message_ais("<span class='notice'>[src] has been turned manually on.</span>")
update_icon()


/obj/machinery/ai_relay/process()
if(stat & (NOPOWER|BROKEN))
visible_message("[src] switches off.")
update_icon()
on = FALSE
use_power = IDLE_POWER_USE
return FALSE
TheGamerdk marked this conversation as resolved.
Show resolved Hide resolved
return TRUE

/obj/machinery/ai_relay/attack_ai(mob/user)
if(get_area(src) == get_area(user))
to_chat(user, "<span class='warning'>If you wish to connect this relay, please use the Refresh Relays button.</span>")
return

var/mob/living/silicon/ai/hacker = user
if(!istype(hacker))
return
if(hacker in linked_ais)
to_chat(user, "<span class='warning'>We already have control of this relay!</span>")
return
if(hacker.relay_hack)
return

hacker.relay_hack = addtimer(CALLBACK(hacker, /mob/living/silicon/ai/.proc/relay_hacked, src), 300, TIMER_STOPPABLE)
var/obj/screen/alert/hackingapc/A
A = hacker.throw_alert("hacking_relay", /obj/screen/alert/hackingapc)
A.target = src

for(var/M in linked_ais)
var/mob/living/silicon/ai/AI = M
if(!istype(AI))
return
to_chat(AI, "<span class='userdanger'>Hostile intrusion detected on [src]! Signal origin tracked to [get_area(hacker)]</span>")


/obj/machinery/ai_relay/attackby(obj/item/O, mob/user, params)
if(default_deconstruction_screwdriver(user, "[icon_state]", "[icon_state]", O))
return
else if(O.tool_behaviour == TOOL_CROWBAR)
if(module_door_open)
module_door_open = FALSE
user.visible_message("[user] has lifted the panel on [src] back in.", "<span class='notice'>You lift the panel back in.</span>")
else
module_door_open = TRUE
user.visible_message("[user] has lifted the panel off of [src].", "<span class='notice'>You lift the panel off.</span>")
O.play_tool_sound(src)
update_icon()
else if(istype(O, /obj/item/ai_relay_module))
if(!module_door_open)
to_chat(user, "<span class='caution'>The module hatch isn't open!</span>")
return
if(inserted_module)
to_chat(user, "<span class='caution'>There's already a module inserted!</span>")
return
inserted_module = O
O.forceMove(src)
else if(istype(O, /obj/item/multitool))
if(stat & (NOPOWER|BROKEN))
to_chat(user, "<span class='caution'>The relay is offline!</span>")
return
reset_connected_ais()
else
return ..()

/obj/machinery/ai_relay/proc/return_module_type()
if(stat & (NOPOWER|BROKEN))
return FALSE
if(!inserted_module)
return FALSE
if(!on)
return FALSE
return inserted_module.enabling_tasks

/obj/machinery/ai_relay/proc/reset_connected_ais()
for(var/A in linked_ais + hacked_ais)
var/mob/living/silicon/ai/AI = A
if(!istype(AI))
continue
AI.relays -= src
to_chat(AI, "<span class='userdanger'>You have been disconnected from [src]!</span>")


/obj/machinery/ai_relay/proc/message_ais(msg, include_hacked = TRUE)
var/list/ais = linked_ais
if(include_hacked)
ais += hacked_ais

for(var/A in ais)
var/mob/living/silicon/ai/AI = A
if(!istype(AI))
continue
to_chat(AI, msg)

/obj/machinery/ai_relay/update_icon()


3 changes: 3 additions & 0 deletions code/game/machinery/announcement_system.dm
Expand Up @@ -153,6 +153,9 @@ GLOBAL_LIST_EMPTY(announcement_systems)
. = attack_ai(user)

/obj/machinery/announcement_system/attack_ai(mob/user)
if(!ai_can_use(MACHINE_INTERACTION, user))
to_chat(user, "<span class='warning'>No Machine Interaction relay detected. Unable to interface with machine.</span>")
return
if(!user.canUseTopic(src, !issilicon(user)))
return
if(stat & BROKEN)
Expand Down
3 changes: 3 additions & 0 deletions code/game/machinery/buttons.dm
Expand Up @@ -115,6 +115,9 @@
obj_flags |= EMAGGED

/obj/machinery/button/attack_ai(mob/user)
if(!ai_can_use(MACHINE_INTERACTION, user))
to_chat(user, "<span class='warning'>No Machine Interaction relay detected. Unable to interface with button.</span>")
return
if(!panel_open)
return attack_hand(user)

Expand Down
3 changes: 3 additions & 0 deletions code/game/machinery/camera/tracking.dm
Expand Up @@ -132,6 +132,9 @@
return TRUE

/obj/machinery/camera/attack_ai(mob/living/silicon/ai/user)
if(!ai_can_use(MACHINE_INTERACTION, user))
to_chat(user, "<span class='warning'>No Machine Interaction relay detected. Unable to interface with airlock.</span>")
return
if (!istype(user))
return
if (!can_use())
Expand Down
3 changes: 3 additions & 0 deletions code/game/machinery/dish_drive.dm
Expand Up @@ -96,6 +96,9 @@
step_towards(I, src)

/obj/machinery/dish_drive/attack_ai(mob/living/user)
if(!ai_can_use(MACHINE_INTERACTION, user))
to_chat(user, "<span class='warning'>No Machine Interaction relay detected. Unable to interface with airlock.</span>")
return
if(stat)
return
to_chat(user, "<span class='notice'>You send a disposal transmission signal to [src].</span>")
Expand Down
4 changes: 4 additions & 0 deletions code/game/machinery/doors/airlock.dm
Expand Up @@ -732,6 +732,10 @@
. += "<span class='notice'>Ctrl-Shift-click [src] to [ emergency ? "disable" : "enable"] emergency access.</span>"

/obj/machinery/door/airlock/attack_ai(mob/user)
if(!ai_can_use(DOOR_CONTROL, user))
to_chat(user, "<span class='warning'>No Door Control relay detected. Unable to interface with airlock.</span>")
return

if(!canAIControl(user))
if(canAIHack())
hack(user)
Expand Down
5 changes: 4 additions & 1 deletion code/game/machinery/doors/firedoor.dm
Expand Up @@ -177,6 +177,9 @@
return !is_holding_pressure()

/obj/machinery/door/firedoor/attack_ai(mob/user)
if(!ai_can_use(ENVIROMENTAL_CONTROL, user))
to_chat(user, "<span class='warning'>No Enviromental Control relay detected. Unable to interface with firelock.</span>")
return
add_fingerprint(user)
if(welded || operating || stat & NOPOWER)
return TRUE
Expand Down Expand Up @@ -325,7 +328,7 @@
to_chat(M, "<span class='notice'>You pull [M.pulling] through [src] right as it closes</span>")
M.pulling.forceMove(T1)
M.start_pulling(M2)

for(var/mob/living/M in T2)
if(M.stat == CONSCIOUS && M.pulling && M.pulling.loc == T1 && !M.pulling.anchored && M.pulling.move_resist <= M.move_force)
var/mob/living/M2 = M.pulling
Expand Down
3 changes: 3 additions & 0 deletions code/game/machinery/firealarm.dm
Expand Up @@ -148,6 +148,9 @@
alarm(user)

/obj/machinery/firealarm/attack_ai(mob/user)
if(!ai_can_use(ENVIROMENTAL_CONTROL, user))
to_chat(user, "<span class='warning'>No Enviromental Control relay detected. Unable to interface with fire alarm.</span>")
TheGamerdk marked this conversation as resolved.
Show resolved Hide resolved
return
return attack_hand(user)

/obj/machinery/firealarm/attack_robot(mob/user)
Expand Down
3 changes: 3 additions & 0 deletions code/game/machinery/flasher.dm
Expand Up @@ -84,6 +84,9 @@

//Let the AI trigger them directly.
/obj/machinery/flasher/attack_ai()
if(!ai_can_use(MACHINE_INTERACTION, usr))
to_chat(usr, "<span class='warning'>No Machine Interaction relay detected. Unable to interface with airlock.</span>")
return
if (anchored)
return flash()

Expand Down
3 changes: 3 additions & 0 deletions code/game/machinery/hologram.dm
Expand Up @@ -329,6 +329,9 @@ Possible to do for anyone motivated enough:

//do not allow AIs to answer calls or people will use it to meta the AI sattelite
/obj/machinery/holopad/attack_ai(mob/living/silicon/ai/user)
if(!ai_can_use(MACHINE_INTERACTION, user))
to_chat(user, "<span class='warning'>No Machine Interaction relay detected. Unable to interface with holopad.</span>")
return
if (!istype(user))
return
if (!on_network)
Expand Down
3 changes: 3 additions & 0 deletions code/game/machinery/igniter.dm
Expand Up @@ -107,6 +107,9 @@
return ..()

/obj/machinery/sparker/attack_ai()
if(!ai_can_use(MACHINE_INTERACTION, usr))
to_chat(usr, "<span class='warning'>No Machine Interaction relay detected. Unable to interface with airlock.</span>")
return
if (anchored)
return src.ignite()
else
Expand Down
4 changes: 4 additions & 0 deletions code/game/machinery/lightswitch.dm
Expand Up @@ -38,6 +38,10 @@
. += "<span class='danger'>You hear a faint hum coming from the switch.</span>"

/obj/machinery/light_switch/interact(mob/user)
if(!ai_can_use(ENVIROMENTAL_CONTROL, user))
to_chat(user, "<span class='warning'>No Enviromental Control relay detected. Unable to interface with light switch.</span>")
return

if(obj_flags & EMAGGED)
shock(user)
. = ..()
Expand Down