diff --git a/code/defines/procs/captain_announce.dm b/code/defines/procs/captain_announce.dm
index 9b91705ea5..092d297a2d 100644
--- a/code/defines/procs/captain_announce.dm
+++ b/code/defines/procs/captain_announce.dm
@@ -1,5 +1,6 @@
-/proc/captain_announce(var/text)
- world << "
Priority Announcement
"
- world << "[html_encode(text)]"
- world << "
"
-
+/proc/captain_announce(message as text, title = "Priority Announcement", announcer = "")
+ world << "[html_encode(title)]
"
+ world << "[html_encode(message)]"
+ if(announcer)
+ world << " -[html_encode(announcer)]"
+ world << "
"
\ No newline at end of file
diff --git a/code/game/machinery/computer/ai_core.dm b/code/game/machinery/computer/ai_core.dm
index 0946e7943c..1c70db6d67 100644
--- a/code/game/machinery/computer/ai_core.dm
+++ b/code/game/machinery/computer/ai_core.dm
@@ -231,6 +231,7 @@ That prevents a few funky behaviors.
new /obj/structure/AIcore/deactivated(T.loc)
T.aiRestorePowerRoutine = 0
T.control_disabled = 1
+ T.aiRadio.disabledAi = 1
T.loc = C
C.AI = T
T.cancel_camera()
@@ -245,6 +246,7 @@ That prevents a few funky behaviors.
var/mob/living/silicon/ai/A = locate() in C//I love locate(). Best proc ever.
if(A)//If AI exists on the card. Else nothing since both are empty.
A.control_disabled = 0
+ A.aiRadio.disabledAi = 0
A.loc = T.loc//To replace the terminal.
C.icon_state = "aicard"
C.name = "inteliCard"
diff --git a/code/game/machinery/computer/aifixer.dm b/code/game/machinery/computer/aifixer.dm
index 1b6ff55887..fc636c879a 100644
--- a/code/game/machinery/computer/aifixer.dm
+++ b/code/game/machinery/computer/aifixer.dm
@@ -87,13 +87,14 @@
src.occupant.adjustToxLoss(-1)
src.occupant.adjustBruteLoss(-1)
src.occupant.updatehealth()
- if (src.occupant.health >= 0 && src.occupant.stat == 2)
- src.occupant.stat = 0
+ if (src.occupant.health >= 0 && src.occupant.stat == DEAD)
+ src.occupant.stat = CONSCIOUS
src.occupant.lying = 0
dead_mob_list -= src.occupant
living_mob_list += src.occupant
src.overlays -= image('icons/obj/computer.dmi', "ai-fixer-404")
src.overlays += image('icons/obj/computer.dmi', "ai-fixer-full")
+ src.occupant.add_ai_verbs()
src.updateUsrDialog()
sleep(10)
src.active = 0
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index ff0c13c2fb..758883dfff 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -1,4 +1,28 @@
+#define AI_CHECK_WIRELESS 1
+#define AI_CHECK_RADIO 2
+
var/list/ai_list = list()
+var/list/ai_verbs_default = list(
+ /mob/living/silicon/ai/proc/ai_announcement,
+ /mob/living/silicon/ai/proc/ai_call_shuttle,
+ // /mob/living/silicon/ai/proc/ai_recall_shuttle,
+ /mob/living/silicon/ai/proc/ai_camera_track,
+ /mob/living/silicon/ai/proc/ai_camera_list,
+ /mob/living/silicon/ai/proc/ai_goto_location,
+ /mob/living/silicon/ai/proc/ai_remove_location,
+ /mob/living/silicon/ai/proc/ai_hologram_change,
+ /mob/living/silicon/ai/proc/ai_network_change,
+ /mob/living/silicon/ai/proc/pick_icon,
+ /mob/living/silicon/ai/proc/ai_roster,
+ /mob/living/silicon/ai/proc/ai_statuschange,
+ /mob/living/silicon/ai/proc/ai_store_location,
+ /mob/living/silicon/ai/proc/checklaws,
+ /mob/living/silicon/ai/proc/control_integrated_radio,
+ /mob/living/silicon/ai/proc/core,
+ /mob/living/silicon/ai/proc/show_laws_verb,
+ /mob/living/silicon/ai/proc/toggle_acceleration,
+ /mob/living/silicon/ai/proc/toggle_camera_light
+)
//Not sure why this is necessary...
/proc/AutoUpdateAI(obj/subject)
@@ -53,19 +77,12 @@ var/list/ai_list = list()
var/datum/trackable/track = null
var/last_announcement = ""
-proc/add_ai_verbs(var/mob/M)
- M.verbs += /mob/living/silicon/ai/proc/ai_call_shuttle
- M.verbs += /mob/living/silicon/ai/proc/ai_camera_track
- M.verbs += /mob/living/silicon/ai/proc/ai_camera_list
- M.verbs += /mob/living/silicon/ai/proc/ai_goto_location
- M.verbs += /mob/living/silicon/ai/proc/ai_remove_location
- M.verbs += /mob/living/silicon/ai/proc/ai_hologram_change
- M.verbs += /mob/living/silicon/ai/proc/ai_network_change
- M.verbs += /mob/living/silicon/ai/proc/ai_roster
- M.verbs += /mob/living/silicon/ai/proc/ai_statuschange
- M.verbs += /mob/living/silicon/ai/proc/ai_store_location
- M.verbs += /mob/living/silicon/ai/proc/control_integrated_radio
- M.verbs += /mob/living/silicon/ai/proc/toggle_camera_light
+/mob/living/silicon/ai/proc/add_ai_verbs()
+ src.verbs += ai_verbs_default
+
+/mob/living/silicon/ai/proc/remove_ai_verbs()
+ src.verbs -= ai_verbs_default
+
/mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/device/mmi/B, var/safety = 0)
var/list/possibleNames = ai_names
@@ -95,8 +112,6 @@ proc/add_ai_verbs(var/mob/M)
else
laws = new base_law_type
- verbs += /mob/living/silicon/ai/proc/show_laws_verb
-
aiPDA = new/obj/item/device/pda/ai(src)
aiPDA.owner = name
aiPDA.ownjob = "AI"
@@ -193,7 +208,7 @@ proc/add_ai_verbs(var/mob/M)
if(powered_ai.anchored)
use_power = 2
-/mob/living/silicon/ai/verb/pick_icon()
+/mob/living/silicon/ai/proc/pick_icon()
set category = "AI Commands"
set name = "Set AI Core Display"
if(stat || aiRestorePowerRoutine)
@@ -288,20 +303,43 @@ proc/add_ai_verbs(var/mob/M)
set name = "Show Crew Manifest"
show_station_manifest()
+/mob/living/silicon/ai/var/message_cooldown = 0
+/mob/living/silicon/ai/proc/ai_announcement()
+ set category = "AI Commands"
+ set name = "Make Station Announcement"
+
+ if(check_unable(AI_CHECK_WIRELESS | AI_CHECK_RADIO))
+ return
+
+ if(message_cooldown)
+ src << "Please allow one minute to pass between announcements."
+ return
+ var/input = stripped_input(usr, "Please write a message to announce to the station crew.", "A.I. Announcement")
+ if(!input)
+ return
+
+ if(check_unable(AI_CHECK_WIRELESS | AI_CHECK_RADIO))
+ return
+
+ captain_announce(input, "A.I. Announcement", src.name)
+ log_say("[key_name(usr)] has made an AI announcement: [input]")
+ message_admins("[key_name_admin(usr)] has made an AI announcement.", 1)
+ message_cooldown = 1
+ spawn(600)//One minute cooldown
+ message_cooldown = 0
+
/mob/living/silicon/ai/proc/ai_call_shuttle()
set category = "AI Commands"
set name = "Call Emergency Shuttle"
- if(src.stat == 2)
- src << "You can't call the shuttle because you are dead!"
+
+ if(check_unable(AI_CHECK_WIRELESS))
return
- if(istype(usr,/mob/living/silicon/ai))
- var/mob/living/silicon/ai/AI = src
- if(AI.control_disabled)
- usr << "Wireless control is disabled!"
- return
var/confirm = alert("Are you sure you want to call the shuttle?", "Confirm Shuttle Call", "Yes", "No")
+ if(check_unable(AI_CHECK_WIRELESS))
+ return
+
if(confirm == "Yes")
call_shuttle_proc(src)
@@ -311,20 +349,19 @@ proc/add_ai_verbs(var/mob/M)
if(C)
C.post_status("shuttle")
- return
-
-/mob/living/silicon/ai/proc/ai_cancel_call()
+/mob/living/silicon/ai/proc/ai_recall_shuttle()
set category = "AI Commands"
- if(src.stat == 2)
- src << "You can't send the shuttle back because you are dead!"
+ set name = "Recall Emergency Shuttle"
+
+ if(check_unable(AI_CHECK_WIRELESS))
return
- if(istype(usr,/mob/living/silicon/ai))
- var/mob/living/silicon/ai/AI = src
- if(AI.control_disabled)
- src << "Wireless control is disabled!"
- return
- cancel_call_proc(src)
- return
+
+ var/confirm = alert("Are you sure you want to recall the shuttle?", "Confirm Shuttle Recall", "Yes", "No")
+ if(check_unable(AI_CHECK_WIRELESS))
+ return
+
+ if(confirm == "Yes")
+ cancel_call_proc(src)
/mob/living/silicon/ai/check_eye(var/mob/user as mob)
if (!current)
@@ -534,7 +571,7 @@ proc/add_ai_verbs(var/mob/M)
src.cameraFollow = null
- if (!C || stat == 2) //C.can_use())
+ if (!C || stat == DEAD) //C.can_use())
return 0
if(!src.eyeobj)
@@ -587,8 +624,7 @@ proc/add_ai_verbs(var/mob/M)
src.cameraFollow = null
var/cameralist[0]
- if(usr.stat == 2)
- usr << "You can't change your camera network because you are dead!"
+ if(check_unable())
return
var/mob/living/silicon/ai/U = usr
@@ -631,9 +667,9 @@ proc/add_ai_verbs(var/mob/M)
set category = "AI Commands"
set name = "AI Status"
- if(usr.stat == 2)
- usr <<"You cannot change your emotional status because you are dead!"
+ if(check_unable(AI_CHECK_WIRELESS))
return
+
var/list/ai_emotions = list("Very Happy", "Happy", "Neutral", "Unsure", "Confused", "Surprised", "Sad", "Upset", "Angry", "Awesome", "BSOD", "Blank", "Problems?", "Facepalm", "Friend Computer")
var/emote = input("Please, select a status!", "AI Status", null, null) in ai_emotions
for (var/obj/machinery/M in machines) //change status
@@ -656,6 +692,9 @@ proc/add_ai_verbs(var/mob/M)
set desc = "Change the default hologram available to AI to something else."
set category = "AI Commands"
+ if(check_unable())
+ return
+
var/input
if(alert("Would you like to select a hologram based on a crew member or switch to unique avatar?",,"Crew Member","Unique")=="Crew Member")
@@ -704,6 +743,9 @@ proc/add_ai_verbs(var/mob/M)
set desc = "Toggles the light on the camera the AI is looking through."
set category = "AI Commands"
+ if(check_unable())
+ return
+
camera_light_on = !camera_light_on
src << "Camera lights [camera_light_on ? "activated" : "deactivated"]."
if(!camera_light_on)
@@ -766,6 +808,25 @@ proc/add_ai_verbs(var/mob/M)
set desc = "Allows you to change settings of your radio."
set category = "AI Commands"
+ if(check_unable(AI_CHECK_RADIO))
+ return
+
src << "Accessing Subspace Transceiver control..."
if (src.aiRadio)
src.aiRadio.interact(src)
+
+/mob/living/silicon/ai/proc/check_unable(var/flags = 0)
+ if(stat == DEAD)
+ usr << "\red You are dead!"
+ return 1
+
+ if((flags & AI_CHECK_WIRELESS) && src.control_disabled)
+ usr << "\red Wireless control is disabled!"
+ return 1
+ if((flags & AI_CHECK_RADIO) && src.aiRadio.disabledAi)
+ src << "\red System Error - Transceiver Disabled!"
+ return 1
+ return 0
+
+#undef AI_CHECK_WIRELESS
+#undef AI_CHECK_RADIO
diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm
index c954185846..f2cd262f4c 100644
--- a/code/modules/mob/living/silicon/ai/death.dm
+++ b/code/modules/mob/living/silicon/ai/death.dm
@@ -11,6 +11,7 @@
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_LEVEL_TWO
+ remove_ai_verbs(src)
var/callshuttle = 0
diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm
index f89a171e0c..a0382f2025 100644
--- a/code/modules/mob/living/silicon/ai/freelook/eye.dm
+++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm
@@ -119,7 +119,7 @@
// Return to the Core.
-/mob/living/silicon/ai/verb/core()
+/mob/living/silicon/ai/proc/core()
set category = "AI Commands"
set name = "AI Core"
@@ -145,7 +145,7 @@
for(var/datum/camerachunk/c in eyeobj.visibleCameraChunks)
c.remove(eyeobj)
-/mob/living/silicon/ai/verb/toggle_acceleration()
+/mob/living/silicon/ai/proc/toggle_acceleration()
set category = "AI Commands"
set name = "Toggle Camera Acceleration"
diff --git a/code/modules/mob/living/silicon/ai/laws.dm b/code/modules/mob/living/silicon/ai/laws.dm
index 9e104ac100..e167c42f06 100755
--- a/code/modules/mob/living/silicon/ai/laws.dm
+++ b/code/modules/mob/living/silicon/ai/laws.dm
@@ -1,4 +1,3 @@
-
/mob/living/silicon/ai/proc/show_laws_verb()
set category = "AI Commands"
set name = "Show Laws"
@@ -107,7 +106,7 @@
sleep(10)
number++
-/mob/living/silicon/ai/verb/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite
+/mob/living/silicon/ai/proc/checklaws() //Gives you a link-driven interface for deciding what laws the statelaws() proc will share with the crew. --NeoFite
set category = "AI Commands"
set name = "State Laws"
diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm
index d0c6c767fc..3a0c1a461c 100644
--- a/code/modules/mob/living/silicon/ai/life.dm
+++ b/code/modules/mob/living/silicon/ai/life.dm
@@ -182,3 +182,7 @@
health = 100 - getOxyLoss() - getToxLoss() - getBruteLoss()
else
health = 100 - getOxyLoss() - getToxLoss() - getFireLoss() - getBruteLoss()
+
+/mob/living/silicon/ai/rejuvenate()
+ ..()
+ add_ai_verbs(src)
\ No newline at end of file
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index 7a6d7140d1..2307d00bcb 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -120,7 +120,7 @@
O.show_laws()
O << "These laws may be changed by other players, or by you being the traitor."
- add_ai_verbs(O)
+ O.add_ai_verbs()
O.job = "AI"
O.rename_self("ai",1)