diff --git a/code/__DEFINES/mob_defines.dm b/code/__DEFINES/mob_defines.dm
index bccec9548a2..d3eb93078ea 100644
--- a/code/__DEFINES/mob_defines.dm
+++ b/code/__DEFINES/mob_defines.dm
@@ -259,7 +259,7 @@
#define ismorph(A) (istype((A), /mob/living/simple_animal/hostile/morph))
#define issilicon(A) (istype((A), /mob/living/silicon))
-#define isAI(A) (istype((A), /mob/living/silicon/ai))
+#define is_ai(A) (istype((A), /mob/living/silicon/ai))
#define isrobot(A) (istype((A), /mob/living/silicon/robot))
#define isdrone(A) (istype((A), /mob/living/silicon/robot/drone))
#define ispAI(A) (istype((A), /mob/living/silicon/pai))
@@ -273,7 +273,7 @@
#define ispathanimal(A) (ispath(A, /mob/living/simple_animal))
#define iscameramob(A) (istype((A), /mob/camera))
-#define isAIEye(A) (istype((A), /mob/camera/ai_eye))
+#define is_ai_eye(A) (istype((A), /mob/camera/eye))
#define isovermind(A) (istype((A), /mob/camera/blob))
#define isSpirit(A) (istype((A), /mob/spirit))
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index 487c5eb39fe..7a339ec8283 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -879,7 +879,7 @@ Returns 1 if the chain up to the area contains the given typepath
continue
O.loc.Exited(O)
- O.setLoc(X)
+ O.set_loc(X)
O.loc.Entered(O)
for(var/mob/M in T)
diff --git a/code/_onclick/ai_onclick.dm b/code/_onclick/ai_onclick.dm
index 3801ae81dd7..a9d63f51c6b 100644
--- a/code/_onclick/ai_onclick.dm
+++ b/code/_onclick/ai_onclick.dm
@@ -102,20 +102,20 @@
add_attack_logs(src, src, "[key_name_admin(src)] might be running a modified client! (failed can_see on AI click of [A]([ADMIN_COORDJMP(pixel_turf)]))", ATKLOG_ALL)
var/message = "[key_name(src)] might be running a modified client! (failed can_see on AI click of [A]([COORD(pixel_turf)]))"
log_admin(message)
- GLOB.discord_manager.send2discord_simple_noadmins("**\[Warning]** [key_name(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([COORD(pixel_turf)]))")
+ GLOB.discord_manager.send2discord_simple_noadmins("**\[Warning]** [key_name(src)] might be running a modified client! (failed check_turf_vis on AI click of [A]([COORD(pixel_turf)]))")
return FALSE
var/turf_visible
if(pixel_turf)
- turf_visible = GLOB.cameranet.checkTurfVis(pixel_turf)
+ turf_visible = GLOB.cameranet.check_turf_vis(pixel_turf)
if(!turf_visible)
if((istype(loc, /obj/item/aicard) || ismecha(loc)) && (pixel_turf in range(client.view, loc)))
turf_visible = TRUE
else
if(pixel_turf.obscured)
- log_admin("[key_name_admin(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([COORD(pixel_turf)])")
- add_attack_logs(src, src, "[key_name_admin(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([ADMIN_COORDJMP(pixel_turf)]))", ATKLOG_ALL)
- GLOB.discord_manager.send2discord_simple_noadmins("**\[Warning]** [key_name(src)] might be running a modified client! (failed checkTurfVis on AI click of [A]([COORD(pixel_turf)]))")
+ log_admin("[key_name_admin(src)] might be running a modified client! (failed check_turf_vis on AI click of [A]([COORD(pixel_turf)])")
+ add_attack_logs(src, src, "[key_name_admin(src)] might be running a modified client! (failed check_turf_vis on AI click of [A]([ADMIN_COORDJMP(pixel_turf)]))", ATKLOG_ALL)
+ GLOB.discord_manager.send2discord_simple_noadmins("**\[Warning]** [key_name(src)] might be running a modified client! (failed check_turf_vis on AI click of [A]([COORD(pixel_turf)]))")
return FALSE
return TRUE
@@ -184,7 +184,7 @@
return
/mob/living/silicon/ai/TurfAdjacent(turf/T)
- return (GLOB.cameranet && GLOB.cameranet.checkTurfVis(T))
+ return (GLOB.cameranet && GLOB.cameranet.check_turf_vis(T))
// APC
diff --git a/code/_onclick/hud/ai_hud.dm b/code/_onclick/hud/ai_hud.dm
index 9d2fba72029..f25d9356c0a 100644
--- a/code/_onclick/hud/ai_hud.dm
+++ b/code/_onclick/hud/ai_hud.dm
@@ -105,7 +105,7 @@
/atom/movable/screen/ai/state_laws/Click()
if(..())
return
- if(isAI(usr))
+ if(is_ai(usr))
var/mob/living/silicon/ai/AI = usr
AI.subsystem_law_manager()
@@ -156,7 +156,7 @@
/atom/movable/screen/ai/sensors/Click()
if(..())
return
- if(isAI(usr))
+ if(is_ai(usr))
var/mob/living/silicon/ai/AI = usr
AI.sensor_mode()
else if(isrobot(usr))
diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
index 5fbf8c8ef26..f1823e4b4b8 100644
--- a/code/_onclick/hud/alert.dm
+++ b/code/_onclick/hud/alert.dm
@@ -514,7 +514,7 @@ so as to remain in compliance with the most up-to-date laws."
var/mob/living/silicon/ai/AI = usr
var/turf/T = get_turf(target)
if(T)
- AI.eyeobj.setLoc(T)
+ AI.eyeobj.set_loc(T)
//MECHS
/atom/movable/screen/alert/low_mech_integrity
diff --git a/code/controllers/subsystem/SSshuttles.dm b/code/controllers/subsystem/SSshuttles.dm
index 1ccc4e5be71..2065c39026f 100644
--- a/code/controllers/subsystem/SSshuttles.dm
+++ b/code/controllers/subsystem/SSshuttles.dm
@@ -173,7 +173,7 @@ SUBSYSTEM_DEF(shuttle)
var/callShuttle = 1
for(var/thing in GLOB.shuttle_caller_list)
- if(isAI(thing))
+ if(is_ai(thing))
var/mob/living/silicon/ai/AI = thing
if(AI.stat || !AI.client)
continue
diff --git a/code/controllers/subsystem/tickets/SStickets.dm b/code/controllers/subsystem/tickets/SStickets.dm
index 269a53fcc1b..c7c77d18f48 100644
--- a/code/controllers/subsystem/tickets/SStickets.dm
+++ b/code/controllers/subsystem/tickets/SStickets.dm
@@ -161,7 +161,7 @@ SUBSYSTEM_DEF(tickets)
if(M)
L += "([ADMIN_QUE(M,"?")]) ([ADMIN_PP(M,"PP")]) ([ADMIN_VV(M,"VV")]) ([ADMIN_TP(M,"TP")]) ([ADMIN_SM(M,"SM")]) ([admin_jump_link(M)])"
L += "(TICKET) "
- L += "[isAI(M) ? "(CL)" : ""] (TAKE) "
+ L += "[is_ai(M) ? "(CL)" : ""] (TAKE) "
L += "(RESOLVE) (AUTO) "
L += "(CONVERT) : [one_line ? " " : "
"][msg]"
return L.Join()
diff --git a/code/datums/diseases/magnitis.dm b/code/datums/diseases/magnitis.dm
index 10095d0ad13..ddb6782f6db 100644
--- a/code/datums/diseases/magnitis.dm
+++ b/code/datums/diseases/magnitis.dm
@@ -22,7 +22,7 @@
if(!M.anchored && (M.flags & CONDUCT))
step_towards(M,affected_mob)
for(var/mob/living/silicon/S in orange(2,affected_mob))
- if(isAI(S)) continue
+ if(is_ai(S)) continue
step_towards(S,affected_mob)
if(3)
if(prob(2))
@@ -37,7 +37,7 @@
for(i=0,iYou haven't set location [location_number] yet!")
return
- AI.eyeobj.setLoc(AI.stored_locations[location_number])
+ AI.eyeobj.set_loc(AI.stored_locations[location_number])
/datum/keybinding/ai/to_location/one
name = "Jump to Location One"
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index b84e06b7b4e..b23129559d8 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -1509,7 +1509,7 @@
message_admins("[key_name_admin(usr)] has un-emagged [key_name_admin(current)]")
if("unemagcyborgs")
- if(!isAI(current))
+ if(!is_ai(current))
return
var/mob/living/silicon/ai/ai = current
for(var/mob/living/silicon/robot/R in ai.connected_robots)
diff --git a/code/datums/station_traits/positive_traits.dm b/code/datums/station_traits/positive_traits.dm
index a545c1504e5..b4f5420d6ec 100644
--- a/code/datums/station_traits/positive_traits.dm
+++ b/code/datums/station_traits/positive_traits.dm
@@ -213,7 +213,7 @@
var/cybernetic_type = job_to_cybernetic[job.type]
if(!cybernetic_type)
- if(isAI(spawned))
+ if(is_ai(spawned))
var/mob/living/silicon/ai/ai = spawned
ai.eyeobj.relay_speech = TRUE //surveillance upgrade. the ai gets cybernetics too.
return
diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm
index 13e3133e7d9..2c102af007a 100644
--- a/code/game/atoms_movable.dm
+++ b/code/game/atoms_movable.dm
@@ -198,9 +198,9 @@
return FALSE
return TRUE
-// Used in shuttle movement and AI eye stuff.
-// Primarily used to notify objects being moved by a shuttle/bluespace fuckup.
-/atom/movable/proc/setLoc(T, teleported=0)
+/// Used in shuttle movement and camera eye stuff.
+/// Primarily used to notify objects being moved by a shuttle/bluespace fuckup.
+/atom/movable/proc/set_loc(T, teleported=0)
var/old_loc = loc
loc = T
Moved(old_loc, get_dir(old_loc, loc))
diff --git a/code/game/data_huds.dm b/code/game/data_huds.dm
index da9bc720a4f..83704a83585 100644
--- a/code/game/data_huds.dm
+++ b/code/game/data_huds.dm
@@ -534,7 +534,7 @@
else if(isrobot(commenter))
var/mob/living/silicon/robot/U = commenter
commenter_display = "[U.name] ([U.modtype] [U.braintype])"
- else if(isAI(commenter))
+ else if(is_ai(commenter))
var/mob/living/silicon/ai/U = commenter
commenter_display = "[U.name] (artificial intelligence)"
comment_text = "Made by [commenter_display] on [GLOB.current_date_string] [station_time_timestamp()]:
[comment_text]"
diff --git a/code/game/gamemodes/autotraitor/autotraitor.dm b/code/game/gamemodes/autotraitor/autotraitor.dm
index 9c510fc5a74..dbcf5e38f9a 100644
--- a/code/game/gamemodes/autotraitor/autotraitor.dm
+++ b/code/game/gamemodes/autotraitor/autotraitor.dm
@@ -72,7 +72,7 @@
if(player.mind.has_antag_datum(/datum/antagonist/traitor))
traitor_count += 1
continue
- if(ishuman(player) || isAI(player))
+ if(ishuman(player) || is_ai(player))
if((ROLE_TRAITOR in player.client.prefs.be_special) && !player.client.skip_antag && !jobban_isbanned(player, ROLE_TRAITOR) && !jobban_isbanned(player, ROLE_SYNDICATE))
possible_traitors += player.mind
for(var/datum/mind/player in possible_traitors)
diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm
index 90ba39865b7..5aff5df2a95 100644
--- a/code/game/gamemodes/malfunction/Malf_Modules.dm
+++ b/code/game/gamemodes/malfunction/Malf_Modules.dm
@@ -126,7 +126,7 @@
/datum/module_picker/Topic(href, href_list)
..()
- if(!isAI(usr))
+ if(!is_ai(usr))
return
var/mob/living/silicon/ai/A = usr
@@ -573,8 +573,8 @@
var/turf/T = turfs[n]
if(!isfloorturf(T))
success = FALSE
- var/datum/camerachunk/C = GLOB.cameranet.getCameraChunk(T.x, T.y, T.z)
- if(!C.visibleTurfs[T])
+ var/datum/camerachunk/C = GLOB.cameranet.get_camera_chunk(T.x, T.y, T.z)
+ if(!C.visible_turfs[T])
alert_msg = "You don't have camera vision of this location!"
success = FALSE
for(var/atom/movable/AM in T.contents)
@@ -673,12 +673,12 @@
I.loc = deploylocation
client.images += I
I.icon_state = "redOverlay"
- var/datum/camerachunk/C = GLOB.cameranet.getCameraChunk(deploylocation.x, deploylocation.y, deploylocation.z)
+ var/datum/camerachunk/C = GLOB.cameranet.get_camera_chunk(deploylocation.x, deploylocation.y, deploylocation.z)
if(!istype(deploylocation))
to_chat(src, "There isn't enough room! Make sure you are placing the machine in a clear area and on a floor.")
return FALSE
- if(!C.visibleTurfs[deploylocation])
+ if(!C.visible_turfs[deploylocation])
to_chat(src, "You don't have camera vision of this location!")
addtimer(CALLBACK(src, PROC_REF(remove_transformer_image), client, I, deploylocation), 3 SECONDS)
return FALSE
diff --git a/code/game/gamemodes/miniantags/abduction/machinery/abductor_camera.dm b/code/game/gamemodes/miniantags/abduction/machinery/abductor_camera.dm
index df5767cf2a9..b8d28d1161a 100644
--- a/code/game/gamemodes/miniantags/abduction/machinery/abductor_camera.dm
+++ b/code/game/gamemodes/miniantags/abduction/machinery/abductor_camera.dm
@@ -23,7 +23,8 @@
return ..()
/obj/machinery/computer/camera_advanced/abductor/CreateEye()
- ..()
+ eyeobj = new /mob/camera/eye/abductor(loc, name, src, current_user)
+ give_eye_control(current_user)
eyeobj.visible_icon = 1
eyeobj.icon = 'icons/obj/abductor.dmi'
eyeobj.icon_state = "camera_target"
@@ -74,10 +75,10 @@
if(!target || !iscarbon(owner))
return
var/mob/living/carbon/human/C = owner
- var/mob/camera/ai_eye/remote/remote_eye = C.remote_control
+ var/mob/camera/eye/abductor/remote_eye = C.remote_control
var/obj/machinery/abductor/pad/P = target
- if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
+ if(GLOB.cameranet.check_turf_vis(remote_eye.loc))
P.PadToLoc(remote_eye.loc)
/datum/action/innate/teleport_out
@@ -101,10 +102,10 @@
if(!target || !iscarbon(owner))
return
var/mob/living/carbon/human/C = owner
- var/mob/camera/ai_eye/remote/remote_eye = C.remote_control
+ var/mob/camera/eye/abductor/remote_eye = C.remote_control
var/obj/machinery/abductor/pad/P = target
- if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
+ if(GLOB.cameranet.check_turf_vis(remote_eye.loc))
P.MobToLoc(remote_eye.loc,C)
/datum/action/innate/vest_mode_swap
@@ -137,7 +138,7 @@
return
var/mob/living/carbon/human/C = owner
- var/mob/camera/ai_eye/remote/remote_eye = C.remote_control
+ var/mob/camera/eye/abductor/remote_eye = C.remote_control
var/obj/machinery/abductor/console/console = target
console.SetDroppoint(remote_eye.loc,owner)
diff --git a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm
index 323943bd78d..99be8d840c2 100644
--- a/code/game/gamemodes/nuclear/nuclear.dm
+++ b/code/game/gamemodes/nuclear/nuclear.dm
@@ -501,7 +501,7 @@
for(var/mob in GLOB.mob_living_list)
var/mob/living/C = mob
- if(ishuman(C) || isAI(C) || isrobot(C))
+ if(ishuman(C) || is_ai(C) || isrobot(C))
if(C.stat == DEAD)
continue
if(!C.client)
diff --git a/code/game/gamemodes/scoreboard.dm b/code/game/gamemodes/scoreboard.dm
index ad5d6da9479..a38ba8eeffc 100644
--- a/code/game/gamemodes/scoreboard.dm
+++ b/code/game/gamemodes/scoreboard.dm
@@ -135,7 +135,7 @@ GLOBAL_VAR(scoreboard) // Variable to save the scoreboard string once it's been
/datum/scoreboard/proc/check_station_player(mob/M)
if(!is_station_level(M.z) || M.stat != DEAD)
return
- if(isAI(M))
+ if(is_ai(M))
dead_ai = TRUE
score_dead_crew++
else if(ishuman(M))
diff --git a/code/game/machinery/ai_display.dm b/code/game/machinery/ai_display.dm
index fda00c73582..155d67d7238 100644
--- a/code/game/machinery/ai_display.dm
+++ b/code/game/machinery/ai_display.dm
@@ -23,7 +23,7 @@ GLOBAL_LIST_EMPTY(ai_displays)
return ..()
/obj/machinery/ai_status_display/attack_ai(mob/living/silicon/ai/user)
- if(isAI(user))
+ if(is_ai(user))
user.ai_statuschange()
/obj/machinery/ai_status_display/emp_act(severity)
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index ca131022a99..bc793fadcc3 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -55,7 +55,7 @@
GLOB.cameranet.cameras += src
part_of_camera_network = should_add_to_cameranet
if(part_of_camera_network)
- GLOB.cameranet.addCamera(src)
+ GLOB.cameranet.add_camera(src)
if(isturf(loc))
var/area/our_area = get_area(src)
LAZYADD(our_area.cameras, UID())
@@ -81,7 +81,7 @@
kick_out_watchers()
QDEL_NULL(assembly)
QDEL_NULL(wires)
- GLOB.cameranet.removeCamera(src)
+ GLOB.cameranet.remove_camera(src)
GLOB.cameranet.cameras -= src
var/area/our_area = get_area(src)
if(our_area) // We should probably send out the warning alarms if this doesn't exist, because this should always have an area!
@@ -134,7 +134,7 @@
/obj/machinery/camera/proc/setViewRange(num = CAMERA_VIEW_DISTANCE)
view_range = num
- GLOB.cameranet.updateVisibility(src, 0)
+ GLOB.cameranet.update_visibility(src, 0)
/obj/machinery/camera/singularity_pull(S, current_size)
if(status && current_size >= STAGE_FIVE) // If the singulo is strong enough to pull anchored objects and the camera is still active, turn off the camera as it gets ripped off the wall.
@@ -192,7 +192,7 @@
to_chat(U, "You hold \the [itemname] up to the camera ...")
U.changeNext_move(CLICK_CD_MELEE)
for(var/mob/O in GLOB.player_list)
- if(isAI(O))
+ if(is_ai(O))
var/mob/living/silicon/ai/AI = O
if(AI.control_disabled || (AI.stat == DEAD))
return
@@ -415,7 +415,7 @@
user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/stretch/impaired, 2)
/obj/machinery/camera/update_remote_sight(mob/living/user)
- if(isXRay() && isAI(user))
+ if(isXRay() && is_ai(user))
user.sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS)
user.see_in_dark = max(user.see_in_dark, 8)
user.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
@@ -446,5 +446,5 @@
return
SEND_SIGNAL(src, COMSIG_CAMERA_MOVED, prev_turf)
- GLOB.cameranet.updatePortableCamera(src, prev_turf)
+ GLOB.cameranet.update_portable_camera(src, prev_turf)
prev_turf = get_turf(src)
diff --git a/code/game/machinery/camera/camera_presets.dm b/code/game/machinery/camera/camera_presets.dm
index 36a39afc6c2..34f90ce2f40 100644
--- a/code/game/machinery/camera/camera_presets.dm
+++ b/code/game/machinery/camera/camera_presets.dm
@@ -146,7 +146,7 @@
assembly.upgrades.Add(new /obj/item/analyzer(assembly))
setPowerUsage()
//Update what it can see.
- GLOB.cameranet.updateVisibility(src, 0)
+ GLOB.cameranet.update_visibility(src, 0)
// If you are upgrading Motion, and it isn't in the camera's New(), add it to the machines list.
/obj/machinery/camera/proc/upgradeMotion()
diff --git a/code/game/machinery/camera/motion.dm b/code/game/machinery/camera/motion.dm
index 5f2e83b11a2..e3b57014330 100644
--- a/code/game/machinery/camera/motion.dm
+++ b/code/game/machinery/camera/motion.dm
@@ -22,7 +22,7 @@
return localMotionTargets
/obj/machinery/camera/proc/newTarget(mob/target)
- if(isAI(target))
+ if(is_ai(target))
return FALSE
if(isbot(target)) //No armsky, you don't get to set off the motion alarm constantly
return FALSE
diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm
index 92f39c2a0d3..9c1a491b6fc 100644
--- a/code/game/machinery/camera/tracking.dm
+++ b/code/game/machinery/camera/tracking.dm
@@ -41,7 +41,7 @@
return 0
var/obj/machinery/camera/C = track.cameras[camera]
- src.eyeobj.setLoc(C)
+ src.eyeobj.set_loc(C)
return
@@ -104,18 +104,18 @@
ai_actual_track(target)
/mob/living/silicon/ai/proc/ai_cancel_tracking(forced = 0)
- if(!cameraFollow)
+ if(!camera_follow)
return
to_chat(src, "Follow camera mode [forced ? "terminated" : "ended"].")
- cameraFollow = null
+ camera_follow = null
/mob/living/silicon/ai/proc/ai_actual_track(mob/living/target, doubleclick = FALSE)
if(!istype(target))
return
var/mob/living/silicon/ai/U = usr
- U.cameraFollow = target
+ U.camera_follow = target
U.tracking = TRUE
to_chat(U, "Attempting to track [target.get_visible_name()]...")
@@ -126,20 +126,20 @@
if(target.is_jammed())
to_chat(U, "Unable to track [target.get_visible_name()]...")
- U.cameraFollow = null
+ U.camera_follow = null
return
if(!target || !target.can_track(usr))
to_chat(U, "Target is not near any active cameras.")
- U.cameraFollow = null
+ U.camera_follow = null
return
to_chat(U, "Now tracking [target.get_visible_name()] on camera.")
var/cameraticks = 0
spawn(0)
- while(U.cameraFollow == target)
- if(U.cameraFollow == null)
+ while(U.camera_follow == target)
+ if(U.camera_follow == null)
return
if(!target.can_track(usr))
@@ -148,7 +148,7 @@
to_chat(U, "Target is not near any active cameras. Attempting to reacquire...")
cameraticks++
if(cameraticks > 9)
- U.cameraFollow = null
+ U.camera_follow = null
to_chat(U, "Unable to reacquire, cancelling track...")
U.tracking = FALSE
return
@@ -161,11 +161,11 @@
U.tracking = FALSE
if(U.eyeobj)
- U.eyeobj.setLoc(get_turf(target))
+ U.eyeobj.set_loc(get_turf(target))
else
view_core()
- U.cameraFollow = null
+ U.camera_follow = null
return
sleep(10)
@@ -175,9 +175,9 @@
return 0
if(isrobot(M))
var/mob/living/silicon/robot/R = M
- if(!(R.camera && R.camera.can_use()) && !GLOB.cameranet.checkCameraVis(M))
+ if(!(R.camera && R.camera.can_use()) && !GLOB.cameranet.check_camera_vis(M))
return 0
- else if(!GLOB.cameranet.checkCameraVis(M))
+ else if(!GLOB.cameranet.check_camera_vis(M))
return 0
return 1
@@ -186,7 +186,7 @@
return
if(!src.can_use())
return
- user.eyeobj.setLoc(get_turf(src))
+ user.eyeobj.set_loc(get_turf(src))
/mob/living/silicon/ai/attack_ai(mob/user)
diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm
index 8c09419e916..a920236b48d 100644
--- a/code/game/machinery/computer/camera_advanced.dm
+++ b/code/game/machinery/computer/camera_advanced.dm
@@ -3,7 +3,7 @@
desc = "Used to access the various cameras on the station."
icon_screen = "cameras"
icon_keyboard = "security_key"
- var/mob/camera/ai_eye/remote/eyeobj
+ var/mob/camera/eye/eyeobj
var/mob/living/carbon/human/current_user = null
var/list/networks = list("SS13")
var/datum/action/innate/camera_off/off_action = new
@@ -11,8 +11,8 @@
var/list/actions = list()
/obj/machinery/computer/camera_advanced/proc/CreateEye()
- eyeobj = new()
- eyeobj.origin = src
+ eyeobj = new /mob/camera/eye/syndicate(loc, name, src, current_user)
+ give_eye_control(current_user)
/obj/machinery/computer/camera_advanced/proc/GrantActions(mob/living/user)
if(off_action)
@@ -25,19 +25,17 @@
jump_action.Grant(user)
actions += jump_action
-/obj/machinery/computer/camera_advanced/proc/remove_eye_control(mob/living/user)
- if(!user)
+/obj/machinery/computer/camera_advanced/proc/RemoveActions()
+ if(!istype(current_user))
return
for(var/V in actions)
var/datum/action/A = V
- A.Remove(user)
+ A.Remove(current_user)
actions.Cut()
- if(user.client)
- user.reset_perspective(null)
- eyeobj.RemoveImages()
- eyeobj.eye_user = null
- user.remote_control = null
+/obj/machinery/computer/camera_advanced/proc/remove_eye_control(mob/living/user)
+ RemoveActions()
+ eyeobj.release_control()
current_user = null
remove_eye(user)
playsound(src, 'sound/machines/terminal_off.ogg', 25, 0)
@@ -57,7 +55,7 @@
return ..()
/obj/machinery/computer/camera_advanced/proc/remove_eye(mob/M)
- if(M == current_user)
+ if(istype(M) && M == current_user)
remove_eye_control(M)
/obj/machinery/computer/camera_advanced/attack_hand(mob/user)
@@ -68,102 +66,17 @@
return
if(..())
return
+ current_user = user
if(!eyeobj)
CreateEye()
-
- if(!eyeobj.eye_initialized)
- var/camera_location
- for(var/obj/machinery/camera/C in GLOB.cameranet.cameras)
- if(!C.can_use())
- continue
- if(length(C.network & networks))
- camera_location = get_turf(C)
- break
- if(camera_location)
- eyeobj.eye_initialized = 1
- give_eye_control(user)
- eyeobj.setLoc(camera_location)
- else
- // An abberant case - silent failure is obnoxious
- to_chat(user, "ERROR: No linked and active camera network found.")
- remove_eye(user)
else
give_eye_control(user)
- eyeobj.setLoc(eyeobj.loc)
-
+ eyeobj.set_loc(eyeobj.loc)
/obj/machinery/computer/camera_advanced/proc/give_eye_control(mob/user)
+ eyeobj.give_control(user)
GrantActions(user)
- current_user = user
- eyeobj.eye_user = user
- eyeobj.name = "Camera Eye ([user.name])"
- user.remote_control = eyeobj
- user.reset_perspective(eyeobj)
-
-/mob/camera/ai_eye/remote
- name = "Inactive Camera Eye"
- // Abductors dont trigger the Ai Detector
- ai_detector_visible = FALSE
- var/sprint = 10
- var/cooldown = 0
- var/acceleration = 1
- var/mob/living/carbon/human/eye_user = null
- var/obj/machinery/computer/camera_advanced/origin
- var/eye_initialized = 0
- var/visible_icon = 0
- var/image/user_image = null
-
-/mob/camera/ai_eye/remote/Destroy()
- eye_user = null
- origin = null
- return ..()
-
-/mob/camera/ai_eye/remote/RemoveImages()
- ..()
- if(visible_icon)
- var/client/C = GetViewerClient()
- if(C)
- C.images -= user_image
-
-/mob/camera/ai_eye/remote/GetViewerClient()
- if(eye_user)
- return eye_user.client
- return null
-
-/mob/camera/ai_eye/remote/setLoc(T)
- if(eye_user)
- if(!isturf(eye_user.loc))
- return
- T = get_turf(T)
- var/old_loc = loc
- loc = T
- Moved(old_loc, get_dir(old_loc, loc))
- if(use_static)
- GLOB.cameranet.visibility(src, GetViewerClient())
- if(visible_icon)
- if(eye_user.client)
- eye_user.client.images -= user_image
- user_image = image(icon,loc,icon_state,FLY_LAYER)
- eye_user.client.images += user_image
-
-/mob/camera/ai_eye/remote/relaymove(mob/user,direct)
- var/initial = initial(sprint)
- var/max_sprint = 50
-
- if(cooldown && cooldown < world.timeofday) // 3 seconds
- sprint = initial
-
- for(var/i = 0; i < max(sprint, initial); i += 20)
- var/turf/step = get_turf(get_step(src, direct))
- if(step)
- src.setLoc(step)
-
- cooldown = world.timeofday + 5
- if(acceleration)
- sprint = min(sprint + 0.5, max_sprint)
- else
- sprint = initial
/datum/action/innate/camera_off
name = "End Camera View"
@@ -173,7 +86,7 @@
if(!target || !iscarbon(target))
return
var/mob/living/carbon/C = target
- var/mob/camera/ai_eye/remote/remote_eye = C.remote_control
+ var/mob/camera/eye/remote_eye = C.remote_control
var/obj/machinery/computer/camera_advanced/console = remote_eye.origin
console.remove_eye_control(target)
@@ -185,7 +98,7 @@
if(!target || !iscarbon(target))
return
var/mob/living/carbon/C = target
- var/mob/camera/ai_eye/remote/remote_eye = C.remote_control
+ var/mob/camera/eye/remote_eye = C.remote_control
var/obj/machinery/computer/camera_advanced/origin = remote_eye.origin
var/list/L = list()
@@ -209,7 +122,7 @@
playsound(origin, "terminal_type", 25, 0)
if(final)
playsound(origin, 'sound/machines/terminal_prompt_confirm.ogg', 25, FALSE)
- remote_eye.setLoc(get_turf(final))
+ remote_eye.set_loc(get_turf(final))
C.overlay_fullscreen("flash", /atom/movable/screen/fullscreen/stretch/flash/noise)
C.clear_fullscreen("flash", 3) //Shorter flash than normal since it's an ~~advanced~~ console!
else
diff --git a/code/game/machinery/computer/camera_console.dm b/code/game/machinery/computer/camera_console.dm
index dfb4e1f08ea..1bcf9828003 100644
--- a/code/game/machinery/computer/camera_console.dm
+++ b/code/game/machinery/computer/camera_console.dm
@@ -173,7 +173,7 @@
ui_interact(user)
/obj/machinery/computer/security/attack_ai(mob/user)
- if(isAI(user))
+ if(is_ai(user))
to_chat(user, "You realise it's kind of stupid to access a camera console when you have the entire camera network at your metaphorical fingertips.")
return
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index 2870683a5c3..83ce0497dcc 100644
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -134,7 +134,7 @@
setMenuState(ui.user, COMM_SCREEN_MAIN)
if("newalertlevel")
- if(isAI(ui.user) || isrobot(ui.user))
+ if(is_ai(ui.user) || isrobot(ui.user))
to_chat(ui.user, "Firewalls prevent you from changing the alert level.")
return
else if(ADMIN_CHECK(ui.user))
@@ -184,7 +184,7 @@
setMenuState(ui.user, COMM_SCREEN_MAIN)
if("cancelshuttle")
- if(isAI(ui.user) || isrobot(ui.user))
+ if(is_ai(ui.user) || isrobot(ui.user))
to_chat(ui.user, "Firewalls prevent you from recalling the shuttle.")
return
var/response = tgui_alert(usr, "Are you sure you wish to recall the shuttle?", "Confirm", list("Yes", "No"))
@@ -418,7 +418,7 @@
/obj/machinery/computer/communications/ui_data(mob/user)
var/list/data = list()
- data["is_ai"] = isAI(user) || isrobot(user)
+ data["is_ai"] = is_ai(user) || isrobot(user)
data["noauthbutton"] = !ishuman(user)
data["menu_state"] = data["is_ai"] ? ai_menu_state : menu_state
data["emagged"] = emagged
@@ -515,19 +515,19 @@
return data
/obj/machinery/computer/communications/proc/setCurrentMessage(mob/user, value)
- if(isAI(user) || isrobot(user))
+ if(is_ai(user) || isrobot(user))
aicurrmsg = value
else
currmsg = value
/obj/machinery/computer/communications/proc/getCurrentMessage(mob/user)
- if(isAI(user) || isrobot(user))
+ if(is_ai(user) || isrobot(user))
return aicurrmsg
else
return currmsg
/obj/machinery/computer/communications/proc/setMenuState(mob/user, value)
- if(isAI(user) || isrobot(user))
+ if(is_ai(user) || isrobot(user))
ai_menu_state=value
else
menu_state=value
diff --git a/code/game/machinery/computer/message_monitor.dm b/code/game/machinery/computer/message_monitor.dm
index fd66ec23513..d89bd4eba62 100644
--- a/code/game/machinery/computer/message_monitor.dm
+++ b/code/game/machinery/computer/message_monitor.dm
@@ -129,7 +129,7 @@
else
for(var/n = ++i; n <= optioncount; n++)
dat += " [n]. ---------------
"
- if((isAI(user) || isrobot(user)) && (user.mind.special_role && user.mind.is_original_mob(user)))
+ if((is_ai(user) || isrobot(user)) && (user.mind.special_role && user.mind.is_original_mob(user)))
//Malf/Traitor AIs can bruteforce into the system to gain the Key.
dat += "*&@#. Bruteforce Key
"
else
@@ -159,7 +159,7 @@
dat += ""
//Hacking screen.
if(2)
- if(isAI(user) || isrobot(user))
+ if(is_ai(user) || isrobot(user))
dat += "Brute-forcing for server key.
It will take 20 seconds for every character that the password has."
dat += "In the meantime, this console can reveal your true intentions if you let someone access it. Make sure no humans enter the room during that time."
else
@@ -349,7 +349,7 @@
//Hack the Console to get the password
if(href_list["hack"])
- if((isAI(usr) || isrobot(usr)) && (usr.mind.special_role && usr.mind.is_original_mob(usr)))
+ if((is_ai(usr) || isrobot(usr)) && (usr.mind.special_role && usr.mind.is_original_mob(usr)))
src.hacking = 1
src.screen = 2
src.icon_screen = hack_icon
diff --git a/code/game/machinery/computer/robot_control.dm b/code/game/machinery/computer/robot_control.dm
index f15a9014be0..d9f96e0a991 100644
--- a/code/game/machinery/computer/robot_control.dm
+++ b/code/game/machinery/computer/robot_control.dm
@@ -66,7 +66,7 @@
return FALSE
if(!console_shows(R))
return FALSE
- if(isAI(user))
+ if(is_ai(user))
if(R.connected_ai != user)
if(telluserwhy)
to_chat(user, "AIs can only control cyborgs which are linked to them.")
@@ -107,7 +107,7 @@
return FALSE
if(user.can_admin_interact())
return TRUE
- if(!isAI(user))
+ if(!is_ai(user))
return FALSE
return (user.mind.special_role && user.mind.is_original_mob(user))
diff --git a/code/game/machinery/dance_machine.dm b/code/game/machinery/dance_machine.dm
index f5a4cf90752..c2389895e0c 100644
--- a/code/game/machinery/dance_machine.dm
+++ b/code/game/machinery/dance_machine.dm
@@ -95,7 +95,7 @@
if(!anchored)
to_chat(user,"This device must be anchored by a wrench!")
return
- if(!Adjacent(user) && !isAI(user))
+ if(!Adjacent(user) && !is_ai(user))
return
user.set_machine(src)
var/list/dat = list()
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index 3ce720c1f8c..c89fff93af6 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -466,7 +466,7 @@
/obj/machinery/door/proc/update_freelook_sight()
if(!glass && GLOB.cameranet)
- GLOB.cameranet.updateVisibility(src, 0)
+ GLOB.cameranet.update_visibility(src, 0)
/obj/machinery/door/proc/check_unres() //unrestricted sides. This overlay indicates which directions the player can access even without an ID
if(hasPower() && unres_sides)
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index c57b10ff4ea..118340d2df8 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -92,6 +92,7 @@ GLOBAL_LIST_EMPTY(holopads)
var/ringing = FALSE
/// Whether or not the user is currently selecting where to send their call.
var/dialling_input = FALSE
+ var/mob/camera/eye/hologram/eye
/obj/machinery/hologram/holopad/Initialize(mapload)
. = ..()
@@ -190,7 +191,7 @@ GLOBAL_LIST_EMPTY(holopads)
/obj/machinery/hologram/holopad/AltClick(mob/living/carbon/human/user)
if(..())
return
- if(isAI(user))
+ if(is_ai(user))
hangup_all_calls()
return
@@ -240,7 +241,7 @@ GLOBAL_LIST_EMPTY(holopads)
popup.open()
/obj/machinery/hologram/holopad/Topic(href, href_list)
- if(..() || isAI(usr))
+ if(..() || is_ai(usr))
return
add_fingerprint(usr)
if(stat & NOPOWER)
@@ -319,7 +320,7 @@ GLOBAL_LIST_EMPTY(holopads)
I don't need to check for client since they're clicking on an object.
This may change in the future but for now will suffice.*/
else if(ai.eyeobj.loc != loc)//Set client eye on the object if it's not already.
- ai.eyeobj.setLoc(get_turf(src))
+ ai.eyeobj.set_loc(get_turf(src))
else if(!LAZYLEN(masters) || !masters[ai])//If there is no hologram, possibly make one.
activate_holo(ai, 1)
else//If there is a hologram, remove it.
@@ -358,7 +359,7 @@ GLOBAL_LIST_EMPTY(holopads)
//Try to transfer hologram to another pad that can project on T
/obj/machinery/hologram/holopad/proc/transfer_to_nearby_pad(turf/T, mob/holo_owner)
- if(!isAI(holo_owner))
+ if(!is_ai(holo_owner))
return
for(var/pad in GLOB.holopads)
var/obj/machinery/hologram/holopad/another = pad
@@ -375,7 +376,7 @@ GLOBAL_LIST_EMPTY(holopads)
if(QDELETED(user) || user.incapacitated() || !user.client)
return FALSE
- if(isAI(user))
+ if(is_ai(user))
var/mob/living/silicon/ai/AI = user
if(!AI.current)
return FALSE
@@ -383,8 +384,8 @@ GLOBAL_LIST_EMPTY(holopads)
//Can we display holos there
//Area check instead of line of sight check because this is a called a lot if AI wants to move around.
-/obj/machinery/hologram/holopad/proc/validate_location(turf/T,check_los = FALSE)
- if(T.z == z && get_dist(T, src) <= holo_range && T.loc == get_area(src))
+/obj/machinery/hologram/holopad/proc/validate_location(turf/T)
+ if(T.z == z && (get_dist(T, src) <= holo_range) && T.loc == get_area(src))
return TRUE
return FALSE
@@ -418,7 +419,7 @@ GLOBAL_LIST_EMPTY(holopads)
return
var/obj/effect/overlay/holo_pad_hologram/hologram = new(loc)//Spawn a blank effect at the location.
- if(isAI(user))
+ if(is_ai(user))
hologram.icon = AI.holo_icon
else //make it like real life
if(isrobot(user))
@@ -438,6 +439,7 @@ GLOBAL_LIST_EMPTY(holopads)
hologram.set_light(2) //hologram lighting
move_hologram()
+ eye = new /mob/camera/eye/hologram(src, user.name, src, user)
set_holo(user, hologram)
if(!masters[user])//If there is not already a hologram.
@@ -490,6 +492,8 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
/obj/machinery/hologram/holopad/proc/set_holo(mob/living/user, obj/effect/overlay/holo_pad_hologram/h)
+ eye = user.remote_control
+ eye.holopad = src
masters[user] = h
holorays[user] = new /obj/effect/overlay/holoray(loc)
var/mob/living/silicon/ai/AI = user
@@ -501,10 +505,13 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
/obj/machinery/hologram/holopad/proc/clear_holo(mob/living/user)
qdel(masters[user]) // Get rid of user's hologram
+ if(!QDELETED(eye))
+ QDEL_NULL(eye)
unset_holo(user)
return TRUE
/obj/machinery/hologram/holopad/proc/unset_holo(mob/living/user)
+ eye = null
var/mob/living/silicon/ai/AI = user
if(istype(AI) && AI.current == src)
AI.current = null
diff --git a/code/game/machinery/magnetic_module.dm b/code/game/machinery/magnetic_module.dm
index 5f50939ffd1..7e0e012b648 100644
--- a/code/game/machinery/magnetic_module.dm
+++ b/code/game/machinery/magnetic_module.dm
@@ -165,7 +165,7 @@
step_towards(M, center)
for(var/mob/living/silicon/S in orange(magnetic_field, center))
- if(isAI(S)) continue
+ if(is_ai(S)) continue
step_towards(S, center)
use_power(electricity_level * 5)
diff --git a/code/game/machinery/poolcontroller.dm b/code/game/machinery/poolcontroller.dm
index 46df33dfc23..71cc230dba3 100644
--- a/code/game/machinery/poolcontroller.dm
+++ b/code/game/machinery/poolcontroller.dm
@@ -102,7 +102,7 @@
QDEL_IN(decal, 25)
/obj/machinery/poolcontroller/proc/handleTemp(mob/M)
- if(!M || isAIEye(M) || issilicon(M) || isobserver(M) || M.stat == DEAD)
+ if(!M || is_ai_eye(M) || issilicon(M) || isobserver(M) || M.stat == DEAD)
return
M.water_act(100, temperature, src)//leave temp at 0, we handle it in the switch. oh wait
switch(temperature) //Apply different effects based on what the temperature is set to.
diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm
index f97faf4f0ad..b0156847211 100644
--- a/code/game/machinery/portable_turret.dm
+++ b/code/game/machinery/portable_turret.dm
@@ -189,7 +189,7 @@ GLOBAL_LIST_EMPTY(turret_icons)
/obj/machinery/porta_turret/proc/isLocked(mob/user)
if(HasController())
return TRUE
- if(isrobot(user) || isAI(user))
+ if(isrobot(user) || is_ai(user))
if(ailock)
to_chat(user, "There seems to be a firewall preventing you from accessing this device.")
return TRUE
diff --git a/code/game/machinery/quantum_pad.dm b/code/game/machinery/quantum_pad.dm
index f5f31efc6fb..7d85686548a 100644
--- a/code/game/machinery/quantum_pad.dm
+++ b/code/game/machinery/quantum_pad.dm
@@ -147,7 +147,7 @@
return TRUE
/obj/machinery/quantumpad/attack_hand(mob/user)
- if(isAI(user))
+ if(is_ai(user))
return
if(!check_usable(user))
return
@@ -161,13 +161,13 @@
if(!istype(AI))
return
if(AI.eyeobj.loc != loc)
- AI.eyeobj.setLoc(get_turf(loc))
+ AI.eyeobj.set_loc(get_turf(loc))
return
if(!check_usable(user))
return
var/turf/T = get_turf(linked_pad)
- if(GLOB.cameranet && GLOB.cameranet.checkTurfVis(T))
- AI.eyeobj.setLoc(T)
+ if(GLOB.cameranet && GLOB.cameranet.check_turf_vis(T))
+ AI.eyeobj.set_loc(T)
else
to_chat(user, "Linked pad is not on or near any active cameras on the station.")
diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm
index da4fafec5c3..d8b133a3eb2 100644
--- a/code/game/machinery/teleporter.dm
+++ b/code/game/machinery/teleporter.dm
@@ -334,8 +334,8 @@
Prevents AI from using the teleporter, prints out failure messages for clarity
*/
/obj/machinery/teleport/proc/blockAI(atom/A)
- if(isAI(A) || istype(A, /obj/structure/ai_core))
- if(isAI(A))
+ if(is_ai(A) || istype(A, /obj/structure/ai_core))
+ if(is_ai(A))
var/mob/living/silicon/ai/T = A
if(T.allow_teleporter)
return FALSE
diff --git a/code/game/machinery/turret_control.dm b/code/game/machinery/turret_control.dm
index ea9bf127181..bdc87cd7d9c 100644
--- a/code/game/machinery/turret_control.dm
+++ b/code/game/machinery/turret_control.dm
@@ -88,7 +88,7 @@
update_icon(UPDATE_ICON_STATE)
/obj/machinery/turretid/proc/isLocked(mob/user)
- if(isrobot(user) || isAI(user))
+ if(isrobot(user) || is_ai(user))
if(ailock)
to_chat(user, "There seems to be a firewall preventing you from accessing this device.")
return TRUE
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index a0719e38671..df4cad6e001 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -660,7 +660,7 @@
occupant.SetSleeping(destruction_sleep_duration)
go_out()
for(var/mob/M in src) //Let's just be ultra sure
- if(isAI(M))
+ if(is_ai(M))
var/mob/living/silicon/ai/AI = M //AIs are loaded into the mech computer itself. When the mech dies, so does the AI. They can be recovered with an AI card from the wreck.
AI.gib() //No wreck, no AI to recover
else
@@ -949,7 +949,7 @@
/////////////////////////////////////
/obj/mecha/attack_ai(mob/living/silicon/ai/user)
- if(!isAI(user))
+ if(!is_ai(user))
return
//Allows the Malf to scan a mech's status and loadout, helping it to decide if it is a worthy chariot.
if(user.can_dominate_mechs)
@@ -987,7 +987,7 @@
to_chat(user, "[name] must have maintenance protocols active in order to allow a transfer.")
return
AI = occupant
- if(!AI || !isAI(occupant)) //Mech does not have an AI for a pilot
+ if(!AI || !is_ai(occupant)) //Mech does not have an AI for a pilot
to_chat(user, "No AI detected in the [name] onboard computer.")
return
if(AI.mind.special_role) //Malf AIs cannot leave mechs. Except through death.
@@ -1042,6 +1042,7 @@
AI.cancel_camera()
AI.controlled_mech = src
AI.remote_control = src
+ AI.reset_perspective(src)
AI.can_shunt = FALSE //ONE AI ENTERS. NO AI LEAVES.
to_chat(AI, "[AI.can_dominate_mechs ? "Takeover of [name] complete! You are now permanently loaded onto the onboard computer. Do not attempt to leave the station sector!" \
: "You have been uploaded to a mech's onboard computer."]")
@@ -1273,7 +1274,7 @@
/obj/mecha/Exited(atom/movable/M, direction)
var/new_loc = get_step(M, direction)
if(occupant && occupant == M) // The occupant exited the mech without calling go_out()
- if(!isAI(occupant)) //This causes carded AIS to gib, so we do not want this to be called during carding.
+ if(!is_ai(occupant)) //This causes carded AIS to gib, so we do not want this to be called during carding.
go_out(1, new_loc)
/obj/mecha/proc/go_out(forced, atom/newloc = loc)
@@ -1292,7 +1293,7 @@
var/mob/living/brain/brain = occupant
RemoveActions(brain)
mob_container = brain.container
- else if(isAI(occupant))
+ else if(is_ai(occupant))
var/mob/living/silicon/ai/AI = occupant
if(forced)//This should only happen if there are multiple AIs in a round, and at least one is Malf.
RemoveActions(occupant)
@@ -1306,7 +1307,11 @@
return
to_chat(AI, "Returning to core...")
AI.controlled_mech = null
- AI.remote_control = null
+ if(istype(AI.eyeobj))
+ AI.remote_control = AI.eyeobj
+ AI.reset_perspective(AI.eyeobj)
+ else
+ AI.eyeobj = new /mob/camera/eye/ai(loc, AI.name, AI, AI)
RemoveActions(occupant, 1)
mob_container = AI
newloc = get_turf(AI.linked_core)
@@ -1581,7 +1586,7 @@
/obj/mecha/obj_destruction()
if(wreckage)
var/mob/living/silicon/ai/AI
- if(isAI(occupant))
+ if(is_ai(occupant))
AI = occupant
occupant = null
var/obj/structure/mecha_wreckage/WR = new wreckage(loc, AI)
diff --git a/code/game/objects/effects/effect_system/effect_system.dm b/code/game/objects/effects/effect_system/effect_system.dm
index 246fd64e963..1a6ee994609 100644
--- a/code/game/objects/effects/effect_system/effect_system.dm
+++ b/code/game/objects/effects/effect_system/effect_system.dm
@@ -13,11 +13,11 @@ would spawn and follow the beaker, even if it is carried or thrown.
/obj/effect/particle_effect/New()
..()
if(SSticker)
- GLOB.cameranet.updateVisibility(src)
+ GLOB.cameranet.update_visibility(src)
/obj/effect/particle_effect/Destroy()
if(SSticker)
- GLOB.cameranet.updateVisibility(src)
+ GLOB.cameranet.update_visibility(src)
return ..()
/datum/effect_system
diff --git a/code/game/objects/items/devices/radio/headset.dm b/code/game/objects/items/devices/radio/headset.dm
index 0f0da313d3d..af74b6cb5eb 100644
--- a/code/game/objects/items/devices/radio/headset.dm
+++ b/code/game/objects/items/devices/radio/headset.dm
@@ -71,7 +71,7 @@
var/mob/living/carbon/human/H = loc
if(H.l_ear == src || H.r_ear == src)
return ..()
- else if(isanimal(loc) || isAI(loc))
+ else if(isanimal(loc) || is_ai(loc))
return ..()
return FALSE
diff --git a/code/game/objects/items/devices/radio/radio_objects.dm b/code/game/objects/items/devices/radio/radio_objects.dm
index d505e3aa64d..98a12cb9145 100644
--- a/code/game/objects/items/devices/radio/radio_objects.dm
+++ b/code/game/objects/items/devices/radio/radio_objects.dm
@@ -411,7 +411,7 @@ GLOBAL_LIST_EMPTY(deadsay_radio_systems)
jobname = "No id"
// --- AI ---
- else if(isAI(M))
+ else if(is_ai(M))
jobname = "AI"
// --- Cyborg ---
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index b45a8cf5022..395cca3a964 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -497,7 +497,7 @@ SLIME SCANNER
scan_type = "robot"
else if(ishuman(M))
scan_type = "prosthetics"
- else if(isAI(M))
+ else if(is_ai(M))
scan_type = "ai"
else
to_chat(user, "You can't analyze non-robotic things!")
diff --git a/code/game/objects/items/tools/multitool.dm b/code/game/objects/items/tools/multitool.dm
index 5f7187c9a0c..42d477cf7f0 100644
--- a/code/game/objects/items/tools/multitool.dm
+++ b/code/game/objects/items/tools/multitool.dm
@@ -94,15 +94,15 @@
/obj/item/multitool/ai_detect/proc/multitool_detect()
var/turf/our_turf = get_turf(src)
for(var/mob/living/silicon/ai/AI in GLOB.ai_list)
- if(AI.cameraFollow == src)
+ if(AI.camera_follow == src)
detect_state = PROXIMITY_ON_SCREEN
break
- if(!detect_state && GLOB.cameranet.chunkGenerated(our_turf.x, our_turf.y, our_turf.z))
- var/datum/camerachunk/chunk = GLOB.cameranet.getCameraChunk(our_turf.x, our_turf.y, our_turf.z)
+ if(!detect_state && GLOB.cameranet.chunk_generated(our_turf.x, our_turf.y, our_turf.z))
+ var/datum/camerachunk/chunk = GLOB.cameranet.get_camera_chunk(our_turf.x, our_turf.y, our_turf.z)
if(chunk)
if(length(chunk.seenby))
- for(var/mob/camera/ai_eye/A in chunk.seenby)
+ for(var/mob/camera/eye/ai/A in chunk.seenby)
//Checks if the A is to be detected or not
if(!A.ai_detector_visible)
continue
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 0b4d7a1b1b1..f9b0a46abc2 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -515,7 +515,7 @@
..()
playsound(src, 'sound/effects/meteorimpact.ogg', 40, 1)
for(var/mob/M in range(10, src))
- if(!M.stat && !isAI(M))\
+ if(!M.stat && !is_ai(M))\
shake_camera(M, 3, 1)
qdel(src)
@@ -1378,7 +1378,7 @@
playsound(src, 'sound/effects/explosionfar.ogg', 50, FALSE, 0)
flick("bigred_press", src)
for(var/mob/M in range(10, src)) // Checks range
- if(!M.stat && !isAI(M)) // Checks to make sure whoever's getting shaken is alive/not the AI
+ if(!M.stat && !is_ai(M)) // Checks to make sure whoever's getting shaken is alive/not the AI
sleep(8) // Short delay to match up with the explosion sound
shake_camera(M, 2, 1) // Shakes player camera 2 squares for 1 second.
diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm
index 635984ca9c5..66661d0d0d4 100644
--- a/code/game/objects/objs.dm
+++ b/code/game/objects/objs.dm
@@ -113,7 +113,7 @@
if(M.client && M.machine == src)
is_in_use = TRUE
src.attack_hand(M)
- if(isAI(usr) || isrobot(usr))
+ if(is_ai(usr) || isrobot(usr))
if(!(usr in nearby))
if(usr.client && usr.machine==src) // && M.machine == src is omitted because if we triggered this by using the dialog, it doesn't matter if our machine changed in between triggering it and this - the dialog is probably still supposed to refresh.
is_in_use = TRUE
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index 3b6a8c87633..35f8be4f301 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -22,7 +22,7 @@
if(smoothing_flags & SMOOTH_CORNERS)
icon_state = ""
if(SSticker)
- GLOB.cameranet.updateVisibility(src)
+ GLOB.cameranet.update_visibility(src)
/obj/structure/Initialize(mapload)
if(!armor)
@@ -34,7 +34,7 @@
/obj/structure/Destroy()
climbers = null
if(SSticker)
- GLOB.cameranet.updateVisibility(src)
+ GLOB.cameranet.update_visibility(src)
if(smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK))
var/turf/T = get_turf(src)
QUEUE_SMOOTH_NEIGHBORS(T)
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index 81a88adc6d2..a1e0b163ebf 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -247,7 +247,7 @@
continue
if(M.buckled || M.anchored || M.has_buckled_mobs())
continue
- if(isAI(M))
+ if(is_ai(M))
continue
M.forceMove(src)
diff --git a/code/game/objects/structures/inflatable.dm b/code/game/objects/structures/inflatable.dm
index 1db795432b7..d8e4e975453 100644
--- a/code/game/objects/structures/inflatable.dm
+++ b/code/game/objects/structures/inflatable.dm
@@ -107,7 +107,7 @@
var/is_operating = FALSE
/obj/structure/inflatable/door/attack_ai(mob/user as mob) //those aren't machinery, they're just big fucking slabs of a mineral
- if(isAI(user)) //so the AI can't open it
+ if(is_ai(user)) //so the AI can't open it
return
else if(isrobot(user)) //but cyborgs can
if(get_dist(user,src) <= 1) //not remotely though
diff --git a/code/game/objects/structures/kitchen_spike.dm b/code/game/objects/structures/kitchen_spike.dm
index 4ab47a636f3..26d4692461b 100644
--- a/code/game/objects/structures/kitchen_spike.dm
+++ b/code/game/objects/structures/kitchen_spike.dm
@@ -87,7 +87,7 @@
deconstruct(TRUE)
/obj/structure/kitchenspike/MouseDrop_T(mob/living/victim, mob/living/user)
- if(!user.Adjacent(src) || !user.Adjacent(victim) || isAI(user) || !ismob(victim))
+ if(!user.Adjacent(src) || !user.Adjacent(victim) || is_ai(user) || !ismob(victim))
return
if(isanimal(user) && victim != user)
return // animals cannot put mobs other than themselves onto spikes
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index 144bf5f747d..e12f73b712d 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -47,7 +47,7 @@
return try_to_operate(user)
/obj/structure/mineral_door/attack_ai(mob/user) //those aren't machinery, they're just big fucking slabs of a mineral
- if(isAI(user)) //so the AI can't open it
+ if(is_ai(user)) //so the AI can't open it
return
else if(isrobot(user) && Adjacent(user)) //but cyborgs can, but not remotely
return try_to_operate(user)
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 09341eaea35..55d44814975 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -118,7 +118,7 @@
SET_BITFLAG_LIST(canSmoothWith)
if(smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK))
QUEUE_SMOOTH(src)
- visibilityChanged()
+ visibility_changed()
for(var/atom/movable/AM in src)
Entered(AM)
@@ -150,7 +150,7 @@
qdel(A)
return
REMOVE_FROM_SMOOTH_QUEUE(src)
- visibilityChanged()
+ visibility_changed()
QDEL_LIST_CONTENTS(blueprint_data)
initialized = FALSE
bound_air = null
@@ -480,9 +480,9 @@
ChangeTurf(baseturf)
return 2
-/turf/proc/visibilityChanged()
+/turf/proc/visibility_changed()
if(SSticker)
- GLOB.cameranet.updateVisibility(src)
+ GLOB.cameranet.update_visibility(src)
/turf/attack_by(obj/item/attacking, mob/user, params)
if(..())
diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm
index f3fc59dfa41..b7a1ace80fb 100644
--- a/code/game/verbs/ooc.dm
+++ b/code/game/verbs/ooc.dm
@@ -177,10 +177,10 @@ GLOBAL_VAR_INIT(admin_ooc_colour, "#b82e00")
if(target.mob in heard)
send = 1
- if(isAI(target.mob))
+ if(is_ai(target.mob))
prefix = " (Core)"
- else if(isAI(target.mob)) // Special case
+ else if(is_ai(target.mob)) // Special case
var/mob/living/silicon/ai/A = target.mob
if(A.eyeobj in hearers(7, source))
send = 1
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index 0e80d8806f2..f12dd40466d 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -387,9 +387,9 @@ GLOBAL_LIST_INIT(view_runtimes_verbs, list(
if(ishuman(mob))
var/mob/living/carbon/human/H = mob
H.regenerate_icons() // workaround for #13269
- if(isAI(mob)) // client.mob, built in byond client var
+ if(is_ai(mob)) // client.mob, built in byond client var
var/mob/living/silicon/ai/ai = mob
- ai.eyeobj.setLoc(old_turf)
+ ai.eyeobj.set_loc(old_turf)
else if(isnewplayer(mob))
to_chat(src, "Error: Aghost: Can't admin-ghost whilst in the lobby. Join or observe first.")
else
diff --git a/code/modules/admin/misc_admin_procs.dm b/code/modules/admin/misc_admin_procs.dm
index aee3772ced0..e3349394eba 100644
--- a/code/modules/admin/misc_admin_procs.dm
+++ b/code/modules/admin/misc_admin_procs.dm
@@ -157,7 +157,7 @@ GLOBAL_VAR_INIT(disable_explosions, FALSE)
"}
var/jumptoeye = ""
- if(isAI(M))
+ if(is_ai(M))
var/mob/living/silicon/ai/A = M
if(A.client && A.eyeobj) // No point following clientless AI eyes
jumptoeye = " (Eye)"
@@ -199,7 +199,7 @@ GLOBAL_VAR_INIT(disable_explosions, FALSE)
body += "Corgize | "
//AI / Cyborg
- if(isAI(M))
+ if(is_ai(M))
body += "Is an AI "
else if(ishuman(M))
body += {"Make AI |
@@ -800,7 +800,7 @@ GLOBAL_VAR_INIT(disable_explosions, FALSE)
if(istype(S, /mob/living/silicon/decoy) && !S.client)
continue
ai_number++
- if(isAI(S))
+ if(is_ai(S))
messages += "AI [key_name(S, TRUE)]'s laws:"
else if(isrobot(S))
var/mob/living/silicon/robot/R = S
diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm
index eb6c435f6a8..3c1eefa6c07 100644
--- a/code/modules/admin/player_panel.dm
+++ b/code/modules/admin/player_panel.dm
@@ -255,7 +255,7 @@
M_job = "Carbon-based"
else if(issilicon(M)) //silicon
- if(isAI(M))
+ if(is_ai(M))
M_job = "AI"
else if(ispAI(M))
M_job = "pAI"
@@ -298,7 +298,7 @@
M_key = replacetext(M_key, "\\", "")
var/M_eyeUID = ""
- if(isAI(M))
+ if(is_ai(M))
var/mob/living/silicon/ai/A = M
if(A.client && A.eyeobj) // No point following clientless AI eyes
M_eyeUID = "[A.eyeobj.UID()]"
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 602e710d128..27340e1c3ea 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -1146,7 +1146,7 @@
if(!ismob(M))
to_chat(usr, "This can only be used on instances of type /mob")
return
- if(isAI(M))
+ if(is_ai(M))
to_chat(usr, "This cannot be used on instances of type /mob/living/silicon/ai")
return
@@ -1297,7 +1297,7 @@
if(!ismob(M))
to_chat(usr, "This can only be used on instances of type /mob")
return
- if(isAI(M))
+ if(is_ai(M))
to_chat(usr, "This cannot be used on instances of type /mob/living/silicon/ai")
return
@@ -1329,7 +1329,7 @@
if(!ismob(M))
to_chat(usr, "This can only be used on instances of type /mob")
return
- if(isAI(M))
+ if(is_ai(M))
to_chat(usr, "This cannot be used on instances of type /mob/living/silicon/ai")
return
@@ -1361,7 +1361,7 @@
if(!ismob(M))
to_chat(usr, "This can only be used on instances of type /mob")
return
- if(isAI(M))
+ if(is_ai(M))
to_chat(usr, "This cannot be used on instances of type /mob/living/silicon/ai")
return
@@ -1385,7 +1385,7 @@
if(!ismob(M))
to_chat(usr, "This can only be used on instances of type /mob")
return
- if(isAI(M))
+ if(is_ai(M))
to_chat(usr, "This cannot be used on instances of type /mob/living/silicon/ai")
return
@@ -1492,7 +1492,7 @@
if(!ismob(M))
to_chat(usr, "This can only be used on instances of type /mob")
return
- if(isAI(M))
+ if(is_ai(M))
to_chat(usr, "This cannot be used on instances of type /mob/living/silicon/ai")
return
@@ -2255,7 +2255,7 @@
if(!href_list["cryoafk"] && !isLivingSSD(M))
to_chat(usr, "This can only be used on living, SSD players.")
return
- if(isAI(M))
+ if(is_ai(M))
var/mob/living/silicon/ai/A = M
A.cryo_AI()
if(istype(M.loc, /obj/machinery/cryopod))
@@ -3615,7 +3615,7 @@
target = C.mob
. = ADMIN_FLW(target, "FLW")
- if(isAI(target)) // AI core/eye follow links
+ if(is_ai(target)) // AI core/eye follow links
var/mob/living/silicon/ai/A = target
if(A.client && A.eyeobj) // No point following clientless AI eyes
. += "|[ADMIN_FLW(A.eyeobj,"EYE")]"
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index b4953dd3107..0a09fa34d0d 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -23,7 +23,7 @@
return
if(ismob(M))
- if(isAI(M))
+ if(is_ai(M))
alert("The AI can't be sent to prison you jerk!", null, null, null, null, null)
return
//strip their stuff before they teleport into a cell :downs:
diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm
index 3cf88d939d2..cc709d5fe20 100644
--- a/code/modules/antagonists/traitor/datum_traitor.dm
+++ b/code/modules/antagonists/traitor/datum_traitor.dm
@@ -44,7 +44,7 @@ RESTRICT_TYPE(/datum/antagonist/traitor)
/datum/antagonist/traitor/Destroy(force, ...)
// Remove all associated malf AI abilities.
- if(isAI(owner.current))
+ if(is_ai(owner.current))
var/mob/living/silicon/ai/A = owner.current
A.clear_zeroth_law()
var/obj/item/radio/headset/heads/ai_integrated/radio = A.get_radio()
@@ -84,7 +84,7 @@ RESTRICT_TYPE(/datum/antagonist/traitor)
return ..()
/datum/antagonist/traitor/select_organization()
- if(isAI(owner.current))
+ if(is_ai(owner.current))
return
var/chaos = pickweight(list(ORG_CHAOS_HUNTER = ORG_PROB_HUNTER, ORG_CHAOS_MILD = ORG_PROB_MILD, ORG_CHAOS_AVERAGE = ORG_PROB_AVERAGE, ORG_CHAOS_HIJACK = ORG_PROB_HIJACK))
for(var/org_type in shuffle(subtypesof(/datum/antag_org/syndicate)))
@@ -108,7 +108,7 @@ RESTRICT_TYPE(/datum/antagonist/traitor)
return ..()
/datum/antagonist/traitor/give_objectives()
- if(isAI(owner.current))
+ if(is_ai(owner.current))
forge_ai_objectives()
else
forge_human_objectives()
@@ -163,7 +163,7 @@ RESTRICT_TYPE(/datum/antagonist/traitor)
antag_memory += "Organization: [organization.name]
"
if(give_codewords)
messages.Add(give_codewords())
- if(isAI(owner.current))
+ if(is_ai(owner.current))
add_law_zero()
owner.current.playsound_local(get_turf(owner.current), 'sound/ambience/antag/malf.ogg', 100, FALSE, pressure_affected = FALSE, use_reverb = FALSE)
var/mob/living/silicon/ai/A = owner.current
@@ -211,7 +211,7 @@ RESTRICT_TYPE(/datum/antagonist/traitor)
* Gives a traitor human their uplink, and uplink code.
*/
/datum/antagonist/traitor/proc/give_uplink()
- if(isAI(owner.current))
+ if(is_ai(owner.current))
return FALSE
var/mob/living/carbon/human/traitor_mob = owner.current
diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm
index 87fd428c61d..9e86fa0c13e 100644
--- a/code/modules/atmospherics/machinery/airalarm.dm
+++ b/code/modules/atmospherics/machinery/airalarm.dm
@@ -674,7 +674,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
return data
/obj/machinery/alarm/proc/has_rcon_access(mob/user)
- return user && (isAI(user) || allowed(user) || emagged || rcon_setting == RCON_YES)
+ return user && (is_ai(user) || allowed(user) || emagged || rcon_setting == RCON_YES)
// Intentional nulls here
/obj/machinery/alarm/ui_data(mob/user)
@@ -796,7 +796,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
return thresholds
/obj/machinery/alarm/ui_state(mob/user)
- if(isAI(user))
+ if(is_ai(user))
var/mob/living/silicon/ai/AI = user
if(!AI.lacks_power() || AI.apc_override)
return GLOB.always_state
@@ -821,7 +821,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
return TRUE
if(user.can_admin_interact())
return TRUE
- else if(isAI(user) || isrobot(user) || emagged || user.has_unlimited_silicon_privilege)
+ else if(is_ai(user) || isrobot(user) || emagged || user.has_unlimited_silicon_privilege)
return TRUE
else
return !locked
@@ -830,7 +830,7 @@ GLOBAL_LIST_INIT(aalarm_modes, list(
if(buildstage != 2)
return UI_CLOSE
- if(aidisabled && (isAI(user) || isrobot(user)))
+ if(aidisabled && (is_ai(user) || isrobot(user)))
to_chat(user, "AI control for \the [src] interface has been disabled.")
return UI_CLOSE
diff --git a/code/modules/atmospherics/machinery/other/meter.dm b/code/modules/atmospherics/machinery/other/meter.dm
index 0f6deb15046..c485f4afda2 100644
--- a/code/modules/atmospherics/machinery/other/meter.dm
+++ b/code/modules/atmospherics/machinery/other/meter.dm
@@ -61,7 +61,7 @@ GLOBAL_LIST_EMPTY(gas_meters)
/obj/machinery/atmospherics/meter/examine(mob/user)
. = ..()
. += "Measures the volume and temperature of the pipe under the meter."
- if(get_dist(user, src) > 3 && !(isAI(user) || istype(user, /mob/dead)))
+ if(get_dist(user, src) > 3 && !(is_ai(user) || istype(user, /mob/dead)))
. += "You are too far away to read it."
else if(stat & (NOPOWER|BROKEN))
@@ -77,7 +77,7 @@ GLOBAL_LIST_EMPTY(gas_meters)
. += "The connect error light is blinking."
/obj/machinery/atmospherics/meter/Click()
- if(isAI(usr)) // ghosts can call ..() for examine
+ if(is_ai(usr)) // ghosts can call ..() for examine
usr.examinate(src)
return TRUE
diff --git a/code/modules/clothing/suits/misc_suits.dm b/code/modules/clothing/suits/misc_suits.dm
index d1f6402e34d..c08071b5881 100644
--- a/code/modules/clothing/suits/misc_suits.dm
+++ b/code/modules/clothing/suits/misc_suits.dm
@@ -204,7 +204,7 @@
if(!M.anchored && (M.flags & CONDUCT))
step_towards(M,src)
for(var/mob/living/silicon/S in orange(2,src))
- if(isAI(S)) continue
+ if(is_ai(S)) continue
step_towards(S,src)
for(var/mob/living/carbon/human/machine/M in orange(2,src))
step_towards(M,src)
diff --git a/code/modules/events/dust.dm b/code/modules/events/dust.dm
index de651813776..f4f83edc12f 100644
--- a/code/modules/events/dust.dm
+++ b/code/modules/events/dust.dm
@@ -73,7 +73,7 @@
return
if(prob(shake_chance))
for(var/mob/M in range(10, src))
- if(!M.stat && !isAI(M))
+ if(!M.stat && !is_ai(M))
shake_camera(M, 3, 1)
playsound(loc, 'sound/effects/meteorimpact.ogg', 40, 1)
diff --git a/code/modules/fish/fishtank.dm b/code/modules/fish/fishtank.dm
index a5fb9ffed0d..eaa21b7dc70 100644
--- a/code/modules/fish/fishtank.dm
+++ b/code/modules/fish/fishtank.dm
@@ -567,7 +567,7 @@
return ..()
/obj/machinery/fishtank/attack_hand(mob/user)
- if(isAI(user))
+ if(is_ai(user))
return
user.changeNext_move(CLICK_CD_MELEE)
playsound(get_turf(src), 'sound/effects/glassknock.ogg', 80, TRUE)
diff --git a/code/modules/mob/living/silicon/ai/freelook/README.md b/code/modules/mob/camera/README.md
similarity index 100%
rename from code/modules/mob/living/silicon/ai/freelook/README.md
rename to code/modules/mob/camera/README.md
diff --git a/code/modules/mob/camera/cameranet.dm b/code/modules/mob/camera/cameranet.dm
new file mode 100644
index 00000000000..8e6277f4045
--- /dev/null
+++ b/code/modules/mob/camera/cameranet.dm
@@ -0,0 +1,160 @@
+// CAMERA NET
+//
+// The datum containing all the chunks.
+GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new())
+
+/datum/cameranet
+ var/name = "Camera Net"
+
+ /// The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Destroy().
+ var/list/cameras = list()
+ /// The chunks of the map, mapping the areas that the cameras can see.
+ var/list/chunks = list()
+ var/ready = FALSE
+
+/// Returns the chunk at (x, y, z) if it exists, otherwise returns null.
+/datum/cameranet/proc/chunk_generated(x, y, z)
+ x &= ~(CAMERA_CHUNK_SIZE - 1)
+ y &= ~(CAMERA_CHUNK_SIZE - 1)
+ var/key = "[x],[y],[z]"
+ return (chunks[key])
+
+/// Returns the chunk at (x, y, z) if it exists, otherwise returns a new chunk at that location.
+/datum/cameranet/proc/get_camera_chunk(x, y, z)
+ x &= ~(CAMERA_CHUNK_SIZE - 1)
+ y &= ~(CAMERA_CHUNK_SIZE - 1)
+ var/key = "[x],[y],[z]"
+ if(!chunks[key])
+ chunks[key] = new /datum/camerachunk(null, x, y, z)
+
+ return chunks[key]
+
+/// Updates what the camera network can see.
+/datum/cameranet/proc/visibility(list/moved_eyes, client/C)
+ if(!islist(moved_eyes))
+ moved_eyes = moved_eyes ? list(moved_eyes) : list()
+
+ var/list/chunks_pre_seen = list()
+ var/list/chunks_post_seen = list()
+
+ for(var/V in moved_eyes)
+ var/mob/camera/eye/eye = V
+ if(C)
+ chunks_pre_seen |= eye.visible_camera_chunks
+ // 0xf = 15
+ var/static_range = eye.static_visibility_range
+ var/x1 = max(0, eye.x - static_range) & ~(CAMERA_CHUNK_SIZE - 1)
+ var/y1 = max(0, eye.y - static_range) & ~(CAMERA_CHUNK_SIZE - 1)
+ var/x2 = min(world.maxx, eye.x + static_range) & ~(CAMERA_CHUNK_SIZE - 1)
+ var/y2 = min(world.maxy, eye.y + static_range) & ~(CAMERA_CHUNK_SIZE - 1)
+
+ var/list/visible_chunks = list()
+
+ for(var/x = x1; x <= x2; x += CAMERA_CHUNK_SIZE)
+ for(var/y = y1; y <= y2; y += CAMERA_CHUNK_SIZE)
+ visible_chunks |= get_camera_chunk(x, y, eye.z)
+
+ var/list/remove = eye.visible_camera_chunks - visible_chunks
+ var/list/add = visible_chunks - eye.visible_camera_chunks
+
+ for(var/chunk in remove)
+ var/datum/camerachunk/c = chunk
+ c.remove(eye, FALSE)
+
+ for(var/chunk in add)
+ var/datum/camerachunk/c = chunk
+ c.add(eye, FALSE)
+
+ if(C)
+ chunks_post_seen |= eye.visible_camera_chunks
+
+ if(C)
+ var/list/remove = chunks_pre_seen - chunks_post_seen
+ var/list/add = chunks_post_seen - chunks_pre_seen
+
+ for(var/chunk in remove)
+ var/datum/camerachunk/c = chunk
+ C.images -= c.obscured
+
+ for(var/chunk in add)
+ var/datum/camerachunk/c = chunk
+ C.images += c.obscured
+
+
+/// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open.
+/datum/cameranet/proc/update_visibility(atom/A, opacity_check = 1)
+ if(!SSticker || (opacity_check && !A.opacity))
+ return
+ major_chunk_change(update = A)
+
+/// Removes a camera from a chunk.
+/datum/cameranet/proc/remove_camera(obj/machinery/camera/c)
+ major_chunk_change(remove = c)
+
+/// Add a camera to a chunk.
+/datum/cameranet/proc/add_camera(obj/machinery/camera/c)
+ major_chunk_change(add = c)
+
+/// Refreshes the chunk location of a portable camera. Used by Cyborgs.
+/datum/cameranet/proc/update_portable_camera(obj/machinery/camera/c, turf/old_loc)
+ major_chunk_change(add = c, old_loc = old_loc)
+
+/// Private method for updating the chunk an atom is in, and all surrounding chunks.
+/// `add` will be added as a camera to the chunk of its current location and all surrounding chunks.
+/// `remove` will be removed as a camera from the chunk of its current location and all surrounding chunks.
+/// `update` will not be added or removed as a camera, but its surrounding chunks will be updated.
+/// These parameters are mutually exclusive.
+/datum/cameranet/proc/major_chunk_change(atom/add = null, atom/remove = null, atom/update = null, turf/old_loc = null)
+ // 0xf = 15
+ if(!add && !remove && !update)
+ return
+ if(add && remove)
+ CRASH("Adding and removing a camera to the cameranet simultaneously is not implemented")
+
+ var/atom/c = remove
+ if(!c)
+ c = add
+ if(!c)
+ c = update
+
+ var/turf/T = get_turf(c)
+ if(!T)
+ return
+
+ // Check if the turf to add falls in the same chunk as the old_loc. If so, do nothing
+ if(old_loc)
+ if(T.x & ~(CAMERA_CHUNK_SIZE - 1) == old_loc.x & ~(CAMERA_CHUNK_SIZE - 1) && T.y & ~(CAMERA_CHUNK_SIZE - 1) == old_loc.y & ~(CAMERA_CHUNK_SIZE - 1))
+ return
+
+ // Use camera view distance here to actually know how far a camera can max watch
+ var/x1 = max(0, T.x - CAMERA_VIEW_DISTANCE) & ~(CAMERA_CHUNK_SIZE - 1)
+ var/y1 = max(0, T.y - CAMERA_VIEW_DISTANCE) & ~(CAMERA_CHUNK_SIZE - 1)
+ var/x2 = min(world.maxx, T.x + CAMERA_VIEW_DISTANCE) & ~(CAMERA_CHUNK_SIZE - 1)
+ var/y2 = min(world.maxy, T.y + CAMERA_VIEW_DISTANCE) & ~(CAMERA_CHUNK_SIZE - 1)
+
+ for(var/x = x1; x <= x2; x += CAMERA_CHUNK_SIZE)
+ for(var/y = y1; y <= y2; y += CAMERA_CHUNK_SIZE)
+ if(chunk_generated(x, y, T.z))
+ var/datum/camerachunk/chunk = get_camera_chunk(x, y, T.z)
+ if(remove)
+ // Remove the camera.
+ chunk.remove_camera(c)
+ else if(add)
+ // You can't have the same camera in the list twice.
+ chunk.add_camera(c)
+ chunk.has_changed()
+
+/// Returns 1 if a mob is on a viewable turf, otherwise returns 0.
+/datum/cameranet/proc/check_camera_vis(mob/living/target as mob)
+ // 0xf = 15
+ var/turf/position = get_turf(target)
+ return check_turf_vis(position)
+
+/datum/cameranet/proc/check_turf_vis(turf/position)
+ var/datum/camerachunk/chunk = get_camera_chunk(position.x, position.y, position.z)
+ if(chunk)
+ if(chunk.changed)
+ chunk.has_changed(1) // Update now, no matter if it's visible or not.
+ if(chunk.visible_turfs[position])
+ return 1
+ return 0
diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/camera/chunk.dm
similarity index 63%
rename from code/modules/mob/living/silicon/ai/freelook/chunk.dm
rename to code/modules/mob/camera/chunk.dm
index 7deb20f2ef3..6a0e7ff9c26 100644
--- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm
+++ b/code/modules/mob/camera/chunk.dm
@@ -1,11 +1,8 @@
-// CAMERA CHUNK
-//
-// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed.
-// Allows the AI Eye to stream these chunks and know what it can and cannot see.
-
+/// A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed.
+/// Allows camera eyes to stream these chunks and know what they can and cannot see.
/datum/camerachunk
- var/list/obscuredTurfs = list()
- var/list/visibleTurfs = list()
+ var/list/obscured_turfs = list()
+ var/list/visible_turfs = list()
var/list/obscured = list()
var/list/active_cameras = list()
var/list/inactive_cameras = list()
@@ -17,6 +14,7 @@
var/y = 0
var/z = 0
+/// Adds a camera to the chunk if it has not already been added.
/datum/camerachunk/proc/add_camera(obj/machinery/camera/cam)
if(active_cameras[cam] || inactive_cameras[cam])
return
@@ -32,6 +30,7 @@
else
inactive_cameras[cam] = cam
+/// Handles each movement by a camera that has been added to the chunk.
/datum/camerachunk/proc/camera_moved(obj/machinery/camera/cam, atom/old_loc)
var/turf/T = get_turf(cam)
@@ -39,6 +38,7 @@
if(T.x + CAMERA_VIEW_DISTANCE < x || T.x - CAMERA_VIEW_DISTANCE >= x + CAMERA_CHUNK_SIZE || T.y + CAMERA_VIEW_DISTANCE < y || T.y - CAMERA_VIEW_DISTANCE >= y + CAMERA_CHUNK_SIZE || T.z != z)
remove_camera(cam)
+/// Removes a camera from the chunk.
/datum/camerachunk/proc/remove_camera(obj/machinery/camera/cam)
UnregisterSignal(cam, list(COMSIG_CAMERA_OFF, COMSIG_CAMERA_ON, COMSIG_PARENT_QDELETING, COMSIG_CAMERA_MOVED))
active_cameras -= cam
@@ -55,42 +55,40 @@
active_cameras -= cam
SScamera.queue(src)
-// Add an AI eye to the chunk, then update if changed.
-/datum/camerachunk/proc/add(mob/camera/ai_eye/eye, add_images = TRUE)
+/// Add a camera eye to the chunk, then update if changed.
+/datum/camerachunk/proc/add(mob/camera/eye/eye, add_images = TRUE)
if(add_images)
- var/client/client = eye.GetViewerClient()
+ var/client/client = eye.get_viewer_client()
if(client)
client.images += obscured
- eye.visibleCameraChunks += src
+ eye.visible_camera_chunks += src
seenby += eye
- RegisterSignal(eye, COMSIG_PARENT_QDELETING, PROC_REF(aiEye_destroyed))
+ RegisterSignal(eye, COMSIG_PARENT_QDELETING, PROC_REF(eye_destroyed))
if(changed)
SScamera.queue(src)
-/datum/camerachunk/proc/aiEye_destroyed(mob/camera/ai_eye/eye)
+/datum/camerachunk/proc/eye_destroyed(mob/camera/eye/eye)
remove(eye, FALSE)
-// Remove an AI eye from the chunk, then update if changed.
-/datum/camerachunk/proc/remove(mob/camera/ai_eye/eye, remove_images = TRUE)
+/// Remove a camera eye from the chunk, then update if changed.
+/datum/camerachunk/proc/remove(mob/camera/eye/eye, remove_images = TRUE)
if(remove_images)
- var/client/client = eye.GetViewerClient()
+ var/client/client = eye.get_viewer_client()
if(client)
client.images -= obscured
- eye.visibleCameraChunks -= src
+ eye.visible_camera_chunks -= src
seenby -= eye
UnregisterSignal(eye, COMSIG_PARENT_QDELETING)
-// Called when a chunk has changed. I.E: A wall was deleted.
-
-/datum/camerachunk/proc/visibilityChanged(turf/loc)
- if(!visibleTurfs[loc])
+/// Called when a chunk has changed. I.E: A wall was deleted.
+/datum/camerachunk/proc/visibility_changed(turf/loc)
+ if(!visible_turfs[loc])
return
- hasChanged()
+ has_changed()
-// Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will
-// instead be flagged to update the next time an AI Eye moves near it.
-
-/datum/camerachunk/proc/hasChanged(update_now = 0)
+/// Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will
+/// instead be flagged to update the next time a camera eye moves near it.
+/datum/camerachunk/proc/has_changed(update_now = 0)
if(update_now)
update()
SScamera.remove_from_queue(src)
@@ -100,48 +98,48 @@
else
changed = TRUE
-// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists.
-
+/// Gathers the visible turfs from cameras and puts them into the appropiate lists.
/datum/camerachunk/proc/update()
- var/list/newVisibleTurfs = list()
+ var/list/new_visible_turfs = list()
for(var/obj/machinery/camera/c as anything in active_cameras)
var/turf/point = locate(src.x + (CAMERA_CHUNK_SIZE / 2), src.y + (CAMERA_CHUNK_SIZE / 2), src.z)
var/turf/T = get_turf(c)
if(get_dist(point, T) > CAMERA_VIEW_DISTANCE + (CAMERA_CHUNK_SIZE / 2))
- continue // Still needed for Ais who get created on Z level 1 on the spot of the new player
+ // Still needed for Ais who get created on Z level 1 on the spot of the new player
+ continue
for(var/turf/t in c.can_see())
if(turfs[t])
- newVisibleTurfs[t] = t
+ new_visible_turfs[t] = t
- var/list/visAdded = newVisibleTurfs - visibleTurfs
- var/list/visRemoved = visibleTurfs - newVisibleTurfs
+ var/list/vis_added = new_visible_turfs - visible_turfs
+ var/list/vis_removed = visible_turfs - new_visible_turfs
- visibleTurfs = newVisibleTurfs
- obscuredTurfs = turfs - newVisibleTurfs
+ visible_turfs = new_visible_turfs
+ obscured_turfs = turfs - new_visible_turfs
var/list/images_to_remove = list()
var/list/images_to_add = list()
- for(var/turf/t as anything in visAdded)
+ for(var/turf/t as anything in vis_added)
if(t.obscured)
obscured -= t.obscured
images_to_remove += t.obscured
- for(var/turf/t as anything in visRemoved)
+ for(var/turf/t as anything in vis_removed)
if(!t.obscured)
t.obscured = image('icons/effects/cameravis.dmi', t, null, BYOND_LIGHTING_LAYER + 0.1)
t.obscured.plane = BYOND_LIGHTING_PLANE + 1
obscured += t.obscured
images_to_add += t.obscured
- for(var/mob/camera/ai_eye/eye as anything in seenby)
- var/client/client = eye.GetViewerClient()
+ for(var/mob/camera/eye/eye as anything in seenby)
+ var/client/client = eye.get_viewer_client()
if(client)
client.images -= images_to_remove
client.images += images_to_add
changed = FALSE
-// Create a new camera chunk, since the chunks are made as they are needed.
+/// Create a new camera chunk, since the chunks are made as they are needed.
/datum/camerachunk/New(loc, x, y, z)
// 0xf = 15
@@ -162,11 +160,11 @@
for(var/obj/machinery/camera/c as anything in active_cameras)
for(var/turf/t in c.can_see())
if(turfs[t])
- visibleTurfs[t] = t
+ visible_turfs[t] = t
- obscuredTurfs = turfs - visibleTurfs
+ obscured_turfs = turfs - visible_turfs
- for(var/turf/t as anything in obscuredTurfs)
+ for(var/turf/t as anything in obscured_turfs)
if(!t.obscured)
t.obscured = image('icons/effects/cameravis.dmi', t, "black", BYOND_LIGHTING_LAYER + 0.1)
t.obscured.plane = BYOND_LIGHTING_PLANE + 1
diff --git a/code/modules/mob/camera/eye.dm b/code/modules/mob/camera/eye.dm
new file mode 100644
index 00000000000..2034a6c7c30
--- /dev/null
+++ b/code/modules/mob/camera/eye.dm
@@ -0,0 +1,191 @@
+/// Camera eyes are remote-control mobs that can move and see throughout the global cameranet.
+/// They're used in AI eyes, holograms, advanced camera consoles, abductor consoles, shuttle consoles,
+/// and xenobiology consoles. When created, the user with which they are initialized will be granted control,
+/// and their movements will be relayed to the camera eye instead. When destroyed, the user's control of the
+/// camera eye will be released; if they were previously remote controlling another object (such as another
+/// camera eye) then they will be put back in control of that object; otherwise they will return to their body.
+/mob/camera/eye
+ name = "Inactive Camera Eye"
+ icon = 'icons/obj/abductor.dmi'
+ icon_state = "camera_target"
+ alpha = 127
+ invisibility = SEE_INVISIBLE_OBSERVER
+
+ /// The list of camera chunks currently visible to the camera eye.
+ var/list/visible_camera_chunks = list()
+ /// The user controlling the eye.
+ var/mob/living/user
+ /// The thing that the user was previously remote controlling before this eye.
+ var/user_previous_remote_control
+ /// The object that created the eye.
+ var/origin
+ /// If true, speech near the camera eye will be relayed to its controller.
+ var/relay_speech = FALSE
+ /// Sets the camera eye visibility range; does not expand viewport, only affects cameranet obscuring
+ var/static_visibility_range = 16
+ /// Toggles whether this eye is detectable by AI Detectors.
+ var/ai_detector_visible = TRUE
+ /// Toggles whether the eye's icon should be visible to its user.
+ var/visible_icon = FALSE
+ /// The list of cameranets that this camera eye can see and access.
+ var/list/networks = list("SS13")
+ /// The in-memory image of the camera eye's icon.
+ var/image/user_image
+
+ // Camera acceleration settings
+ // Initially, the camera moves one turf per move. If there is no movement for
+ // cooldown_rate in deciseconds, the camera will reset to this movement rate.
+ // Every move otherwise increases sprint by acceleration_rate, until sprint
+ // exceeds sprint_threshold, and the movement rate increases by one per move.
+ // The movement rate is 1 + round(sprint / sprint_threshold).
+
+ /// The maximum sprint value - this caps acceleration
+ var/max_sprint = 50
+ /// The minimum sprint needed to increase base velocity
+ var/sprint_threshold = 20
+ /// The amount that sprint is increased per move
+ var/acceleration_rate = 0.5
+ /// Keeps track of acceleration - movement rate is 1 + round(sprint / sprint_threshold)
+ var/sprint = 10
+ /// The absolute time that sprint will reset to its initial value
+ var/cooldown = 0
+ /// The time after which sprint should be reset to its initial state, if no movements are made
+ var/cooldown_rate = 5
+ /// Toggles camera acceleration on or off.
+ var/acceleration = 1
+
+/mob/camera/eye/Initialize(mapload, owner_name, camera_origin, mob/living/user)
+ . = ..()
+ name = "Camera Eye ([owner_name])"
+ origin = camera_origin
+ give_control(user)
+ update_visibility()
+ refresh_visible_icon()
+ if(!validate_active_cameranet())
+ return INITIALIZE_HINT_QDEL
+
+/// Validates that there is an active cameranet. If strict is 0, does nothing.
+/// Returns 1 if there is an active cameranet. Warns the user and returns 0 if there is not.
+/mob/camera/eye/proc/validate_active_cameranet(strict = 0)
+ var/camera = first_active_camera()
+ if(strict && !camera)
+ to_chat(user, "ERROR: No linked and active camera network found.")
+ return FALSE
+ return TRUE
+
+/// Returns the turf of the first active camera in the global cameranet.
+/mob/camera/eye/proc/first_active_camera()
+ for(var/obj/machinery/camera/C in GLOB.cameranet.cameras)
+ if(!C.can_use())
+ continue
+ if(length(C.network & networks))
+ return get_turf(C)
+
+/// Updates what the global cameranet can see with respect to this eye and its user's client.
+/mob/camera/eye/proc/update_visibility()
+ GLOB.cameranet.visibility(src, user.client)
+
+/// Refreshes user_image in the user's client.images.
+/mob/camera/eye/proc/refresh_visible_icon()
+ if(visible_icon && user.client)
+ user.client.images -= user_image
+ user_image = image(icon,loc,icon_state,FLY_LAYER)
+ user.client.images += user_image
+
+/// Sets the camera eye's location to T, updates global cameranet visibility, and refreshes user_images.
+/mob/camera/eye/set_loc(T)
+ if(user)
+ T = get_turf(T)
+ ..(T)
+ update_visibility()
+ refresh_visible_icon()
+
+/// Disables independent movement by camera eyes; camera eyes must be controlled by relaymove.
+/mob/camera/eye/Move()
+ return FALSE
+
+/// If `usr` is an AI, set the camera eye's location to the location of the atom clicked.
+/atom/proc/move_camera_by_click()
+ if(is_ai(usr))
+ var/mob/living/silicon/ai/AI = usr
+ if(AI.eyeobj && (AI.client.eye == AI.eyeobj) && (AI.eyeobj.z == z))
+ AI.camera_follow = null
+ if(isturf(loc) || isturf(src))
+ AI.eyeobj.set_loc(src)
+
+/// Returns the user's client, if it exists; otherwise returns null.
+/mob/camera/eye/proc/get_viewer_client()
+ return user?.client
+
+/// Removes obscured chunk images and user_images from the user's client.images.
+/mob/camera/eye/proc/remove_images()
+ var/client/C = get_viewer_client()
+ if(!C)
+ return
+ for(var/datum/camerachunk/chunk as anything in visible_camera_chunks)
+ C.images -= chunk.obscured
+ if(visible_icon)
+ C.images -= user_image
+
+/// Calls `remove_images`, changes the user's remote control from this camera eye to `user_previous_remote_control`.
+/mob/camera/eye/proc/release_control()
+ if(!istype(user))
+ return
+ if(user.client)
+ user.reset_perspective(user.client.mob)
+ remove_images()
+ user.remote_control = null
+ if(user_previous_remote_control)
+ user.reset_perspective(user_previous_remote_control)
+ user.remote_control = user_previous_remote_control
+ user_previous_remote_control = null
+ user = null
+
+/// Forces this eye's current user to release control, renames this eye, and grants `new_user` control of this eye.
+/mob/camera/eye/proc/give_control(mob/new_user)
+ if(!istype(new_user))
+ return
+ release_control()
+ user = new_user
+ rename_camera(user.name)
+ if(istype(user.remote_control))
+ user_previous_remote_control = user.remote_control
+ user.remote_control = src
+ user.reset_perspective(src)
+
+/// Renames the camera eye (only visible in observer Orbit menu)
+/mob/camera/eye/proc/rename_camera(new_name)
+ name = "Camera Eye ([new_name])"
+
+/// Remove this eye from all chunks containing it.
+/mob/camera/eye/proc/release_chunks()
+ for(var/datum/camerachunk/chunk as anything in visible_camera_chunks)
+ chunk.remove(src)
+
+/mob/camera/eye/Destroy()
+ release_control()
+ release_chunks()
+ return ..()
+
+/// Called when the user controlling this eye attempts to move; uses camera acceleration settings.
+/mob/camera/eye/relaymove(mob/user,direct)
+ var/initial = initial(sprint)
+
+ if(cooldown && cooldown < world.timeofday)
+ sprint = initial
+
+ for(var/i in 0 to sprint step sprint_threshold)
+ var/turf/next_step= get_turf(get_step(src, direct))
+ if(next_step)
+ set_loc(next_step)
+
+ cooldown = world.timeofday + cooldown_rate
+ if(acceleration)
+ sprint = min(sprint + acceleration_rate, max_sprint)
+ else
+ sprint = initial
+
+/// If `relay_speech` is truthy, allows the camera eye's user to hear speech spoken at the eye's location.
+/mob/camera/eye/hear_say(list/message_pieces, verb = "says", italics = 0, mob/speaker = null, sound/speech_sound, sound_vol, sound_frequency, use_voice = TRUE)
+ if(relay_speech)
+ user.hear_say(message_pieces, verb, italics, speaker, speech_sound, sound_vol, sound_frequency)
diff --git a/code/modules/mob/camera/eye/abductor.dm b/code/modules/mob/camera/eye/abductor.dm
new file mode 100644
index 00000000000..3b8c531099a
--- /dev/null
+++ b/code/modules/mob/camera/eye/abductor.dm
@@ -0,0 +1,14 @@
+/mob/camera/eye/abductor
+ name = "Abductor Camera Eye"
+ ai_detector_visible = FALSE
+
+/mob/camera/eye/abductor/Initialize(mapload, owner_name, camera_origin, user)
+ ..()
+ set_loc(first_active_camera())
+
+/mob/camera/eye/abductor/rename_camera(new_name)
+ name = "Abductor Camera Eye ([new_name])"
+
+/// Requires the cameranet to be validated.
+/mob/camera/eye/abductor/validate_active_cameranet()
+ ..(TRUE)
diff --git a/code/modules/mob/camera/eye/ai_eye.dm b/code/modules/mob/camera/eye/ai_eye.dm
new file mode 100644
index 00000000000..d915f95f2fe
--- /dev/null
+++ b/code/modules/mob/camera/eye/ai_eye.dm
@@ -0,0 +1,34 @@
+/mob/camera/eye/ai
+ name = "Inactive AI Eye"
+ icon = 'icons/mob/ai.dmi'
+ icon_state = "eye"
+ var/mob/living/silicon/ai/ai = null
+
+/mob/camera/eye/ai/Initialize(mapload, owner_name, camera_origin, mob/living/user)
+ . = ..()
+ ai = user
+ if(is_ai_eye(ai.eyeobj))
+ stack_trace("Tried to create an AI Eye for [user], but there is one already assigned")
+ return INITIALIZE_HINT_QDEL
+ name = "[owner_name] (AI Eye)"
+
+/// Ensures that the user's perspective is on this eye (instead of, for example, a mech or hologram eye) and
+/// updates parallax
+/mob/camera/eye/ai/set_loc(T)
+ ..()
+ user.reset_perspective(src)
+ update_parallax_contents()
+
+/// Cancels the camera's follow target if tracking has stopped, and lights up nearby lights if the AI has
+/// "Toggle Camera Lights" enabled
+/mob/camera/eye/ai/relaymove(mob/user, direct)
+ ..()
+ if(!ai.tracking)
+ ai.camera_follow = null
+ if(ai.camera_light_on)
+ ai.light_cameras()
+
+/// Relays speech near the AI eye to the AI if the AI has surveillance, either from a malf module or a station trait
+/mob/camera/eye/ai/hear_say(list/message_pieces, verb = "says", italics = 0, mob/speaker = null, sound/speech_sound, sound_vol, sound_frequency, use_voice = TRUE)
+ if(relay_speech)
+ ai.relay_speech(speaker, message_pieces, verb)
diff --git a/code/modules/mob/camera/eye/hologram_eye.dm b/code/modules/mob/camera/eye/hologram_eye.dm
new file mode 100644
index 00000000000..a30c63827a9
--- /dev/null
+++ b/code/modules/mob/camera/eye/hologram_eye.dm
@@ -0,0 +1,53 @@
+/mob/camera/eye/hologram
+ name = "Inactive Hologram Eye"
+ ai_detector_visible = FALSE
+ acceleration = FALSE
+ relay_speech = TRUE
+ var/obj/machinery/hologram/holopad/holopad
+
+/mob/camera/eye/hologram/Initialize(mapload, owner_name, camera_origin, mob/living/user)
+ ..()
+ holopad = camera_origin
+ set_loc(holopad)
+
+/mob/camera/eye/hologram/rename_camera(new_name)
+ name = "Hologram ([new_name])"
+
+/// Hologram movement copies the delays and diagonal delays of regular mob movement
+/// for crew, and for AI unless fast holograms are enabled
+/mob/camera/eye/hologram/relaymove(mob/user, direct)
+ var/mob/living/silicon/ai/ai = user
+ if(istype(ai) && ai.fast_holograms)
+ return ..()
+ var/turf/new_location = get_turf(get_step(src, direct))
+ if(new_location.z != z || get_dist(new_location, src) > 1)
+ return
+ var/base_delay = GLOB.configuration.movement.base_run_speed
+ var/diag_delay = base_delay * SQRT_2
+ var/delay = (direct & (direct - 1)) ? diag_delay : base_delay
+ user.client.move_delay = debounced_move(normalized_delay_speed(delay))
+ user.last_movement = world.time
+ set_loc(new_location)
+
+/mob/camera/eye/hologram/proc/debounced_move(delay_speed)
+ var/old_move_delay = user.client.move_delay
+ if(old_move_delay + world.tick_lag > world.time)
+ return old_move_delay + delay_speed
+ else
+ return world.time + delay_speed
+
+/mob/camera/eye/hologram/proc/normalized_delay_speed(delay_speed)
+ return TICKS2DS(-round(-(DS2TICKS(delay_speed))))
+
+/// Requires the cameranet to be validated.
+/mob/camera/eye/hologram/validate_active_cameranet()
+ ..(TRUE)
+
+/// Moves the associated hologram, and the previously controlled object (probably an AI eye), to the new location.
+/mob/camera/eye/hologram/set_loc(T)
+ . = ..()
+ var/turf/new_location = get_turf(T)
+ holopad.move_hologram(user, new_location)
+ var/mob/camera/eye/previous_eye = user_previous_remote_control
+ if(istype(previous_eye))
+ previous_eye.set_loc(new_location)
diff --git a/code/modules/mob/camera/eye/shuttle_navigator.dm b/code/modules/mob/camera/eye/shuttle_navigator.dm
new file mode 100644
index 00000000000..6e80fbc2ee4
--- /dev/null
+++ b/code/modules/mob/camera/eye/shuttle_navigator.dm
@@ -0,0 +1,30 @@
+/mob/camera/eye/shuttle_docker
+ name = "Shuttle Docker Camera Eye"
+ ai_detector_visible = FALSE
+ simulated = FALSE
+ var/list/placement_images = list()
+ var/list/placed_images = list()
+
+/mob/camera/eye/shuttle_docker/Initialize(mapload, owner_name, camera_origin, mob/living/user)
+ ..()
+ set_loc(first_active_camera())
+
+/mob/camera/eye/shuttle_docker/rename_camera(new_name)
+ name = "Shuttle Docker Camera Eye ([new_name])"
+
+/// Prevents the shuttle docker eye from updating global cameranet chunks. Shuttle dockers don't use station cameras.
+/mob/camera/eye/shuttle_docker/update_visibility()
+ return FALSE
+
+/// Prevents moving the camera eye into the station, and updates the current location's landing spot validity.
+/mob/camera/eye/shuttle_docker/set_loc(T)
+ if(isspaceturf(get_turf(T)) || istype(get_area(T), /area/space) || istype(get_area(T), /area/shuttle))
+ ..()
+ var/obj/machinery/computer/camera_advanced/shuttle_docker/console = origin
+ console.check_landing_spot()
+
+/mob/camera/eye/shuttle_docker/update_remote_sight(mob/living/user)
+ user.sight = SEE_TURFS
+
+ ..()
+ return TRUE
diff --git a/code/modules/mob/camera/eye/syndicate.dm b/code/modules/mob/camera/eye/syndicate.dm
new file mode 100644
index 00000000000..47fa732f81f
--- /dev/null
+++ b/code/modules/mob/camera/eye/syndicate.dm
@@ -0,0 +1,10 @@
+/mob/camera/eye/syndicate
+ name = "Syndicate Researcher Camera Eye"
+ ai_detector_visible = FALSE
+
+/mob/camera/eye/syndicate/Initialize(mapload, owner_name, camera_origin, user)
+ ..()
+ set_loc(first_active_camera())
+
+/mob/camera/eye/syndicate/rename_camera(new_name)
+ name = "Syndicate Researcher Camera Eye ([new_name])"
diff --git a/code/modules/mob/camera/eye/xenobio_eye.dm b/code/modules/mob/camera/eye/xenobio_eye.dm
new file mode 100644
index 00000000000..2e2bef7e710
--- /dev/null
+++ b/code/modules/mob/camera/eye/xenobio_eye.dm
@@ -0,0 +1,22 @@
+/mob/camera/eye/xenobio
+ name = "Xenobiology Console Camera Eye"
+ visible_icon = TRUE
+ ai_detector_visible = FALSE
+ var/allowed_area
+
+/mob/camera/eye/xenobio/Initialize(mapload, owner_name, camera_origin, mob/living/user)
+ . = ..()
+ var/area/A = get_area(camera_origin)
+ allowed_area = A.name
+
+/mob/camera/eye/xenobio/rename_camera(new_name)
+ name = "Xenobiology Console ([new_name])"
+
+/// Prevents the camera eye from going outside of the xenobiology area
+/mob/camera/eye/xenobio/set_loc(T)
+ var/area/new_area = get_area(T)
+ if(!new_area)
+ return
+ if(new_area.name != allowed_area && !new_area.xenobiology_compatible)
+ return
+ return ..()
diff --git a/code/modules/mob/dead/observer/observer_base.dm b/code/modules/mob/dead/observer/observer_base.dm
index 59159c638f8..d7d10ee753d 100644
--- a/code/modules/mob/dead/observer/observer_base.dm
+++ b/code/modules/mob/dead/observer/observer_base.dm
@@ -255,7 +255,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
warningmsg = "You have committed suicide too early in the round"
else if(stat != DEAD)
warningmsg = "You are alive"
- if(isAI(src))
+ if(is_ai(src))
warningmsg = "You are a living AI! You should probably use OOC -> Wipe Core instead."
else if(GLOB.non_respawnable_keys[ckey])
warningmsg = "You have lost your right to respawn"
@@ -656,7 +656,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/proc/ghost_follow_link(atom/target, atom/ghost)
if((!target) || (!ghost)) return
- if(isAI(target)) // AI core/eye follow links
+ if(is_ai(target)) // AI core/eye follow links
var/mob/living/silicon/ai/A = target
. = "core"
if(A.client && A.eyeobj) // No point following clientless AI eyes
diff --git a/code/modules/mob/dead/observer/observer_say.dm b/code/modules/mob/dead/observer/observer_say.dm
index 0f86ba90898..79e01aeae49 100644
--- a/code/modules/mob/dead/observer/observer_say.dm
+++ b/code/modules/mob/dead/observer/observer_say.dm
@@ -17,7 +17,7 @@
if(!speaker || !ismob(speaker))
return speaker_name
var/mob/speaker_mob = speaker
- if(isAI(speaker_mob))
+ if(is_ai(speaker_mob))
//AI's can't pretend to be other mobs.
return speaker_name
if(!check_name_against || check_name_against == speaker_mob.real_name)
diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm
index 1de7157c975..98bd00372f3 100644
--- a/code/modules/mob/language.dm
+++ b/code/modules/mob/language.dm
@@ -624,7 +624,7 @@
continue
else if(drone_only && !isdrone(S))
continue
- else if(isAI(S))
+ else if(is_ai(S))
message_start = list("[name], [speaker.name]")
else if(isrobot(S))
var/mob/living/silicon/robot/borg = S
diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm
index 0dd5b93626a..3ac09b57112 100644
--- a/code/modules/mob/living/carbon/examine.dm
+++ b/code/modules/mob/living/carbon/examine.dm
@@ -364,7 +364,7 @@
return (hudtype in have_hudtypes)
- else if(isrobot(M) || isAI(M)) //Stand-in/Stopgap to prevent pAIs from freely altering records, pending a more advanced Records system
+ else if(isrobot(M) || is_ai(M)) //Stand-in/Stopgap to prevent pAIs from freely altering records, pending a more advanced Records system
return (hudtype in list(EXAMINE_HUD_SECURITY_READ, EXAMINE_HUD_SECURITY_WRITE, EXAMINE_HUD_MEDICAL_READ, EXAMINE_HUD_MEDICAL_WRITE))
else if(isobserver(M))
diff --git a/code/modules/mob/living/carbon/human/human_mob.dm b/code/modules/mob/living/carbon/human/human_mob.dm
index ebe84b02116..26a3e275b2d 100644
--- a/code/modules/mob/living/carbon/human/human_mob.dm
+++ b/code/modules/mob/living/carbon/human/human_mob.dm
@@ -723,7 +723,7 @@
else if(isrobot(user))
var/mob/living/silicon/robot/U = user
rank = "[U.modtype] [U.braintype]"
- else if(isAI(user))
+ else if(is_ai(user))
rank = "AI"
set_criminal_status(user, found_record, new_status, reason, rank)
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index db2fa4914bd..e85da8a348a 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -30,7 +30,7 @@
var/now_pushing = null
- var/atom/movable/cameraFollow = null
+ var/atom/movable/camera_follow = null
var/on_fire = 0 //The "Are we on fire?" var
var/fire_stacks = 0 //Tracks how many stacks of fire we have on, max is usually 20
diff --git a/code/modules/mob/living/silicon/ai/ai_death.dm b/code/modules/mob/living/silicon/ai/ai_death.dm
index 6f170c292f1..b2dbf6e8bda 100644
--- a/code/modules/mob/living/silicon/ai/ai_death.dm
+++ b/code/modules/mob/living/silicon/ai/ai_death.dm
@@ -10,7 +10,7 @@
else
icon_state = "ai_dead"
if(eyeobj)
- eyeobj.setLoc(get_turf(src))
+ eyeobj.set_loc(get_turf(src))
GLOB.shuttle_caller_list -= src
SSshuttle.autoEvac()
diff --git a/code/modules/mob/living/silicon/ai/ai_life.dm b/code/modules/mob/living/silicon/ai/ai_life.dm
index abf0b4e9452..3ba153e83e9 100644
--- a/code/modules/mob/living/silicon/ai/ai_life.dm
+++ b/code/modules/mob/living/silicon/ai/ai_life.dm
@@ -10,7 +10,7 @@
var/turf/T = get_turf(src)
if(stat != CONSCIOUS) //ai's fucked
- cameraFollow = null
+ camera_follow = null
reset_perspective(null)
unset_machine()
diff --git a/code/modules/mob/living/silicon/ai/ai_mob.dm b/code/modules/mob/living/silicon/ai/ai_mob.dm
index 33a071912f7..77504341b2c 100644
--- a/code/modules/mob/living/silicon/ai/ai_mob.dm
+++ b/code/modules/mob/living/silicon/ai/ai_mob.dm
@@ -14,6 +14,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
/mob/living/silicon/ai/proc/pick_icon,
/mob/living/silicon/ai/proc/sensor_mode,
/mob/living/silicon/ai/proc/show_laws_verb,
+ /mob/living/silicon/ai/proc/toggle_fast_holograms,
/mob/living/silicon/ai/proc/toggle_acceleration,
/mob/living/silicon/ai/proc/toggle_camera_light,
/mob/living/silicon/ai/proc/botcall,
@@ -104,10 +105,8 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
var/obj/machinery/doomsday_device/doomsday_device
var/obj/machinery/hologram/holopad/holo = null
- var/mob/camera/ai_eye/eyeobj
- var/sprint = 10
- var/cooldown = 0
- var/acceleration = 1
+ var/mob/camera/eye/ai/eyeobj
+ var/fast_holograms = TRUE
var/tracking = FALSE //this is 1 if the AI is currently tracking somebody, but the track has not yet been completed.
/// If true, this AI core can use the teleporter.
@@ -121,7 +120,6 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
var/announce_arrivals = TRUE
var/arrivalmsg = "$name, $rank, has arrived on the station."
- var/list/all_eyes = list()
var/next_text_announcement
//Used with the hotkeys on 2-5 to store locations.
@@ -228,8 +226,8 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
spawn(5)
new /obj/machinery/ai_powersupply(src)
-
- create_eye()
+
+ eyeobj = new /mob/camera/eye/ai(loc, name, src, src)
builtInCamera = new /obj/machinery/camera/portable(src)
builtInCamera.c_tag = name
@@ -769,7 +767,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
if(controlled_mech)
to_chat(src, "You are already loaded into an onboard computer!")
return
- if(!GLOB.cameranet.checkCameraVis(M))
+ if(!GLOB.cameranet.check_camera_vis(M))
to_chat(src, "Exosuit is no longer near active cameras.")
return
if(lacks_power())
@@ -826,7 +824,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
//The target must be in view of a camera or near the core.
if(turf_check in range(get_turf(src)))
call_bot(turf_check)
- else if(GLOB.cameranet && GLOB.cameranet.checkTurfVis(turf_check))
+ else if(GLOB.cameranet && GLOB.cameranet.check_turf_vis(turf_check))
call_bot(turf_check)
else
to_chat(src, "Selected location is not visible.")
@@ -882,7 +880,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
/mob/living/silicon/ai/proc/switchCamera(obj/machinery/camera/C)
if(!tracking)
- cameraFollow = null
+ camera_follow = null
if(QDELETED(C) || stat == DEAD) //C.can_use())
return FALSE
@@ -891,7 +889,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
view_core()
return
// ok, we're alive, camera is good and in our network...
- eyeobj.setLoc(get_turf(C))
+ eyeobj.set_loc(get_turf(C))
//machine = src
return TRUE
@@ -939,7 +937,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
if(!C.can_use())
continue
if(network in C.network)
- U.eyeobj.setLoc(get_turf(C))
+ U.eyeobj.set_loc(get_turf(C))
break
to_chat(src, "Switched to [network] camera network.")
//End of code by Mord_Sith
@@ -1238,7 +1236,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
var/list/obj/machinery/camera/add = list()
var/list/obj/machinery/camera/remove = list()
var/list/obj/machinery/camera/visible = list()
- for(var/datum/camerachunk/CC in eyeobj.visibleCameraChunks)
+ for(var/datum/camerachunk/CC in eyeobj.visible_camera_chunks)
for(var/obj/machinery/camera/C in CC.active_cameras)
if(!C.can_use() || get_dist(C, eyeobj) > 7)
continue
@@ -1340,7 +1338,7 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
//get_turf_pixel() is because APCs in maint aren't actually in view of the inner camera
//apc_override is needed here because AIs use their own APC when depowered
var/turf/T = isturf(A) ? A : get_turf_pixel(A)
- return (GLOB.cameranet && GLOB.cameranet.checkTurfVis(T)) || apc_override
+ return (GLOB.cameranet && GLOB.cameranet.check_turf_vis(T)) || apc_override
//AI is carded/shunted
//view(src) returns nothing for carded/shunted AIs and they have x-ray vision so just use get_dist
var/list/viewscale = getviewsize(client.view)
@@ -1433,8 +1431,45 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
else
to_chat(src, "Target is not on or near any active cameras on the station.")
-/mob/living/silicon/ai/proc/camera_visibility(mob/camera/ai_eye/moved_eye)
- GLOB.cameranet.visibility(moved_eye, client, all_eyes)
+// Return to the Core.
+/mob/living/silicon/ai/proc/core()
+ set category = "AI Commands"
+ set name = "AI Core"
+
+ view_core()
+
+/mob/living/silicon/ai/proc/view_core()
+
+ current = null
+ camera_follow = null
+ unset_machine()
+
+ if(eyeobj && loc)
+ eyeobj.loc = loc
+ else
+ to_chat(src, "ERROR: Eyeobj not found. Creating new eye...")
+ eyeobj = new /mob/camera/eye/ai(loc, name, src, src)
+
+ eyeobj.set_loc(loc)
+
+/mob/living/silicon/ai/proc/toggle_fast_holograms()
+ set category = "AI Commands"
+ set name = "Toggle Fast Holograms"
+
+ if(usr.stat == DEAD || !is_ai_eye(eyeobj))
+ return
+ fast_holograms = !fast_holograms
+ to_chat(usr, "Fast holograms have been toggled [fast_holograms ? "on" : "off"].")
+
+/mob/living/silicon/ai/proc/toggle_acceleration()
+ set category = "AI Commands"
+ set name = "Toggle Camera Acceleration"
+
+ if(usr.stat == DEAD)
+ return //won't work if dead
+ if(is_ai_eye(eyeobj))
+ eyeobj.acceleration = !eyeobj.acceleration
+ to_chat(usr, "Camera acceleration has been toggled [eyeobj.acceleration ? "on" : "off"].")
/mob/living/silicon/ai/handle_fire()
return
diff --git a/code/modules/mob/living/silicon/ai/ai_say.dm b/code/modules/mob/living/silicon/ai/ai_say.dm
index 1e676eb05a3..ebcec382ef4 100644
--- a/code/modules/mob/living/silicon/ai/ai_say.dm
+++ b/code/modules/mob/living/silicon/ai/ai_say.dm
@@ -28,7 +28,7 @@
else if(iscarbon(speaker)) // Nonhuman carbon mob
jobname = "No ID"
- else if(isAI(speaker))
+ else if(is_ai(speaker))
jobname = "AI"
else if(isrobot(speaker))
jobname = "Cyborg"
diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm
deleted file mode 100644
index c98203ef2bd..00000000000
--- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm
+++ /dev/null
@@ -1,177 +0,0 @@
-// CAMERA NET
-//
-// The datum containing all the chunks.
-GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new())
-
-/datum/cameranet
- var/name = "Camera Net" // Name to show for VV and stat()
-
- // The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Destroy().
- var/list/cameras = list()
- // The chunks of the map, mapping the areas that the cameras can see.
- var/list/chunks = list()
- var/ready = FALSE
-
-// Checks if a chunk has been Generated in x, y, z.
-/datum/cameranet/proc/chunkGenerated(x, y, z)
- x &= ~(CAMERA_CHUNK_SIZE - 1)
- y &= ~(CAMERA_CHUNK_SIZE - 1)
- var/key = "[x],[y],[z]"
- return (chunks[key])
-
-// Returns the chunk in the x, y, z.
-// If there is no chunk, it creates a new chunk and returns that.
-/datum/cameranet/proc/getCameraChunk(x, y, z)
- x &= ~(CAMERA_CHUNK_SIZE - 1)
- y &= ~(CAMERA_CHUNK_SIZE - 1)
- var/key = "[x],[y],[z]"
- if(!chunks[key])
- chunks[key] = new /datum/camerachunk(null, x, y, z)
-
- return chunks[key]
-
-// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set.
-
-/datum/cameranet/proc/visibility(list/moved_eyes, client/C, list/other_eyes)
- if(!islist(moved_eyes))
- moved_eyes = moved_eyes ? list(moved_eyes) : list()
- if(islist(other_eyes))
- other_eyes = (other_eyes - moved_eyes)
- else
- other_eyes = list()
-
- var/list/chunks_pre_seen = list()
- var/list/chunks_post_seen = list()
-
- for(var/V in moved_eyes)
- var/mob/camera/ai_eye/eye = V
- if(C)
- chunks_pre_seen |= eye.visibleCameraChunks
- // 0xf = 15
- var/static_range = eye.static_visibility_range
- var/x1 = max(0, eye.x - static_range) & ~(CAMERA_CHUNK_SIZE - 1)
- var/y1 = max(0, eye.y - static_range) & ~(CAMERA_CHUNK_SIZE - 1)
- var/x2 = min(world.maxx, eye.x + static_range) & ~(CAMERA_CHUNK_SIZE - 1)
- var/y2 = min(world.maxy, eye.y + static_range) & ~(CAMERA_CHUNK_SIZE - 1)
-
- var/list/visibleChunks = list()
-
- for(var/x = x1; x <= x2; x += CAMERA_CHUNK_SIZE)
- for(var/y = y1; y <= y2; y += CAMERA_CHUNK_SIZE)
- visibleChunks |= getCameraChunk(x, y, eye.z)
-
- var/list/remove = eye.visibleCameraChunks - visibleChunks
- var/list/add = visibleChunks - eye.visibleCameraChunks
-
- for(var/chunk in remove)
- var/datum/camerachunk/c = chunk
- c.remove(eye, FALSE)
-
- for(var/chunk in add)
- var/datum/camerachunk/c = chunk
- c.add(eye, FALSE)
-
- if(C)
- chunks_post_seen |= eye.visibleCameraChunks
-
- if(C)
- for(var/V in other_eyes)
- var/mob/camera/ai_eye/eye = V
- chunks_post_seen |= eye.visibleCameraChunks
-
- var/list/remove = chunks_pre_seen - chunks_post_seen
- var/list/add = chunks_post_seen - chunks_pre_seen
-
- for(var/chunk in remove)
- var/datum/camerachunk/c = chunk
- C.images -= c.obscured
-
- for(var/chunk in add)
- var/datum/camerachunk/c = chunk
- C.images += c.obscured
-
-
-// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open.
-
-/datum/cameranet/proc/updateVisibility(atom/A, opacity_check = 1)
-
- if(!SSticker || (opacity_check && !A.opacity))
- return
- majorChunkChange(A, 2)
-
-/datum/cameranet/proc/updateChunk(x, y, z)
- // 0xf = 15
- if(!chunkGenerated(x, y, z))
- return
- var/datum/camerachunk/chunk = getCameraChunk(x, y, z)
- chunk.hasChanged()
-
-// Removes a camera from a chunk.
-
-/datum/cameranet/proc/removeCamera(obj/machinery/camera/c)
- majorChunkChange(c, 0)
-
-// Add a camera to a chunk.
-
-/datum/cameranet/proc/addCamera(obj/machinery/camera/c)
- majorChunkChange(c, 1)
-
-// Used for Cyborg cameras. Since portable cameras can be in ANY chunk.
-
-/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/c, turf/old_loc)
- majorChunkChange(c, 1, old_loc)
-
-// Never access this proc directly!!!!
-// This will update the chunk and all the surrounding chunks.
-// It will also add the atom to the cameras list if you set the choice to 1.
-// Setting the choice to 0 will remove the camera from the chunks.
-// If you want to update the chunks around an object, without adding/removing a camera, use choice 2.
-
-/datum/cameranet/proc/majorChunkChange(atom/c, choice, turf/old_loc = null)
- // 0xf = 15
- if(!c)
- return
-
- var/turf/T = get_turf(c)
- if(!T)
- return
-
- if(old_loc)
- // Check if the current turf falls in the same chunka as the old_loc. If so, don't do anything
- if(T.x & ~(CAMERA_CHUNK_SIZE - 1) == old_loc.x & ~(CAMERA_CHUNK_SIZE - 1) && T.y & ~(CAMERA_CHUNK_SIZE - 1) == old_loc.y & ~(CAMERA_CHUNK_SIZE - 1))
- return
-
- // Use camera view distance here to actually know how far a camera can max watch
- var/x1 = max(0, T.x - CAMERA_VIEW_DISTANCE) & ~(CAMERA_CHUNK_SIZE - 1)
- var/y1 = max(0, T.y - CAMERA_VIEW_DISTANCE) & ~(CAMERA_CHUNK_SIZE - 1)
- var/x2 = min(world.maxx, T.x + CAMERA_VIEW_DISTANCE) & ~(CAMERA_CHUNK_SIZE - 1)
- var/y2 = min(world.maxy, T.y + CAMERA_VIEW_DISTANCE) & ~(CAMERA_CHUNK_SIZE - 1)
-
- for(var/x = x1; x <= x2; x += CAMERA_CHUNK_SIZE)
- for(var/y = y1; y <= y2; y += CAMERA_CHUNK_SIZE)
- if(chunkGenerated(x, y, T.z))
- var/datum/camerachunk/chunk = getCameraChunk(x, y, T.z)
- if(choice == 0)
- // Remove the camera.
- chunk.remove_camera(c)
- else if(choice == 1)
- // You can't have the same camera in the list twice.
- chunk.add_camera(c)
- chunk.hasChanged()
-
-// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0.
-
-/datum/cameranet/proc/checkCameraVis(mob/living/target as mob)
-
- // 0xf = 15
- var/turf/position = get_turf(target)
- return checkTurfVis(position)
-
-/datum/cameranet/proc/checkTurfVis(turf/position)
- var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z)
- if(chunk)
- if(chunk.changed)
- chunk.hasChanged(1) // Update now, no matter if it's visible or not.
- if(chunk.visibleTurfs[position])
- return 1
- return 0
diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm
deleted file mode 100644
index e4219d090d1..00000000000
--- a/code/modules/mob/living/silicon/ai/freelook/eye.dm
+++ /dev/null
@@ -1,155 +0,0 @@
-// AI EYE
-//
-// An invisible (no icon) mob that the AI controls to look around the station with.
-// It streams chunks as it moves around, which will show it what the AI can and cannot see.
-
-/mob/camera/ai_eye
- name = "Inactive AI Eye"
-
- icon = 'icons/mob/ai.dmi' //Allows ghosts to see what the AI is looking at.
- icon_state = "eye"
- alpha = 127
- invisibility = SEE_INVISIBLE_OBSERVER
-
- var/list/visibleCameraChunks = list()
- var/mob/living/silicon/ai/ai = null
- var/relay_speech = FALSE
- var/use_static = TRUE
- var/static_visibility_range = 16
- // Decides if it is shown by AI Detector or not
- var/ai_detector_visible = TRUE
-
-
-// Use this when setting the aiEye's location.
-// It will also stream the chunk that the new loc is in.
-
-/mob/camera/ai_eye/setLoc(T)
- if(ai)
- if(!isturf(ai.loc))
- return
- T = get_turf(T)
- ..(T)
- if(use_static)
- ai.camera_visibility(src)
- if(ai.client)
- ai.client.eye = src
- update_parallax_contents()
- //Holopad
- if(istype(ai.current, /obj/machinery/hologram/holopad))
- var/obj/machinery/hologram/holopad/H = ai.current
- H.move_hologram(ai, T)
-
-/mob/camera/ai_eye/Move()
- return 0
-
-/mob/camera/ai_eye/Process_Spacemove(movement_dir)
- // Nothing in space can stop us from moving.
- return 1
-
-/mob/camera/ai_eye/proc/GetViewerClient()
- if(ai)
- return ai.client
- return null
-
-/mob/camera/ai_eye/proc/RemoveImages()
- var/client/C = GetViewerClient()
- if(C && use_static)
- for(var/V in visibleCameraChunks)
- var/datum/camerachunk/chunk = V
- C.images -= chunk.obscured
-
-/mob/camera/ai_eye/Destroy()
- if(ai)
- ai.all_eyes -= src
- ai = null
- for(var/V in visibleCameraChunks)
- var/datum/camerachunk/chunk = V
- chunk.remove(src)
- return ..()
-
-/atom/proc/move_camera_by_click()
- if(isAI(usr))
- var/mob/living/silicon/ai/AI = usr
- if(AI.eyeobj && (AI.client.eye == AI.eyeobj) && (AI.eyeobj.z == z))
- AI.cameraFollow = null
- if(isturf(loc) || isturf(src))
- AI.eyeobj.setLoc(src)
-
-// AI MOVEMENT
-
-// This will move the AIEye. It will also cause lights near the eye to light up, if toggled.
-// This is handled in the proc below this one.
-
-/client/proc/AIMove(n, direct, mob/living/silicon/ai/user)
-
- var/initial = initial(user.sprint)
- var/max_sprint = 50
-
- if(user.cooldown && user.cooldown < world.timeofday) // 3 seconds
- user.sprint = initial
-
- for(var/i = 0; i < max(user.sprint, initial); i += 20)
- var/turf/step = get_turf(get_step(user.eyeobj, direct))
- if(step)
- user.eyeobj.setLoc(step)
-
- user.cooldown = world.timeofday + 5
- if(user.acceleration)
- user.sprint = min(user.sprint + 0.5, max_sprint)
- else
- user.sprint = initial
-
- if(!user.tracking)
- user.cameraFollow = null
-
- //user.unset_machine() //Uncomment this if it causes problems.
- //user.lightNearbyCamera()
- if(user.camera_light_on)
- user.light_cameras()
-
-// Return to the Core.
-/mob/living/silicon/ai/proc/core()
- set category = "AI Commands"
- set name = "AI Core"
-
- view_core()
-
-/mob/living/silicon/ai/proc/view_core()
-
- current = null
- cameraFollow = null
- unset_machine()
-
- if(src.eyeobj && src.loc)
- src.eyeobj.loc = src.loc
- else
- to_chat(src, "ERROR: Eyeobj not found. Creating new eye...")
- create_eye()
-
- eyeobj.setLoc(loc)
-
-/mob/living/silicon/ai/proc/create_eye()
- if(eyeobj)
- return
- eyeobj = new /mob/camera/ai_eye()
- all_eyes += eyeobj
- eyeobj.ai = src
- eyeobj.setLoc(loc)
- eyeobj.name = "[name] (AI Eye)"
-
-/mob/living/silicon/ai/proc/toggle_acceleration()
- set category = "AI Commands"
- set name = "Toggle Camera Acceleration"
-
- if(usr.stat == DEAD)
- return //won't work if dead
- acceleration = !acceleration
- to_chat(usr, "Camera acceleration has been toggled [acceleration ? "on" : "off"].")
-
-/mob/camera/ai_eye/hear_say(list/message_pieces, verb = "says", italics = 0, mob/speaker = null, sound/speech_sound, sound_vol, sound_frequency, use_voice = TRUE)
- if(relay_speech)
- if(istype(ai))
- ai.relay_speech(speaker, message_pieces, verb)
- else
- var/mob/M = ai
- M.hear_say(message_pieces, verb, italics, speaker, speech_sound, sound_vol, sound_frequency)
diff --git a/code/modules/mob/living/silicon/robot/robot_mob.dm b/code/modules/mob/living/silicon/robot/robot_mob.dm
index 1695045530a..4b49a4010b1 100644
--- a/code/modules/mob/living/silicon/robot/robot_mob.dm
+++ b/code/modules/mob/living/silicon/robot/robot_mob.dm
@@ -1424,7 +1424,7 @@ GLOBAL_LIST_INIT(robot_verbs_default, list(
. = ..()
if(camera && last_camera_update + CAMERA_UPDATE_COOLDOWN < world.time)
last_camera_update = world.time
- GLOB.cameranet.updatePortableCamera(camera, OldLoc)
+ GLOB.cameranet.update_portable_camera(camera, OldLoc)
SEND_SIGNAL(camera, COMSIG_CAMERA_MOVED, OldLoc)
#undef CAMERA_UPDATE_COOLDOWN
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 6cc28544343..f6ada6c5994 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -805,8 +805,8 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \
reset_perspective(null)
unset_machine()
if(isliving(src))
- if(src:cameraFollow)
- src:cameraFollow = null
+ if(src:camera_follow)
+ src:camera_follow = null
/mob/Topic(href, href_list)
if(href_list["flavor_more"])
diff --git a/code/modules/mob/mob_misc_procs.dm b/code/modules/mob/mob_misc_procs.dm
index a9d99cfb3f0..9ffcbc99bc4 100644
--- a/code/modules/mob/mob_misc_procs.dm
+++ b/code/modules/mob/mob_misc_procs.dm
@@ -461,7 +461,7 @@
if(hud_used && hud_used.action_intent)
hud_used.action_intent.icon_state = "[a_intent]"
- else if(isrobot(src) || islarva(src) || isanimal(src) || isAI(src))
+ else if(isrobot(src) || islarva(src) || isanimal(src) || is_ai(src))
switch(input)
if(INTENT_HELP)
a_intent = INTENT_HELP
@@ -511,7 +511,7 @@
var/obj/item/multitool/P
if(isrobot(user) || ishuman(user))
P = user.get_active_hand()
- else if(isAI(user))
+ else if(is_ai(user))
var/mob/living/silicon/ai/AI=user
P = AI.aiMulti
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 6f1cd194d7f..80254530dca 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -91,12 +91,17 @@
if(mob.remote_control) //we're controlling something, our movement is relayed to it
return mob.remote_control.relaymove(mob, direct)
- if(isAI(mob))
- if(istype(mob.loc, /obj/item/aicard))
- var/obj/O = mob.loc
- return O.relaymove(mob, direct) // aicards have special relaymove stuff
- return AIMove(n, direct, mob)
-
+ if(is_ai(mob))
+ var/mob/living/silicon/ai/ai = mob
+ var/mob/camera/eye/ai/eye = ai.eyeobj
+ if(istype(eye) && !istype(ai.remote_control))
+ ai.remote_control = eye
+ return eye.relaymove(mob, direct)
+ if(!istype(eye) && !istype(mob.loc, /obj/item/aicard))
+ eye = new /mob/camera/eye/ai(mob.loc, ai.name, ai, ai)
+ if(istype(eye))
+ return eye.relaymove(mob, direct)
+ return FALSE // If the AI is outside of its eye or a mech (e.g. carded), it can't move
if(Process_Grab())
return
diff --git a/code/modules/mob/mob_say_base.dm b/code/modules/mob/mob_say_base.dm
index ddb279e0ac9..c3bc723c4d3 100644
--- a/code/modules/mob/mob_say_base.dm
+++ b/code/modules/mob/mob_say_base.dm
@@ -89,7 +89,7 @@
var/mob/other_mob = other
if(other_mob.universal_speak)
return TRUE
- if(isAI(src) && ispAI(other_mob))
+ if(is_ai(src) && ispAI(other_mob))
return TRUE
if(istype(other_mob, src.type) || istype(src, other_mob.type))
return TRUE
diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm
index 4c9ab5822db..0ddea1a79e2 100644
--- a/code/modules/paperwork/photocopier.dm
+++ b/code/modules/paperwork/photocopier.dm
@@ -525,7 +525,7 @@
toner = 0
/obj/machinery/photocopier/MouseDrop_T(mob/target, mob/living/user)
- if(!istype(target) || target.buckled || get_dist(user, src) > 1 || get_dist(user, target) > 1 || user.stat || isAI(user) || target.move_resist > user.pull_force)
+ if(!istype(target) || target.buckled || get_dist(user, src) > 1 || get_dist(user, target) > 1 || user.stat || is_ai(user) || target.move_resist > user.pull_force)
return
if(check_mob()) //is target mob or another mob on this photocopier already?
return
diff --git a/code/modules/paperwork/silicon_photography.dm b/code/modules/paperwork/silicon_photography.dm
index dedde0f789f..f8180ef4a5a 100644
--- a/code/modules/paperwork/silicon_photography.dm
+++ b/code/modules/paperwork/silicon_photography.dm
@@ -165,7 +165,7 @@
deletepicture(src)
/obj/item/camera/siliconcam/proc/getsource()
- if(isAI(loc))
+ if(is_ai(loc))
return src
var/mob/living/silicon/robot/C = loc
diff --git a/code/modules/power/apc/apc.dm b/code/modules/power/apc/apc.dm
index 6552d232ce6..ffb063c52d4 100644
--- a/code/modules/power/apc/apc.dm
+++ b/code/modules/power/apc/apc.dm
@@ -518,7 +518,7 @@
/obj/machinery/power/apc/proc/is_authenticated(mob/user as mob)
if(user.can_admin_interact())
return TRUE
- if(isAI(user) || isrobot(user) || user.has_unlimited_silicon_privilege)
+ if(is_ai(user) || isrobot(user) || user.has_unlimited_silicon_privilege)
return TRUE
else
return !locked
@@ -526,7 +526,7 @@
/obj/machinery/power/apc/proc/is_locked(mob/user as mob)
if(user.can_admin_interact())
return FALSE
- if(isAI(user) || isrobot(user) || user.has_unlimited_silicon_privilege)
+ if(is_ai(user) || isrobot(user) || user.has_unlimited_silicon_privilege)
return FALSE
else
return locked
diff --git a/code/modules/power/generators/portable generators/pacman.dm b/code/modules/power/generators/portable generators/pacman.dm
index f350c7bf8a1..12705003760 100644
--- a/code/modules/power/generators/portable generators/pacman.dm
+++ b/code/modules/power/generators/portable generators/pacman.dm
@@ -263,7 +263,7 @@
var/list/data = list()
data["active"] = active
- if(isAI(user))
+ if(is_ai(user))
data["is_ai"] = TRUE
else if(isrobot(user) && !Adjacent(user))
data["is_ai"] = TRUE
diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm
index 86ff7958f7a..59e51c611ac 100644
--- a/code/modules/projectiles/projectile/beams.dm
+++ b/code/modules/projectiles/projectile/beams.dm
@@ -52,7 +52,7 @@
impact_light_color_override = LIGHT_COLOR_DARKRED
/obj/item/projectile/beam/laser/ai_turret/prehit(atom/target)
- if(isAI(target))
+ if(is_ai(target))
damage = 0 //cheater cheater I don't want AI to die to stupid placement eater
nodamage = 1
if(isliving(target))
diff --git a/code/modules/recycling/disposal.dm b/code/modules/recycling/disposal.dm
index 0ea0f0e2f01..33a01ea0c84 100644
--- a/code/modules/recycling/disposal.dm
+++ b/code/modules/recycling/disposal.dm
@@ -273,7 +273,7 @@
// mouse drop another mob or self
//
/obj/machinery/disposal/MouseDrop_T(mob/living/target, mob/living/user)
- if(!istype(target) || target.buckled || target.has_buckled_mobs() || get_dist(user, src) > 1 || get_dist(user, target) > 1 || user.stat || isAI(user))
+ if(!istype(target) || target.buckled || target.has_buckled_mobs() || get_dist(user, src) > 1 || get_dist(user, target) > 1 || user.stat || is_ai(user))
return
// Animals cannot put mobs other than themselves into disposals.
@@ -389,7 +389,7 @@
/obj/machinery/disposal/ui_data(mob/user)
var/list/data = list()
- data["isAI"] = isAI(user)
+ data["is_ai"] = is_ai(user)
data["flushing"] = flush
data["mode"] = mode
data["pressure"] = round(clamp(100* air_contents.return_pressure() / (SEND_PRESSURE), 0, 100),1)
diff --git a/code/modules/recycling/sortingmachinery.dm b/code/modules/recycling/sortingmachinery.dm
index ddc87780cbc..1a391158a0c 100644
--- a/code/modules/recycling/sortingmachinery.dm
+++ b/code/modules/recycling/sortingmachinery.dm
@@ -308,7 +308,7 @@
. = ..()
/obj/machinery/disposal/delivery_chute/Bumped(atom/movable/AM) //Go straight into the chute
- if(isprojectile(AM) || isAI(AM) || QDELETED(AM))
+ if(isprojectile(AM) || is_ai(AM) || QDELETED(AM))
return
// We may already contain the object because thrown objects
diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm
index fe330b6a36e..84a60c49cf0 100644
--- a/code/modules/research/xenobiology/xenobio_camera.dm
+++ b/code/modules/research/xenobiology/xenobio_camera.dm
@@ -1,26 +1,3 @@
-//Xenobio control console
-/mob/camera/ai_eye/remote/xenobio
- visible_icon = 1
- icon = 'icons/obj/abductor.dmi'
- icon_state = "camera_target"
- // The Xenobio Console does not trigger the AI Detector
- ai_detector_visible = FALSE
- /// Area that the xenobio camera eye is allowed to travel
- var/allowed_area = null
-
-/mob/camera/ai_eye/remote/xenobio/Initialize(mapload)
- . = ..()
- var/area/A = get_area(loc)
- allowed_area = A.name
-
-/mob/camera/ai_eye/remote/xenobio/setLoc(t)
- var/area/new_area = get_area(t)
- if(!new_area)
- return
- if(new_area.name != allowed_area && !new_area.xenobiology_compatible)
- return
- return ..()
-
/*
* # Slime Management Console
*
@@ -54,6 +31,10 @@
if(!connected_recycler)
locate_recycler()
+/obj/machinery/computer/camera_advanced/xenobio/CreateEye()
+ eyeobj = new /mob/camera/eye/xenobio(loc, name, src, current_user)
+ give_eye_control(current_user)
+
/obj/machinery/computer/camera_advanced/xenobio/proc/locate_recycler()
for(var/obj/machinery/monkey_recycler/recycler in GLOB.monkey_recyclers)
if(get_area(recycler) == get_area(loc))
@@ -79,14 +60,6 @@
stored_slimes -= A
return ..()
-/obj/machinery/computer/camera_advanced/xenobio/CreateEye()
- eyeobj = new /mob/camera/ai_eye/remote/xenobio(get_turf(src))
- eyeobj.origin = src
- eyeobj.visible_icon = TRUE
- eyeobj.acceleration = FALSE
- eyeobj.icon = 'icons/obj/abductor.dmi'
- eyeobj.icon_state = "camera_target"
-
/obj/machinery/computer/camera_advanced/xenobio/GrantActions(mob/living/carbon/user)
..()
@@ -223,13 +196,13 @@
if(!target || !ishuman(owner))
return
var/mob/living/carbon/human/C = owner
- var/mob/camera/ai_eye/remote/xenobio/remote_eye = C.remote_control
+ var/mob/camera/eye/xenobio/remote_eye = C.remote_control
var/obj/machinery/computer/camera_advanced/xenobio/X = target
if(iswallturf(remote_eye.loc))
to_chat(owner, "You can't place slime here.")
return
- else if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
+ else if(GLOB.cameranet.check_turf_vis(remote_eye.loc))
for(var/mob/living/simple_animal/slime/S in X.stored_slimes)
X.release_slime(S, remote_eye.loc)
else
@@ -243,10 +216,10 @@
if(!target || !ishuman(owner))
return
var/mob/living/carbon/human/C = owner
- var/mob/camera/ai_eye/remote/xenobio/remote_eye = C.remote_control
+ var/mob/camera/eye/xenobio/remote_eye = C.remote_control
var/obj/machinery/computer/camera_advanced/xenobio/X = target
- if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
+ if(GLOB.cameranet.check_turf_vis(remote_eye.loc))
for(var/mob/living/simple_animal/slime/S in remote_eye.loc)
if(length(X.stored_slimes) >= X.max_slimes)
break
@@ -265,11 +238,11 @@
if(!target || !ishuman(owner))
return
var/mob/living/carbon/human/C = owner
- var/mob/camera/ai_eye/remote/xenobio/remote_eye = C.remote_control
+ var/mob/camera/eye/xenobio/remote_eye = C.remote_control
var/obj/machinery/computer/camera_advanced/xenobio/X = target
var/obj/machinery/monkey_recycler/recycler = X.connected_recycler
- if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
+ if(GLOB.cameranet.check_turf_vis(remote_eye.loc))
if(LAZYLEN(SSmobs.cubemonkeys) >= GLOB.configuration.general.monkey_cube_cap)
to_chat(owner, "Bluespace harmonics prevent the spawning of more than [GLOB.configuration.general.monkey_cube_cap] monkeys on the station at one time!")
return
@@ -309,14 +282,14 @@
if(!target || !ishuman(owner))
return
var/mob/living/carbon/human/C = owner
- var/mob/camera/ai_eye/remote/xenobio/remote_eye = C.remote_control
+ var/mob/camera/eye/xenobio/remote_eye = C.remote_control
var/obj/machinery/computer/camera_advanced/xenobio/X = target
var/obj/machinery/monkey_recycler/recycler = X.connected_recycler
if(!recycler)
to_chat(owner, "There is no connected monkey recycler. Use a multitool to link one.")
return
- if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
+ if(GLOB.cameranet.check_turf_vis(remote_eye.loc))
for(var/mob/living/carbon/human/M in remote_eye.loc)
if(issmall(M) && M.stat)
M.visible_message("[M] vanishes as [M.p_theyre()] reclaimed for recycling!")
@@ -334,9 +307,9 @@
if(!target || !isliving(owner))
return
var/mob/living/C = owner
- var/mob/camera/ai_eye/remote/xenobio/remote_eye = C.remote_control
+ var/mob/camera/eye/xenobio/remote_eye = C.remote_control
- if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
+ if(GLOB.cameranet.check_turf_vis(remote_eye.loc))
for(var/mob/living/simple_animal/slime/S in remote_eye.loc)
slime_scan(S, C)
else
@@ -351,14 +324,14 @@
return
var/mob/living/carbon/human/C = owner
- var/mob/camera/ai_eye/remote/xenobio/remote_eye = C.remote_control
+ var/mob/camera/eye/xenobio/remote_eye = C.remote_control
var/obj/machinery/computer/camera_advanced/xenobio/X = target
if(QDELETED(X.current_potion))
to_chat(owner, "No potion loaded.")
return
- if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
+ if(GLOB.cameranet.check_turf_vis(remote_eye.loc))
for(var/mob/living/simple_animal/slime/S in remote_eye.loc)
X.current_potion.attack__legacy__attackchain(S, C)
break
@@ -416,22 +389,22 @@
// Scans slime
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickCtrl(mob/living/user, mob/living/simple_animal/slime/S)
- if(!GLOB.cameranet.checkTurfVis(S.loc))
+ if(!GLOB.cameranet.check_turf_vis(S.loc))
to_chat(user, "Target is not near a camera. Cannot proceed.")
return
var/mob/living/C = user
- var/mob/camera/ai_eye/remote/xenobio/E = C.remote_control
+ var/mob/camera/eye/xenobio/E = C.remote_control
var/area/mobarea = get_area(S.loc)
if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible)
slime_scan(S, C)
//Feeds a potion to slime
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickAlt(mob/living/user, mob/living/simple_animal/slime/S)
- if(!GLOB.cameranet.checkTurfVis(S.loc))
+ if(!GLOB.cameranet.check_turf_vis(S.loc))
to_chat(user, "Target is not near a camera. Cannot proceed.")
return
var/mob/living/C = user
- var/mob/camera/ai_eye/remote/xenobio/E = C.remote_control
+ var/mob/camera/eye/xenobio/E = C.remote_control
var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin
var/area/mobarea = get_area(S.loc)
if(!X.current_potion)
@@ -442,11 +415,11 @@
//Picks up slime
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoSlimeClickShift(mob/living/user, mob/living/simple_animal/slime/S)
- if(!GLOB.cameranet.checkTurfVis(S.loc))
+ if(!GLOB.cameranet.check_turf_vis(S.loc))
to_chat(user, "Target is not near a camera. Cannot proceed.")
return
var/mob/living/C = user
- var/mob/camera/ai_eye/remote/xenobio/E = C.remote_control
+ var/mob/camera/eye/xenobio/E = C.remote_control
var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin
var/area/mobarea = get_area(S.loc)
if(mobarea.name == E.allowed_area || mobarea.xenobiology_compatible)
@@ -463,11 +436,11 @@
//Place slimes
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoTurfClickShift(mob/living/user, turf/T)
- if(!GLOB.cameranet.checkTurfVis(T))
+ if(!GLOB.cameranet.check_turf_vis(T))
to_chat(user, "Target is not near a camera. Cannot proceed.")
return
var/mob/living/C = user
- var/mob/camera/ai_eye/remote/xenobio/E = C.remote_control
+ var/mob/camera/eye/xenobio/E = C.remote_control
var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin
var/area/turfarea = get_area(T)
if(iswallturf(T))
@@ -479,11 +452,11 @@
//Place monkey
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoTurfClickCtrl(mob/living/user, turf/T)
- if(!GLOB.cameranet.checkTurfVis(T))
+ if(!GLOB.cameranet.check_turf_vis(T))
to_chat(user, "Target is not near a camera. Cannot proceed.")
return
var/mob/living/C = user
- var/mob/camera/ai_eye/remote/xenobio/E = C.remote_control
+ var/mob/camera/eye/xenobio/E = C.remote_control
var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin
var/obj/machinery/monkey_recycler/recycler = X.connected_recycler
var/area/turfarea = get_area(T)
@@ -513,11 +486,11 @@
//Pick up monkey
/obj/machinery/computer/camera_advanced/xenobio/proc/XenoMonkeyClickCtrl(mob/living/user, mob/living/carbon/human/M)
- if(!GLOB.cameranet.checkTurfVis(M.loc))
+ if(!GLOB.cameranet.check_turf_vis(M.loc))
to_chat(user, "Target is not near a camera. Cannot proceed.")
return
var/mob/living/C = user
- var/mob/camera/ai_eye/remote/xenobio/E = C.remote_control
+ var/mob/camera/eye/xenobio/E = C.remote_control
var/obj/machinery/computer/camera_advanced/xenobio/X = E.origin
var/area/mobarea = get_area(M.loc)
var/obj/machinery/monkey_recycler/recycler = X.connected_recycler
diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm
index 762fba8ab68..8c41e177816 100644
--- a/code/modules/shuttle/emergency.dm
+++ b/code/modules/shuttle/emergency.dm
@@ -182,7 +182,7 @@
attempt_hijack_stage(user)
/obj/machinery/computer/emergency_shuttle/proc/attempt_hijack_stage(mob/living/user)
- var/is_ai = isAI(user)
+ var/is_ai = is_ai(user)
if(!Adjacent(user) && !is_ai)
return
if(!ishuman(user) && !is_ai) //No, xenomorphs, constructs and traitors in cyborgs can not hack it.
diff --git a/code/modules/shuttle/navigation_computer.dm b/code/modules/shuttle/navigation_computer.dm
index ac9c5a4add9..9cdaca55d54 100644
--- a/code/modules/shuttle/navigation_computer.dm
+++ b/code/modules/shuttle/navigation_computer.dm
@@ -55,8 +55,8 @@
shuttle_port = null
return
- eyeobj = new /mob/camera/ai_eye/remote/shuttle_docker(get_turf(locate("landmark*Observer-Start")), src) // There should always be an observer start landmark
- var/mob/camera/ai_eye/remote/shuttle_docker/the_eye = eyeobj
+ eyeobj = new /mob/camera/eye/shuttle_docker(get_turf(locate("landmark*Observer-Start")), name, src, current_user) // There should always be an observer start landmark
+ var/mob/camera/eye/shuttle_docker/the_eye = eyeobj
the_eye.setDir(shuttle_port.dir)
var/turf/origin = locate(shuttle_port.x + x_offset, shuttle_port.y + y_offset, shuttle_port.z)
for(var/V in shuttle_port.shuttle_areas)
@@ -72,11 +72,12 @@
I.plane = 0
I.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
the_eye.placement_images[I] = list(x_off, y_off)
+ give_eye_control(current_user)
/obj/machinery/computer/camera_advanced/shuttle_docker/give_eye_control(mob/user)
..()
if(!QDELETED(user) && user.client)
- var/mob/camera/ai_eye/remote/shuttle_docker/the_eye = eyeobj
+ var/mob/camera/eye/shuttle_docker/the_eye = eyeobj
var/list/to_add = list()
to_add += the_eye.placement_images
to_add += the_eye.placed_images
@@ -89,7 +90,7 @@
/obj/machinery/computer/camera_advanced/shuttle_docker/remove_eye_control(mob/living/user)
..()
if(!QDELETED(user) && user.client)
- var/mob/camera/ai_eye/remote/shuttle_docker/the_eye = eyeobj
+ var/mob/camera/eye/shuttle_docker/the_eye = eyeobj
var/list/to_remove = list()
to_remove += the_eye.placement_images
to_remove += the_eye.placed_images
@@ -103,8 +104,8 @@
if(designating_target_loc || !current_user)
return
- var/mob/camera/ai_eye/remote/shuttle_docker/the_eye = eyeobj
- var/landing_clear = checkLandingSpot()
+ var/mob/camera/eye/shuttle_docker/the_eye = eyeobj
+ var/landing_clear = check_landing_spot()
if(designate_time && (landing_clear != SHUTTLE_DOCKER_BLOCKED))
to_chat(current_user, "Targeting transit location, please wait [DisplayTimeText(designate_time)]...")
designating_target_loc = the_eye.loc
@@ -115,7 +116,7 @@
if(!wait_completed)
to_chat(current_user, "Operation aborted.")
return
- landing_clear = checkLandingSpot()
+ landing_clear = check_landing_spot()
if(landing_clear != SHUTTLE_DOCKER_LANDING_CLEAR)
switch(landing_clear)
@@ -162,7 +163,7 @@
return TRUE
/obj/machinery/computer/camera_advanced/shuttle_docker/proc/rotateLandingSpot()
- var/mob/camera/ai_eye/remote/shuttle_docker/the_eye = eyeobj
+ var/mob/camera/eye/shuttle_docker/the_eye = eyeobj
var/list/image_cache = the_eye.placement_images
the_eye.setDir(turn(the_eye.dir, -90))
for(var/i in 1 to length(image_cache))
@@ -175,10 +176,10 @@
var/Tmp = x_offset
x_offset = y_offset
y_offset = -Tmp
- checkLandingSpot()
+ check_landing_spot()
-/obj/machinery/computer/camera_advanced/shuttle_docker/proc/checkLandingSpot()
- var/mob/camera/ai_eye/remote/shuttle_docker/the_eye = eyeobj
+/obj/machinery/computer/camera_advanced/shuttle_docker/proc/check_landing_spot()
+ var/mob/camera/eye/shuttle_docker/the_eye = eyeobj
var/turf/eyeturf = get_turf(the_eye)
if(!eyeturf)
return SHUTTLE_DOCKER_BLOCKED
@@ -253,34 +254,6 @@
if(dock)
jumpto_ports[dock.id] = TRUE
-/mob/camera/ai_eye/remote/shuttle_docker
- visible_icon = FALSE
- use_static = FALSE
- simulated = FALSE
- // The Shuttle Docker does not trigger the AI Detector
- ai_detector_visible = FALSE
- var/list/placement_images = list()
- var/list/placed_images = list()
-
-/mob/camera/ai_eye/remote/shuttle_docker/Initialize(mapload, obj/machinery/computer/camera_advanced/origin)
- src.origin = origin
- return ..()
-
-/mob/camera/ai_eye/remote/shuttle_docker/setLoc(T)
- if(isspaceturf(get_turf(T)) || isspacearea(get_area(T)) || istype(get_area(T), /area/shuttle))
- ..()
- var/obj/machinery/computer/camera_advanced/shuttle_docker/console = origin
- console.checkLandingSpot()
- return
- else
- return
-
-/mob/camera/ai_eye/remote/shuttle_docker/update_remote_sight(mob/living/user)
- user.sight = SEE_TURFS
-
- ..()
- return TRUE
-
/datum/action/innate/shuttledocker_rotate
name = "Rotate"
button_overlay_icon = 'icons/mob/actions/actions_mecha.dmi'
@@ -290,7 +263,7 @@
if(QDELETED(target) || !isliving(target))
return
var/mob/living/C = target
- var/mob/camera/ai_eye/remote/remote_eye = C.remote_control
+ var/mob/camera/eye/remote_eye = C.remote_control
var/obj/machinery/computer/camera_advanced/shuttle_docker/origin = remote_eye.origin
origin.rotateLandingSpot()
@@ -303,7 +276,7 @@
if(QDELETED(target) || !isliving(target))
return
var/mob/living/C = target
- var/mob/camera/ai_eye/remote/remote_eye = C.remote_control
+ var/mob/camera/eye/remote_eye = C.remote_control
var/obj/machinery/computer/camera_advanced/shuttle_docker/origin = remote_eye.origin
origin.placeLandingSpot(target)
@@ -315,7 +288,7 @@
if(QDELETED(target) || !isliving(target))
return
var/mob/living/C = target
- var/mob/camera/ai_eye/remote/remote_eye = C.remote_control
+ var/mob/camera/eye/remote_eye = C.remote_control
var/obj/machinery/computer/camera_advanced/shuttle_docker/console = remote_eye.origin
playsound(console, 'sound/machines/terminal_prompt_deny.ogg', 25, 0)
@@ -337,7 +310,7 @@
var/turf/T = get_turf(L[selected])
if(T)
playsound(console, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0)
- remote_eye.setLoc(T)
+ remote_eye.set_loc(T)
to_chat(target, "Jumped to [selected]")
else
playsound(console, 'sound/machines/terminal_prompt_deny.ogg', 25, 0)
diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm
index a4e35b9bec9..289beee4223 100644
--- a/code/modules/surgery/organs/vocal_cords.dm
+++ b/code/modules/surgery/organs/vocal_cords.dm
@@ -166,8 +166,8 @@ GLOBAL_DATUM_INIT(multispin_words, /regex, regex("like a record baby"))
var/mob/living/carbon/human/H = L
if(H.check_ear_prot() >= HEARING_PROTECTION_TOTAL)
continue
- if(istype(L, /mob/camera/ai_eye))
- var/mob/camera/ai_eye/ai_eye = L
+ if(istype(L, /mob/camera/eye/ai))
+ var/mob/camera/eye/ai/ai_eye = L
if(ai_eye.relay_speech && ai_eye.ai)
listeners += ai_eye.ai
else
diff --git a/code/modules/tgui/modules/crew_monitor.dm b/code/modules/tgui/modules/crew_monitor.dm
index 7b8df4bae23..f10b8ac3b59 100644
--- a/code/modules/tgui/modules/crew_monitor.dm
+++ b/code/modules/tgui/modules/crew_monitor.dm
@@ -37,7 +37,7 @@
switch(action)
if("track")
var/mob/living/carbon/human/H = locate(params["track"]) in GLOB.human_list
- if(isAI(usr))
+ if(is_ai(usr))
var/mob/living/silicon/ai/AI = usr
if(hassensorlevel(H, SUIT_SENSOR_TRACKING))
AI.ai_actual_track(H)
@@ -105,7 +105,7 @@
data["offsetX"] = offset_x
data["offsetY"] = offset_y
- data["isAI"] = isAI(user)
+ data["isAI"] = is_ai(user)
data["isObserver"] = isobserver(user)
data["ignoreSensors"] = ignore_sensors
data["crewmembers"] = GLOB.crew_repository.health_data(viewing_current_z_level, ignore_sensors)
diff --git a/code/modules/tgui/modules/law_manager.dm b/code/modules/tgui/modules/law_manager.dm
index 001a8bdc31c..4e8cf27f791 100644
--- a/code/modules/tgui/modules/law_manager.dm
+++ b/code/modules/tgui/modules/law_manager.dm
@@ -140,7 +140,7 @@
if("notify_laws")
to_chat(owner, "Law Notice")
owner.laws.show_laws(owner)
- if(isAI(owner))
+ if(is_ai(owner))
var/mob/living/silicon/ai/AI = owner
for(var/mob/living/silicon/robot/R in AI.connected_robots)
to_chat(R, "Law Notice")
@@ -178,7 +178,7 @@
package_laws(data, "inherent_laws", owner.laws.inherent_laws)
package_laws(data, "supplied_laws", owner.laws.supplied_laws)
- data["isAI"] = isAI(owner)
+ data["isAI"] = is_ai(owner)
data["isMalf"] = is_malf(user)
data["isSlaved"] = owner.is_slaved()
data["isAdmin"] = is_admin(user)
diff --git a/code/modules/tgui/plugins/tgui_login.dm b/code/modules/tgui/plugins/tgui_login.dm
index 0f80f0a13fe..ea1beabaf6e 100644
--- a/code/modules/tgui/plugins/tgui_login.dm
+++ b/code/modules/tgui/plugins/tgui_login.dm
@@ -56,7 +56,7 @@ GLOBAL_LIST(ui_logins)
"rank" = state.rank,
"logged_in" = state.logged_in,
)
- data["isAI"] = isAI(user)
+ data["isAI"] = is_ai(user)
data["isRobot"] = isrobot(user)
data["isAdmin"] = user.can_admin_interact()
@@ -133,7 +133,7 @@ GLOBAL_LIST(ui_logins)
else
to_chat(usr, "Access Denied")
return
- else if(login_type == LOGIN_TYPE_AI && isAI(usr))
+ else if(login_type == LOGIN_TYPE_AI && is_ai(usr))
state.name = usr.name
state.rank = "AI"
else if(login_type == LOGIN_TYPE_ROBOT && isrobot(usr))
diff --git a/paradise.dme b/paradise.dme
index 06372adc927..0ad61290e5c 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -2214,6 +2214,15 @@
#include "code\modules\mob\transform_procs.dm"
#include "code\modules\mob\typing_indicator.dm"
#include "code\modules\mob\camera\camera_mob.dm"
+#include "code\modules\mob\camera\cameranet.dm"
+#include "code\modules\mob\camera\chunk.dm"
+#include "code\modules\mob\camera\eye.dm"
+#include "code\modules\mob\camera\eye\abductor.dm"
+#include "code\modules\mob\camera\eye\ai_eye.dm"
+#include "code\modules\mob\camera\eye\hologram_eye.dm"
+#include "code\modules\mob\camera\eye\shuttle_navigator.dm"
+#include "code\modules\mob\camera\eye\syndicate.dm"
+#include "code\modules\mob\camera\eye\xenobio_eye.dm"
#include "code\modules\mob\dead\dead.dm"
#include "code\modules\mob\dead\observer\observer_base.dm"
#include "code\modules\mob\dead\observer\observer_login.dm"
@@ -2349,9 +2358,6 @@
#include "code\modules\mob\living\silicon\ai\ai_update_status.dm"
#include "code\modules\mob\living\silicon\ai\latejoin.dm"
#include "code\modules\mob\living\silicon\ai\ai_verbs\botcall.dm"
-#include "code\modules\mob\living\silicon\ai\freelook\cameranet.dm"
-#include "code\modules\mob\living\silicon\ai\freelook\chunk.dm"
-#include "code\modules\mob\living\silicon\ai\freelook\eye.dm"
#include "code\modules\mob\living\silicon\decoy\decoy.dm"
#include "code\modules\mob\living\silicon\decoy\decoy_death.dm"
#include "code\modules\mob\living\silicon\decoy\decoy_life.dm"