mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-15 09:03:23 +01:00
-Ported/continued AI Freelook. AIs can now look around like a ghost with the exception that they cannot see what cameras cannot see. Meaning if you're in maintenance, and there's no cameras near you, the AI will not know what you are doing. This also means there's no X-Ray vision cameras anymore. I've added documentation to freelook.dm which explains how the system works, if anyone is interested in adding anything. More information here: http://nanotrasen.com/phpBB3/viewtopic.php?f=7&t=9675
-I've added some cameras to rooms that should have cameras but were previously depending on other camera's using their X-Ray vision in order to see into a room. -AIs have a multitool in their contents that they can use to interact with the telecommunication machines. -Added "Follow" for observers. Works the same as AI tracking without checking if they can track. -Added a range to how far Cyborgs can interact with machines. This is to stop Cyborgs from interacting with machines through cameras, which could be used to easily disable the AI. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@4531 316c924e-a436-60f5-8080-3fe189b3f50e
This commit is contained in:
@@ -320,6 +320,10 @@ Turf and target are seperate in case you want to teleport some distance from a t
|
||||
oldname = null//don't bother with the records update crap
|
||||
world << "<b>[newname] is the AI!</b>"
|
||||
world << sound('sound/AI/newAI.ogg')
|
||||
for(var/mob/aiEye/E in mob_list)
|
||||
if(E.ai && E.ai == src)
|
||||
E.name = "[newname] (AI Eye)"
|
||||
break
|
||||
|
||||
fully_replace_character_name(oldname,newname)
|
||||
|
||||
|
||||
+61
-120
@@ -1,39 +1,3 @@
|
||||
var/global/list/obj/machinery/camera/Cameras = list()
|
||||
|
||||
/obj/machinery/camera/New()
|
||||
Cameras += src
|
||||
..()
|
||||
|
||||
/obj/machinery/camera/Del()
|
||||
Cameras -= src
|
||||
..()
|
||||
|
||||
|
||||
// Double clicking turfs to move to nearest camera
|
||||
|
||||
/turf/proc/move_camera_by_click()
|
||||
if (usr.stat)
|
||||
return ..()
|
||||
if (world.time <= usr:lastDblClick+2)
|
||||
return ..()
|
||||
|
||||
//try to find the closest working camera in the same area, switch to it
|
||||
var/area/A = get_area(src)
|
||||
var/best_dist = INFINITY //infinity
|
||||
var/best_cam = null
|
||||
for(var/obj/machinery/camera/C in A)
|
||||
if(usr:network != C.network) continue
|
||||
if(!C.status) continue // ignore disabled cameras
|
||||
var/dist = get_dist(src, C)
|
||||
if(dist < best_dist)
|
||||
best_dist = dist
|
||||
best_cam = C
|
||||
|
||||
if(!best_cam)
|
||||
return ..()
|
||||
usr:lastDblClick = world.time
|
||||
usr:switchCamera(best_cam)
|
||||
|
||||
/mob/living/silicon/ai/proc/ai_camera_list()
|
||||
set category = "AI Commands"
|
||||
set name = "Show Camera List"
|
||||
@@ -55,26 +19,33 @@ var/global/list/obj/machinery/camera/Cameras = list()
|
||||
var/list/namecounts = list()
|
||||
var/list/humans = list()
|
||||
var/list/others = list()
|
||||
|
||||
for(var/mob/living/M in mob_list)
|
||||
//Cameras can't track people wearing an agent card or a ninja hood.
|
||||
var/human = 0
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
human = 1
|
||||
if(istype(M:wear_id, /obj/item/weapon/card/id/syndicate))
|
||||
continue
|
||||
if(istype(M:head, /obj/item/clothing/head/helmet/space/space_ninja)&&!M:head:canremove)
|
||||
continue
|
||||
if(!istype(M.loc, /turf)) //in a closet or something, AI can't see him anyways
|
||||
continue
|
||||
if(istype(M.loc.loc, /area/wizard_station))
|
||||
continue
|
||||
if(M.invisibility)//cloaked
|
||||
// Easy checks first.
|
||||
// Don't detect mobs on Centcom. Since the wizard den is on Centcomm, we only need this.
|
||||
if(M.loc.z == 2)
|
||||
continue
|
||||
if(M == usr)
|
||||
continue
|
||||
if(M.invisibility)//cloaked
|
||||
continue
|
||||
if(M.digitalcamo)
|
||||
continue
|
||||
if(M.loc.z == 2) // Don't detect mobs on Centcom
|
||||
|
||||
// Human check
|
||||
var/human = 0
|
||||
if(istype(M, /mob/living/carbon/human))
|
||||
human = 1
|
||||
var/mob/living/carbon/human/H = M
|
||||
//Cameras can't track people wearing an agent card or a ninja hood.
|
||||
if(istype(H.wear_id, /obj/item/weapon/card/id/syndicate))
|
||||
continue
|
||||
if(istype(H.head, /obj/item/clothing/head/helmet/space/space_ninja))
|
||||
var/obj/item/clothing/head/helmet/space/space_ninja/hood = H.head
|
||||
if(!hood.canremove)
|
||||
continue
|
||||
// Now, are they viewable by a camera? (This is last because it's the most intensive check)
|
||||
if(!cameranet.checkCameraVis(M))
|
||||
continue
|
||||
|
||||
var/name = M.name
|
||||
@@ -104,9 +75,10 @@ var/global/list/obj/machinery/camera/Cameras = list()
|
||||
var/mob/living/silicon/ai/U = usr
|
||||
|
||||
U.cameraFollow = target
|
||||
U << text("Now tracking [] on camera.", target.name)
|
||||
if (U.machine == null)
|
||||
U.machine = U
|
||||
//U << text("Now tracking [] on camera.", target.name)
|
||||
//if (U.machine == null)
|
||||
// U.machine = U
|
||||
U << "Now tracking [target.name] on camera."
|
||||
|
||||
spawn (0)
|
||||
while (U.cameraFollow == target)
|
||||
@@ -117,7 +89,7 @@ var/global/list/obj/machinery/camera/Cameras = list()
|
||||
U << "Follow camera mode terminated."
|
||||
U.cameraFollow = null
|
||||
return
|
||||
if(istype(target:head, /obj/item/clothing/head/helmet/space/space_ninja)&&!target:head:canremove)
|
||||
if(istype(target:head, /obj/item/clothing/head/helmet/space/space_ninja) && !target:head:canremove)
|
||||
U << "Follow camera mode terminated."
|
||||
U.cameraFollow = null
|
||||
return
|
||||
@@ -132,47 +104,14 @@ var/global/list/obj/machinery/camera/Cameras = list()
|
||||
return
|
||||
else if (!target || !istype(target.loc, /turf)) //in a closet
|
||||
U << "Target is not on or near any active cameras on the station. We'll check again in 5 seconds (unless you use the cancel-camera verb)."
|
||||
sleep(40) //because we're sleeping another second after this (a few lines down)
|
||||
sleep(30) //because we're sleeping another second after this (a few lines down)
|
||||
continue
|
||||
else if(!cameranet.checkCameraVis(target))
|
||||
U << "Target is not on or near any active cameras on the station. We'll check again in 5 seconds (unless you use the cancel-camera verb)."
|
||||
sleep(30) //because we're sleeping another second after this (a few lines down)
|
||||
continue
|
||||
|
||||
var/obj/machinery/camera/C = U.current
|
||||
if ((C && istype(C, /obj/machinery/camera)) || C==null)
|
||||
|
||||
if(isrobot(target))
|
||||
var/mob/living/silicon/robot/R = target
|
||||
C = R.camera
|
||||
U.reset_view(C)
|
||||
else
|
||||
var/closestDist = -1
|
||||
if (C!=null)
|
||||
if (C.status)
|
||||
closestDist = get_dist(C, target)
|
||||
//U << text("Dist = [] for camera []", closestDist, C.name)
|
||||
var/zmatched = 0
|
||||
if (closestDist > 7 || closestDist == -1)
|
||||
//check other cameras
|
||||
var/obj/machinery/camera/closest = C
|
||||
for(var/obj/machinery/camera/C2 in Cameras)
|
||||
if (C2.network == src.network)
|
||||
if (C2.z == target.z)
|
||||
zmatched = 1
|
||||
if (C2.status)
|
||||
var/dist = get_dist(C2, target)
|
||||
if ((dist < closestDist) || (closestDist == -1))
|
||||
closestDist = dist
|
||||
closest = C2
|
||||
//U << text("Closest camera dist = [], for camera []", closestDist, closest.area.name)
|
||||
|
||||
if (closest != C)
|
||||
U.reset_view(closest)
|
||||
//use_power(50)
|
||||
if (zmatched == 0)
|
||||
U << "Target is not on or near any active cameras on the station. We'll check again in 5 seconds (unless you use the cancel-camera verb)."
|
||||
sleep(40) //because we're sleeping another second after this (a few lines down)
|
||||
else
|
||||
U << "Follow camera mode ended."
|
||||
U.cameraFollow = null
|
||||
|
||||
U.eyeobj.setLoc(get_turf(target))
|
||||
sleep(10)
|
||||
|
||||
/proc/camera_sort(list/L)
|
||||
@@ -191,7 +130,6 @@ var/global/list/obj/machinery/camera/Cameras = list()
|
||||
L.Swap(j, j + 1)
|
||||
return L
|
||||
|
||||
|
||||
/mob/living/silicon/ai/attack_ai(var/mob/user as mob)
|
||||
if (user != src)
|
||||
return
|
||||
@@ -199,13 +137,8 @@ var/global/list/obj/machinery/camera/Cameras = list()
|
||||
if (stat == 2)
|
||||
return
|
||||
|
||||
// If they cancel then just put them back to their old camera
|
||||
var/obj/machinery/camera/tempC = src.current
|
||||
user.machine = src
|
||||
switchCamera(null)
|
||||
|
||||
var/list/L = list()
|
||||
for (var/obj/machinery/camera/C in Cameras)
|
||||
for (var/obj/machinery/camera/C in cameranet.cameras)
|
||||
L.Add(C)
|
||||
|
||||
camera_sort(L)
|
||||
@@ -214,19 +147,15 @@ var/global/list/obj/machinery/camera/Cameras = list()
|
||||
D["Cancel"] = "Cancel"
|
||||
for (var/obj/machinery/camera/C in L)
|
||||
if (C.network == src.network)
|
||||
D[text("[][]", C.c_tag, (C.status ? null : " (Deactivated)"))] = C
|
||||
D[text("[][]", C.c_tag, (C.can_use() ? null : " (Deactivated)"))] = C
|
||||
|
||||
var/t = input(user, "Which camera should you change to?") as null|anything in D
|
||||
|
||||
if (!t || t == "Cancel")
|
||||
if(tempC && tempC.status)
|
||||
switchCamera(tempC)
|
||||
else
|
||||
switchCamera(null)
|
||||
return 0
|
||||
|
||||
var/obj/machinery/camera/C = D[t]
|
||||
switchCamera(C)
|
||||
src.eyeobj.setLoc(C)
|
||||
|
||||
return
|
||||
|
||||
@@ -234,13 +163,15 @@ var/global/list/obj/machinery/camera/Cameras = list()
|
||||
if(prob(100/(hardened + severity)))
|
||||
icon_state = "cameraemp"
|
||||
network = null //Not the best way but it will do. I think.
|
||||
cameranet.removeCamera(src)
|
||||
stat |= EMPED
|
||||
sd_SetLuminosity(0)
|
||||
spawn(900)
|
||||
network = initial(network)
|
||||
icon_state = initial(icon_state)
|
||||
for(var/mob/living/silicon/ai/O in mob_list)
|
||||
if (O.current == src)
|
||||
O.cancel_camera()
|
||||
O << "Your connection to the camera has been lost."
|
||||
stat &= ~EMPED
|
||||
if(can_use())
|
||||
cameranet.addCamera(src)
|
||||
for(var/mob/O in mob_list)
|
||||
if (istype(O.machine, /obj/machinery/computer/security))
|
||||
var/obj/machinery/computer/security/S = O.machine
|
||||
@@ -266,9 +197,9 @@ var/global/list/obj/machinery/camera/Cameras = list()
|
||||
/obj/machinery/camera/attack_ai(var/mob/living/silicon/ai/user as mob)
|
||||
if (!istype(user))
|
||||
return
|
||||
if (src.network != user.network || !(src.status))
|
||||
if (!src.can_use())
|
||||
return
|
||||
user.reset_view(src)
|
||||
user.eyeobj.setLoc(get_turf(src))
|
||||
|
||||
/obj/machinery/camera/attack_paw(mob/living/carbon/alien/humanoid/user as mob)
|
||||
if(!istype(user))
|
||||
@@ -329,7 +260,7 @@ var/global/list/obj/machinery/camera/Cameras = list()
|
||||
case.motion = 1
|
||||
del(src)
|
||||
else if (istype(W, /obj/item/weapon/camera_bug))
|
||||
if (!src.status)
|
||||
if (!src.can_use())
|
||||
user << "\blue Camera non-functional"
|
||||
return
|
||||
if (src.bugged)
|
||||
@@ -381,10 +312,6 @@ var/global/list/obj/machinery/camera/Cameras = list()
|
||||
// now disconnect anyone using the camera
|
||||
//Apparently, this will disconnect anyone even if the camera was re-activated.
|
||||
//I guess that doesn't matter since they can't use it anyway?
|
||||
for(var/mob/living/silicon/ai/O in player_list)
|
||||
if (O.current == src)
|
||||
O.cancel_camera()
|
||||
O << "Your connection to the camera has been lost."
|
||||
for(var/mob/O in player_list)
|
||||
if (istype(O.machine, /obj/machinery/computer/security))
|
||||
var/obj/machinery/computer/security/S = O.machine
|
||||
@@ -393,6 +320,13 @@ var/global/list/obj/machinery/camera/Cameras = list()
|
||||
O.reset_view(null)
|
||||
O << "The screen bursts into static."
|
||||
|
||||
/obj/machinery/camera/proc/can_use()
|
||||
if(!status)
|
||||
return 0
|
||||
if(stat & EMPED)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/atom/proc/auto_turn()
|
||||
//Automatically turns based on nearby walls.
|
||||
var/turf/simulated/wall/T = null
|
||||
@@ -414,10 +348,17 @@ var/global/list/obj/machinery/camera/Cameras = list()
|
||||
//Return a working camera that can see a given mob
|
||||
//or null if none
|
||||
/proc/seen_by_camera(var/mob/M)
|
||||
for(var/obj/machinery/camera/C in oview(4, M))
|
||||
if(C.can_use()) // check if camera disabled
|
||||
return C
|
||||
break
|
||||
return null
|
||||
|
||||
for(var/obj/machinery/camera/C in oview(M))
|
||||
if(C.status) // check if camera disabled
|
||||
/proc/near_range_camera(var/mob/M)
|
||||
|
||||
for(var/obj/machinery/camera/C in range(4, M))
|
||||
if(C.can_use()) // check if camera disabled
|
||||
return C
|
||||
break
|
||||
|
||||
return null
|
||||
return null
|
||||
@@ -30,10 +30,11 @@
|
||||
attack_hand(var/mob/user as mob)
|
||||
if(stat & (NOPOWER|BROKEN)) return
|
||||
|
||||
user.machine = src
|
||||
if(!isAI(user))
|
||||
user.machine = src
|
||||
|
||||
var/list/L = list()
|
||||
for (var/obj/machinery/camera/C in Cameras)
|
||||
for (var/obj/machinery/camera/C in cameranet.cameras)
|
||||
L.Add(C)
|
||||
|
||||
camera_sort(L)
|
||||
@@ -56,14 +57,20 @@
|
||||
return 0
|
||||
|
||||
if(C)
|
||||
if ((get_dist(user, src) > 1 || user.machine != src || user.blinded || !( user.canmove ) || !( C.status )) && (!istype(user, /mob/living/silicon/ai)))
|
||||
if(!C.status)
|
||||
if ((get_dist(user, src) > 1 || user.machine != src || user.blinded || !( user.canmove ) || !( C.can_use() )) && (!istype(user, /mob/living/silicon/ai)))
|
||||
if(!C.can_use() && !isAI(user))
|
||||
src.current = null
|
||||
return 0
|
||||
else
|
||||
src.current = C
|
||||
use_power(50)
|
||||
spawn( 5 )
|
||||
if(isAI(user))
|
||||
var/mob/living/silicon/ai/A = user
|
||||
A.eyeobj.setLoc(get_turf(C))
|
||||
A.client.eye = A.eyeobj
|
||||
else
|
||||
src.current = C
|
||||
use_power(50)
|
||||
|
||||
spawn(5)
|
||||
attack_hand(user)
|
||||
return
|
||||
|
||||
|
||||
@@ -31,9 +31,8 @@ Possible to do for anyone motivated enough:
|
||||
/*There are pretty much only three ways to interact here.
|
||||
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.*/
|
||||
if(user.client.eye!=src)//Set client eye on the object if it's not already.
|
||||
user.current = src
|
||||
user.reset_view(src)
|
||||
if(user.eyeobj.loc != src.loc)//Set client eye on the object if it's not already.
|
||||
user.eyeobj.setLoc(get_turf(src))
|
||||
else if(!hologram)//If there is no hologram, possibly make one.
|
||||
activate_holo(user)
|
||||
else if(master==user)//If there is a hologram, remove it. But only if the user is the master. Otherwise do nothing.
|
||||
@@ -41,7 +40,7 @@ Possible to do for anyone motivated enough:
|
||||
return
|
||||
|
||||
/obj/machinery/hologram/holopad/proc/activate_holo(mob/living/silicon/ai/user)
|
||||
if(!(stat & NOPOWER)&&user.client.eye==src)//If the projector has power and client eye is on it.
|
||||
if(!(stat & NOPOWER) && user.eyeobj.loc == src.loc)//If the projector has power and client eye is on it.
|
||||
if(!hologram)//If there is not already a hologram.
|
||||
create_holo(user)//Create one.
|
||||
for(var/mob/M in viewers())
|
||||
@@ -76,6 +75,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
|
||||
hologram.name = "AI hologram"//If someone decides to right click.
|
||||
sd_SetLuminosity(1)//To make the pad glowy.
|
||||
icon_state = "holopad1"
|
||||
A.current = src
|
||||
master = A//AI is the master.
|
||||
use_power = 2//Active power usage.
|
||||
return 1
|
||||
@@ -83,6 +83,8 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
|
||||
/obj/machinery/hologram/holopad/proc/clear_holo()
|
||||
hologram.sd_SetLuminosity(0)//Clear lighting.
|
||||
del(hologram)//Get rid of hologram.
|
||||
if(master.current == src)
|
||||
master.current = null
|
||||
master = null//Null the master, since no-one is using it now.
|
||||
sd_SetLuminosity(0)//Clear lighting for the parent.
|
||||
icon_state = "holopad0"
|
||||
@@ -91,8 +93,8 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
|
||||
|
||||
/obj/machinery/hologram/holopad/process()
|
||||
if(hologram)//If there is a hologram.
|
||||
if(master&&!master.stat&&master.client&&master.client.eye==src)//If there is an AI attached, it's not incapacitated, it has a client, and the client eye is centered on the projector.
|
||||
if( !(get_dist(src,hologram.loc)>3||stat & NOPOWER) )//If the hologram is not out of bounds and the machine has power.
|
||||
if(master && !master.stat && master.client && master.eyeobj.loc == src.loc)//If there is an AI attached, it's not incapacitated, it has a client, and the client eye is centered on the projector.
|
||||
if(!(stat & NOPOWER))//If the machine has power.
|
||||
return 1
|
||||
clear_holo()//If not, we want to get rid of the hologram.
|
||||
return 1
|
||||
|
||||
@@ -184,7 +184,13 @@ Class Procs:
|
||||
return 0
|
||||
|
||||
/obj/machinery/attack_ai(mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
if(isrobot(user))
|
||||
// For some reason attack_robot doesn't work
|
||||
// This is to stop robots from using cameras to remotely control machines.
|
||||
if(user.client && user.client.eye == user)
|
||||
return src.attack_hand(user)
|
||||
else
|
||||
return src.attack_hand(user)
|
||||
|
||||
/obj/machinery/attack_paw(mob/user as mob)
|
||||
return src.attack_hand(user)
|
||||
|
||||
+1881
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,20 @@
|
||||
/mob/living/silicon/ai/proc/ai_statuschange()
|
||||
set category = "AI Commands"
|
||||
set name = "AI Status"
|
||||
|
||||
if(usr.stat == 2)
|
||||
usr <<"You cannot change your emotional status because you are dead!"
|
||||
return
|
||||
var/list/ai_emotions = list("Very Happy", "Happy", "Neutral", "Unsure", "Confused", "Sad", "BSOD", "Blank", "Problems?", "Awesome", "Facepalm", "Friend Computer")
|
||||
var/emote = input("Please, select a status!", "AI Status", null, null) in ai_emotions
|
||||
for (var/obj/machinery/ai_status_display/AISD in world) //change status
|
||||
spawn( 0 )
|
||||
AISD.emotion = emote
|
||||
for (var/obj/machinery/status_display/SD in world) //if Friend Computer, change ALL displays
|
||||
if(emote=="Friend Computer")
|
||||
spawn(0)
|
||||
SD.friendc = 1
|
||||
else
|
||||
spawn(0)
|
||||
SD.friendc = 0
|
||||
return
|
||||
@@ -58,7 +58,7 @@ var/intercom_range_display_status = 0
|
||||
del(C)
|
||||
|
||||
if(camera_range_display_status)
|
||||
for(var/obj/machinery/camera/C in Cameras)
|
||||
for(var/obj/machinery/camera/C in cameranet.cameras)
|
||||
new/obj/effect/debugging/camera_range(C.loc)
|
||||
feedback_add_details("admin_verb","mCRD") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
@@ -74,7 +74,7 @@ var/intercom_range_display_status = 0
|
||||
|
||||
var/list/obj/machinery/camera/CL = list()
|
||||
|
||||
for(var/obj/machinery/camera/C in Cameras)
|
||||
for(var/obj/machinery/camera/C in cameranet.cameras)
|
||||
CL += C
|
||||
|
||||
var/output = {"<B>CAMERA ANNOMALITIES REPORT</B><HR>
|
||||
|
||||
@@ -174,6 +174,21 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
L+=T
|
||||
usr.loc = pick(L)
|
||||
|
||||
/mob/dead/observer/verb/follow()
|
||||
set category = "Ghost"
|
||||
set name = "Follow" // "Haunt"
|
||||
set desc = "Follow and haunt a mob."
|
||||
|
||||
if(istype(usr, /mob/dead/observer))
|
||||
var/mob/target = input("Please, select a player!", "Jump to Mob", null, null) as null|anything in sortAtom(mob_list)
|
||||
if(target)
|
||||
spawn(0)
|
||||
var/turf/pos = get_turf(src)
|
||||
while(src.loc == pos)
|
||||
src.loc = get_turf(target)
|
||||
pos = src.loc
|
||||
sleep(15)
|
||||
|
||||
|
||||
/mob/dead/observer/verb/jumptomob() //Moves the ghost instead of just changing the ghosts's eye -Nodrak
|
||||
set category = "Ghost"
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
var/ioncheck[1]
|
||||
var/icon/holo_icon//Default is assigned when AI is created.
|
||||
var/obj/item/device/pda/ai/aiPDA = null
|
||||
var/obj/item/device/multitool/aiMulti = null
|
||||
|
||||
//MALFUNCTION
|
||||
var/datum/AI_Module/module_picker/malf_picker
|
||||
@@ -69,6 +70,8 @@
|
||||
aiPDA.ownjob = "AI"
|
||||
aiPDA.name = name + " (" + aiPDA.ownjob + ")"
|
||||
|
||||
aiMulti = new(src)
|
||||
|
||||
if (istype(loc, /turf))
|
||||
verbs.Add(/mob/living/silicon/ai/proc/ai_call_shuttle,/mob/living/silicon/ai/proc/ai_camera_track, \
|
||||
/mob/living/silicon/ai/proc/ai_camera_list, /mob/living/silicon/ai/proc/ai_network_change, \
|
||||
@@ -101,7 +104,7 @@
|
||||
|
||||
/mob/living/silicon/ai/verb/pick_icon()
|
||||
set category = "AI Commands"
|
||||
set name = "Change AI Core Display"
|
||||
set name = "Set AI Core Display"
|
||||
if(stat || aiRestorePowerRoutine)
|
||||
return
|
||||
|
||||
@@ -292,7 +295,7 @@
|
||||
machine = null
|
||||
src << browse(null, t1)
|
||||
if (href_list["switchcamera"])
|
||||
switchCamera(locate(href_list["switchcamera"]))
|
||||
switchCamera(locate(href_list["switchcamera"])) in cameranet.cameras
|
||||
if (href_list["showalerts"])
|
||||
ai_alerts()
|
||||
|
||||
@@ -325,15 +328,15 @@
|
||||
statelaws()
|
||||
|
||||
if (href_list["track"])
|
||||
var/mob/target = locate(href_list["track"])
|
||||
var/mob/living/silicon/ai/A = locate(href_list["track2"])
|
||||
var/mob/target = locate(href_list["track"]) in mob_list
|
||||
var/mob/living/silicon/ai/A = locate(href_list["track2"]) in mob_list
|
||||
if(A && target)
|
||||
A.ai_actual_track(target)
|
||||
return
|
||||
|
||||
else if (href_list["faketrack"])
|
||||
var/mob/target = locate(href_list["track"])
|
||||
var/mob/living/silicon/ai/A = locate(href_list["track2"])
|
||||
var/mob/target = locate(href_list["track"]) in mob_list
|
||||
var/mob/living/silicon/ai/A = locate(href_list["track2"]) in mob_list
|
||||
if(A && target)
|
||||
|
||||
A.cameraFollow = target
|
||||
@@ -437,14 +440,15 @@
|
||||
/mob/living/silicon/ai/proc/switchCamera(var/obj/machinery/camera/C)
|
||||
|
||||
src.cameraFollow = null
|
||||
if (!C || stat == 2 || !C.status || C.network != network)
|
||||
machine = null
|
||||
reset_view(null)
|
||||
if (!C || stat == 2 || !C.can_use())
|
||||
//machine = null
|
||||
//reset_view(null)
|
||||
return 0
|
||||
|
||||
// ok, we're alive, camera is good and in our network...
|
||||
eyeobj.setLoc(get_turf(C))
|
||||
machine = src
|
||||
reset_view(C)
|
||||
|
||||
return 1
|
||||
|
||||
/mob/living/silicon/ai/triggerAlarm(var/class, area/A, var/O, var/alarmsource)
|
||||
@@ -468,7 +472,7 @@
|
||||
C = O
|
||||
L[A.name] = list(A, (C) ? C : O, list(alarmsource))
|
||||
if (O)
|
||||
if (C && C.status)
|
||||
if (C && C.can_use())
|
||||
src << "--- [class] alarm detected in [A.name]! (<A HREF=?src=\ref[src];switchcamera=\ref[C]>[C.c_tag]</A>)"
|
||||
else if (CL && CL.len)
|
||||
var/foo = 0
|
||||
@@ -504,17 +508,17 @@
|
||||
/mob/living/silicon/ai/cancel_camera()
|
||||
set category = "AI Commands"
|
||||
set name = "Cancel Camera View"
|
||||
reset_view(null)
|
||||
machine = null
|
||||
//reset_view(null)
|
||||
//machine = null
|
||||
src.cameraFollow = null
|
||||
|
||||
|
||||
//Replaces /mob/living/silicon/ai/verb/change_network() in ai.dm & camera.dm
|
||||
//Adds in /mob/living/silicon/ai/proc/ai_network_change() instead
|
||||
//Addition by Mord_Sith to define AI's network change ability
|
||||
/mob/living/silicon/ai/proc/ai_network_change()
|
||||
set category = "AI Commands"
|
||||
set name = "Change Camera Network"
|
||||
reset_view(null)
|
||||
set name = "Jump To Network"
|
||||
machine = null
|
||||
src.cameraFollow = null
|
||||
var/cameralist[0]
|
||||
@@ -523,8 +527,10 @@
|
||||
usr << "You can't change your camera network because you are dead!"
|
||||
return
|
||||
|
||||
for (var/obj/machinery/camera/C in Cameras)
|
||||
if(!C.status)
|
||||
var/mob/living/silicon/ai/U = usr
|
||||
|
||||
for (var/obj/machinery/camera/C in cameranet.cameras)
|
||||
if(!C.can_use())
|
||||
continue
|
||||
if(C.network == "AI Satellite")
|
||||
if (ticker.mode.name == "AI malfunction")
|
||||
@@ -535,10 +541,17 @@
|
||||
else
|
||||
if(C.network != "CREED" && C.network != "thunder" && C.network != "RD" && C.network != "toxins" && C.network != "Prison")
|
||||
cameralist[C.network] = C.network
|
||||
|
||||
network = input(usr, "Which network would you like to view?") as null|anything in cameralist
|
||||
var/old_network = network
|
||||
network = input(U, "Which network would you like to view?") as null|anything in cameralist
|
||||
if(isnull(network))
|
||||
network = initial(network) // If nothing is selected, default to SS13 (or the initial network)
|
||||
network = old_network // If nothing is selected
|
||||
else
|
||||
for(var/obj/machinery/camera/C in cameranet.cameras)
|
||||
if(!C.can_use())
|
||||
continue
|
||||
if(C.network == network)
|
||||
U.eyeobj.setLoc(get_turf(C))
|
||||
break
|
||||
src << "\blue Switched to [network] camera network."
|
||||
//End of code by Mord_Sith
|
||||
|
||||
@@ -620,15 +633,39 @@
|
||||
|
||||
//Toggles the luminosity and applies it by re-entereing the camera.
|
||||
/mob/living/silicon/ai/proc/toggle_camera_light()
|
||||
set name = "Toggle camera light"
|
||||
set name = "Toggle Camera Light"
|
||||
set desc = "Toggles the light on the camera the AI is looking through."
|
||||
set category = "AI Commands"
|
||||
|
||||
if(!current)
|
||||
usr << "\red You are not looking through a camera right now."
|
||||
return
|
||||
camera_light_on = !camera_light_on
|
||||
reset_view(current)
|
||||
src << "Camera lights [camera_light_on ? "activated" : "deactivated"]."
|
||||
if(!camera_light_on)
|
||||
if(src.current)
|
||||
src.current.sd_SetLuminosity(0)
|
||||
else
|
||||
src.lightNearbyCamera()
|
||||
|
||||
|
||||
|
||||
// Handled camera lighting, when toggled.
|
||||
// It will get the nearest camera via range, it wouldn't matter
|
||||
|
||||
/mob/living/silicon/ai/proc/lightNearbyCamera(var/lum)
|
||||
if(camera_light_on && camera_light_on < world.timeofday)
|
||||
if(src.current)
|
||||
// I have to use range instead of view or the darkness gets in the way.
|
||||
var/camera = near_range_camera(src.eyeobj)
|
||||
if(camera && src.current != camera)
|
||||
src.current.sd_SetLuminosity(0)
|
||||
src.current = camera
|
||||
src.current.sd_SetLuminosity(lum)
|
||||
else if(isnull(camera))
|
||||
src.current.sd_SetLuminosity(0)
|
||||
src.current = null
|
||||
camera_light_on = world.timeofday + 1 * 10 // Update the light every 2 seconds.
|
||||
else
|
||||
src.current = near_range_camera(src.eyeobj)
|
||||
if(src.current) src.current.sd_SetLuminosity(lum)
|
||||
|
||||
|
||||
#undef AI_CAMERA_LUMINOSITY
|
||||
@@ -4,6 +4,7 @@
|
||||
icon_state = "ai-crash"
|
||||
|
||||
update_canmove()
|
||||
src.eyeobj.setLoc(get_turf(src))
|
||||
if(blind) blind.layer = 0
|
||||
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
|
||||
see_in_dark = 8
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
// CAMERA NET
|
||||
//
|
||||
// The datum containing all the chunks.
|
||||
|
||||
var/datum/cameranet/cameranet = new()
|
||||
|
||||
/datum/cameranet
|
||||
// The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del().
|
||||
var/list/cameras = list()
|
||||
// The chunks of the map, mapping the areas that the cameras can see.
|
||||
var/list/chunks = list()
|
||||
var/ready = 0
|
||||
|
||||
// Checks if a chunk has been Generated in x, y, z.
|
||||
/datum/cameranet/proc/chunkGenerated(x, y, z)
|
||||
x &= ~0xf
|
||||
y &= ~0xf
|
||||
var/key = "[x],[y],[z]"
|
||||
return key in chunks
|
||||
|
||||
// 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 &= ~0xf
|
||||
y &= ~0xf
|
||||
var/key = "[x],[y],[z]"
|
||||
if(!(key in chunks))
|
||||
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(mob/aiEye/ai)
|
||||
// 0xf = 15
|
||||
var/x1 = max(0, ai.x - 16) & ~0xf
|
||||
var/y1 = max(0, ai.y - 16) & ~0xf
|
||||
var/x2 = min(world.maxx, ai.x + 16) & ~0xf
|
||||
var/y2 = min(world.maxy, ai.y + 16) & ~0xf
|
||||
|
||||
var/list/visibleChunks = list()
|
||||
|
||||
for(var/x = x1; x <= x2; x += 16)
|
||||
for(var/y = y1; y <= y2; y += 16)
|
||||
visibleChunks += getCameraChunk(x, y, ai.z)
|
||||
|
||||
var/list/remove = ai.visibleCameraChunks - visibleChunks
|
||||
var/list/add = visibleChunks - ai.visibleCameraChunks
|
||||
|
||||
for(var/datum/camerachunk/c in remove)
|
||||
c.remove(ai)
|
||||
|
||||
for(var/datum/camerachunk/c in add)
|
||||
c.add(ai)
|
||||
|
||||
// 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, var/opacity_check = 1)
|
||||
|
||||
if(!ticker || (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)
|
||||
if(c.can_use())
|
||||
majorChunkChange(c, 1)
|
||||
|
||||
// Used for Cyborg cameras. It is the same as "add" but named differently for easier readability
|
||||
// and to allow the user know what it is for. Since portable cameras can be in ANY chunk, we have to
|
||||
// all it to be added to all chunks. If the camera is disabled, it will instead remove.
|
||||
|
||||
/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/c)
|
||||
if(c.can_use())
|
||||
majorChunkChange(c, 1)
|
||||
else
|
||||
majorChunkChange(c, 0)
|
||||
|
||||
// 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, var/choice)
|
||||
// 0xf = 15
|
||||
if(!c)
|
||||
return
|
||||
|
||||
var/turf/T = get_turf(c)
|
||||
if(T)
|
||||
var/x1 = max(0, T.x - 16) & ~0xf
|
||||
var/y1 = max(0, T.y - 16) & ~0xf
|
||||
var/x2 = min(world.maxx, T.x + 16) & ~0xf
|
||||
var/y2 = min(world.maxy, T.y + 16) & ~0xf
|
||||
|
||||
for(var/x = x1; x <= x2; x += 16)
|
||||
for(var/y = y1; y <= y2; y += 16)
|
||||
if(chunkGenerated(x, y, T.z))
|
||||
var/datum/camerachunk/chunk = getCameraChunk(x, y, T.z)
|
||||
if(choice == 0)
|
||||
// Remove the camera.
|
||||
chunk.cameras -= c
|
||||
else if(choice == 1)
|
||||
// You can't have the same camera in the list twice.
|
||||
chunk.cameras |= 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)
|
||||
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(position in chunk.visibleTurfs)
|
||||
return 1
|
||||
return 0
|
||||
@@ -0,0 +1,135 @@
|
||||
#define UPDATE_BUFFER 15
|
||||
|
||||
// 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.
|
||||
|
||||
/datum/camerachunk
|
||||
var/list/obscuredTurfs = list()
|
||||
var/list/visibleTurfs = list()
|
||||
var/list/obscured = list()
|
||||
var/list/cameras = list()
|
||||
var/list/turfs = list()
|
||||
var/list/seenby = list()
|
||||
var/visible = 0
|
||||
var/changed = 0
|
||||
var/updating = 0
|
||||
|
||||
// Add an AI eye to the chunk, then update if changed.
|
||||
|
||||
/datum/camerachunk/proc/add(mob/aiEye/ai)
|
||||
ai.visibleCameraChunks += src
|
||||
if(ai.ai.client)
|
||||
ai.ai.client.images += obscured
|
||||
visible++
|
||||
seenby += ai
|
||||
if(changed && !updating)
|
||||
update()
|
||||
|
||||
// Remove an AI eye from the chunk, then update if changed.
|
||||
|
||||
/datum/camerachunk/proc/remove(mob/aiEye/ai)
|
||||
ai.visibleCameraChunks -= src
|
||||
if(ai.ai.client)
|
||||
ai.ai.client.images -= obscured
|
||||
seenby -= ai
|
||||
if(visible > 0)
|
||||
visible--
|
||||
|
||||
// Called when a chunk has changed. I.E: A wall was deleted.
|
||||
|
||||
/datum/camerachunk/proc/visibilityChanged(turf/loc)
|
||||
if(!(loc in visibleTurfs))
|
||||
return
|
||||
|
||||
hasChanged()
|
||||
|
||||
// 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(var/update_now = 0)
|
||||
if(visible || update_now)
|
||||
if(!updating)
|
||||
updating = 1
|
||||
spawn(UPDATE_BUFFER) // Batch large changes, such as many doors opening or closing at once
|
||||
update()
|
||||
updating = 0
|
||||
else
|
||||
changed = 1
|
||||
|
||||
// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists.
|
||||
|
||||
/datum/camerachunk/proc/update()
|
||||
|
||||
var/list/newVisibleTurfs = list()
|
||||
|
||||
for(var/obj/machinery/camera/c in cameras)
|
||||
if(!c.can_use())
|
||||
continue
|
||||
var/turf/pos = get_turf(c)
|
||||
if(pos)
|
||||
for(var/turf/t in hear(7, pos))
|
||||
if(t in turfs)
|
||||
newVisibleTurfs += t
|
||||
|
||||
var/list/visAdded = newVisibleTurfs - visibleTurfs
|
||||
var/list/visRemoved = visibleTurfs - newVisibleTurfs
|
||||
|
||||
visibleTurfs = newVisibleTurfs
|
||||
obscuredTurfs = turfs - newVisibleTurfs
|
||||
|
||||
|
||||
for(var/turf/t in visAdded)
|
||||
if(t.obscured)
|
||||
obscured -= t.obscured
|
||||
for(var/mob/aiEye/m in seenby)
|
||||
if(m.ai.client)
|
||||
m.ai.client.images -= t.obscured
|
||||
|
||||
for(var/turf/t in visRemoved)
|
||||
if(t in obscuredTurfs)
|
||||
if(!t.obscured)
|
||||
t.obscured = image('effects/cameravis.dmi', t, "black", 15)
|
||||
|
||||
obscured += t.obscured
|
||||
for(var/mob/aiEye/m in seenby)
|
||||
if(!m)
|
||||
seenby -= m
|
||||
if(m.ai.client)
|
||||
m.ai.client.images += t.obscured
|
||||
|
||||
// Create a new camera chunk, since the chunks are made as they are needed.
|
||||
|
||||
/datum/camerachunk/New(loc, x, y, z)
|
||||
|
||||
// 0xf = 15
|
||||
x &= ~0xf
|
||||
y &= ~0xf
|
||||
|
||||
for(var/obj/machinery/camera/c in range(16, locate(x + 8, y + 8, z)))
|
||||
if(c.can_use())
|
||||
cameras += c
|
||||
|
||||
for(var/turf/t in range(10, locate(x + 8, y + 8, z)))
|
||||
|
||||
if(t.x >= x && t.y >= y && t.x < x + 16 && t.y < y + 16)
|
||||
turfs += t
|
||||
|
||||
for(var/obj/machinery/camera/c in cameras)
|
||||
if(!c.can_use())
|
||||
continue
|
||||
var/turf/pos = get_turf(c)
|
||||
if(pos)
|
||||
for(var/turf/t in hear(7, pos))
|
||||
if(t in turfs)
|
||||
visibleTurfs += t
|
||||
|
||||
obscuredTurfs = turfs - visibleTurfs
|
||||
|
||||
for(var/turf/t in obscuredTurfs)
|
||||
if(!t.obscured)
|
||||
t.obscured = image('effects/cameravis.dmi', t, "black", 15)
|
||||
obscured += t.obscured
|
||||
|
||||
#undef UPDATE_BUFFER
|
||||
@@ -0,0 +1,70 @@
|
||||
// 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/aiEye
|
||||
name = "Inactive AI Eye"
|
||||
var/list/visibleCameraChunks = list()
|
||||
var/mob/living/silicon/ai/ai = null
|
||||
density = 0
|
||||
nodamage = 1 // You can't damage it.
|
||||
|
||||
// Movement code. Returns 0 to stop air movement from moving it.
|
||||
/mob/aiEye/Move()
|
||||
return 0
|
||||
|
||||
// Use this when setting the aiEye's location.
|
||||
// It will also stream the chunk that the new loc is in.
|
||||
|
||||
/mob/aiEye/proc/setLoc(var/T)
|
||||
T = get_turf(T)
|
||||
loc = T
|
||||
cameranet.visibility(src)
|
||||
|
||||
// AI MOVEMENT
|
||||
|
||||
// The AI's "eye". Described on the top of the page.
|
||||
|
||||
/mob/living/silicon/ai/var/mob/aiEye/eyeobj = new()
|
||||
|
||||
// Intiliaze the eye by assigning it's "ai" variable to us. Then set it's loc to us.
|
||||
|
||||
/mob/living/silicon/ai/New()
|
||||
..()
|
||||
eyeobj.ai = src
|
||||
spawn(5)
|
||||
eyeobj.loc = src.loc
|
||||
eyeobj.name = "[src.name] (AI Eye)" // Give it a name
|
||||
|
||||
/mob/living/silicon/ai/Del()
|
||||
eyeobj.ai = null
|
||||
del(eyeobj) // No AI, no Eye
|
||||
..()
|
||||
|
||||
// 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/AIMove(n, direct, var/mob/living/silicon/ai/user)
|
||||
|
||||
user.eyeobj.setLoc(get_turf(get_step(user.eyeobj, direct)))
|
||||
user.cameraFollow = null
|
||||
src.eye = user.eyeobj
|
||||
//user.machine = null //Uncomment this if it causes problems.
|
||||
user.lightNearbyCamera()
|
||||
|
||||
|
||||
// Return to the Core.
|
||||
|
||||
/mob/living/silicon/ai/verb/core()
|
||||
set category = "AI Commands"
|
||||
set name = "AI Core"
|
||||
current = null
|
||||
cameraFollow = null
|
||||
machine = null
|
||||
src.eyeobj.loc = src.loc
|
||||
if(client && client.eye)
|
||||
client.eye = src
|
||||
for(var/datum/camerachunk/c in eyeobj.visibleCameraChunks)
|
||||
c.remove(eyeobj)
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
// CREDITS
|
||||
/*
|
||||
Initial code credit for this goes to Uristqwerty.
|
||||
Debugging, functionality, all comments and porting by Giacom.
|
||||
|
||||
Everything about freelook (or what we can put in here) will be stored here.
|
||||
|
||||
|
||||
WHAT IS THIS?
|
||||
|
||||
This is a replacement for the current camera movement system, of the AI. Before this, the AI had to move between cameras and could
|
||||
only see what the cameras could see. Not only this but the cameras could see through walls, which created problems.
|
||||
With this, the AI controls an "AI Eye" mob, which moves just like a ghost; such as moving through walls and being invisible to players.
|
||||
The AI's eye is set to this mob and then we use a system (explained below) to determine what the cameras around the AI Eye can and
|
||||
cannot see. If the camera cannot see a turf, it will black it out, otherwise it won't and the AI will be able to see it.
|
||||
This creates several features, such as.. no more see-through-wall cameras, easier to control camera movement, easier tracking,
|
||||
the AI only being able to track mobs which are visible to a camera, only trackable mobs appearing on the mob list and many more.
|
||||
|
||||
|
||||
HOW IT WORKS
|
||||
|
||||
It works by first creating a camera network datum. Inside of this camera network are "chunks" (which will be
|
||||
explained later) and "cameras". The cameras list is kept up to date by obj/machinery/camera/New() and Del().
|
||||
|
||||
Next the camera network has chunks. These chunks are a 16x16 tile block of turfs and cameras contained inside the chunk.
|
||||
These turfs are then sorted out based on what the cameras can and cannot see. If none of the cameras can see the turf, inside
|
||||
the 16x16 block, it is listed as an "obscured" turf. Meaning the AI won't be able to see it.
|
||||
|
||||
|
||||
HOW IT UPDATES
|
||||
|
||||
The camera network uses a streaming method in order to effeciently update chunks. Since the server will have doors opening, doors closing,
|
||||
turf being destroyed and other lag inducing stuff, we want to update it under certain conditions and not every tick.
|
||||
|
||||
The chunks are not created straight away, only when an AI eye moves into it's area is when it gets created.
|
||||
One a chunk is created, when a non glass door opens/closes or an opacity turf is destroyed, we check to see if an AI Eye is looking in the area.
|
||||
We do this with the "seenby" list, which updates everytime an AI is near a chunk. If there is an AI eye inside the area, we update the chunk
|
||||
that the changed atom is inside and all surrounding chunks, since a camera's vision could leak onto another chunk. If there is no AI Eye, we instead
|
||||
flag the chunk to update whenever it is loaded by an AI Eye. This is basically how the chunks update and keep it in sync. We then add some lag reducing
|
||||
measures, such as an UPDATE_BUFFER which stops a chunk from updating too many times in a certain time-frame, only updating if the changed atom was blocking
|
||||
sight; for example, we don't update glass airlocks or floors.
|
||||
|
||||
|
||||
WHERE IS EVERYTHING?
|
||||
|
||||
cameranet.dm = Everything about the cameranet datum.
|
||||
chunk.dm = Everything about the chunk datum.
|
||||
eye.dm = Everything about the AI and the AIEye.
|
||||
updating.dm = Everything about triggers that will update chunks.
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,76 @@
|
||||
//UPDATE TRIGGERS, when the chunk (and the surrounding chunks) should update.
|
||||
|
||||
// TURFS
|
||||
|
||||
/turf
|
||||
var/image/obscured
|
||||
|
||||
/turf/proc/visibilityChanged()
|
||||
cameranet.updateVisibility(src)
|
||||
|
||||
/atom/proc/move_camera_by_click()
|
||||
if(istype(usr, /mob/living/silicon/ai))
|
||||
var/mob/living/silicon/ai/AI = usr
|
||||
if(AI.client.eye == AI.eyeobj)
|
||||
AI.eyeobj.setLoc(src)
|
||||
|
||||
/turf/simulated/Del()
|
||||
visibilityChanged()
|
||||
..()
|
||||
|
||||
/turf/simulated/New()
|
||||
..()
|
||||
visibilityChanged()
|
||||
|
||||
// STRUCTURES
|
||||
|
||||
/obj/structure/Del()
|
||||
cameranet.updateVisibility(src)
|
||||
..()
|
||||
|
||||
/obj/structure/New()
|
||||
..()
|
||||
cameranet.updateVisibility(src)
|
||||
|
||||
// DOORS
|
||||
|
||||
// Simply updates the visibility of the area when it opens/closes/destroyed.
|
||||
/obj/machinery/door/update_nearby_tiles(need_rebuild)
|
||||
. = ..(need_rebuild)
|
||||
// Glass door glass = 1
|
||||
// don't check then?
|
||||
if(!glass)
|
||||
cameranet.updateVisibility(src, 0)
|
||||
|
||||
// ROBOT MOVEMENT
|
||||
|
||||
// Update the portable camera everytime the Robot moves.
|
||||
// This might be laggy, comment it out if there are problems.
|
||||
|
||||
/mob/living/silicon/robot/Move()
|
||||
. = ..()
|
||||
if(.)
|
||||
if(src.camera)
|
||||
cameranet.updatePortableCamera(src.camera)
|
||||
|
||||
// CAMERA
|
||||
|
||||
// An addition to deactivate which removes/adds the camera from the chunk list based on if it works or not.
|
||||
|
||||
/obj/machinery/camera/deactivate(user as mob, var/choice = 1)
|
||||
..(user, choice)
|
||||
if(src.can_use())
|
||||
cameranet.addCamera(src)
|
||||
else
|
||||
src.sd_SetLuminosity(0)
|
||||
cameranet.removeCamera(src)
|
||||
|
||||
/obj/machinery/camera/New()
|
||||
..()
|
||||
cameranet.cameras += src
|
||||
cameranet.addCamera(src)
|
||||
|
||||
/obj/machinery/camera/Del()
|
||||
cameranet.cameras -= src
|
||||
cameranet.removeCamera(src)
|
||||
..()
|
||||
@@ -22,4 +22,5 @@
|
||||
if(O)
|
||||
O.mode = 1
|
||||
O.emotion = "Neutral"
|
||||
src.core()
|
||||
return
|
||||
@@ -6,4 +6,5 @@
|
||||
if (client)
|
||||
client.eye = loc
|
||||
client.perspective = EYE_PERSPECTIVE
|
||||
src.core()
|
||||
return
|
||||
@@ -13,20 +13,6 @@
|
||||
var/obj/machinery/camera/closest = null
|
||||
var/atom/old = (user.current?user.current : user.loc)
|
||||
|
||||
if(istype(user.loc, /obj/item/clothing/suit/space/space_ninja))//To make ninja suit AI holograms work.
|
||||
var/obj/item/clothing/suit/space/space_ninja/S = user.loc//Ease of use.
|
||||
if(S.hologram)//If there is a hologram.
|
||||
S.hologram.loc = get_step(S.hologram, direct)
|
||||
S.hologram.dir = direct
|
||||
return//Whatever the case, return since you can't move anyway.
|
||||
|
||||
if(user.client)//To make AI holograms work. They will relay directions as long as they are centered on the object.
|
||||
var/obj/machinery/hologram/holopad/T = user.client.eye//Client eye centers on an object.
|
||||
if(istype(T)&&T.hologram&&T.master==user)//If there is a hologram and its master is the user.
|
||||
T.hologram.loc = get_step(T.hologram, direct)
|
||||
T.hologram.dir = direct
|
||||
return//Relay move and then return if that's the case.
|
||||
|
||||
if(!old) return
|
||||
|
||||
var/dx = 0
|
||||
@@ -43,7 +29,7 @@
|
||||
var/area/A = get_area(old)
|
||||
var/list/old_types = dd_text2list("[A.type]", "/")
|
||||
|
||||
for(var/obj/machinery/camera/current in Cameras)
|
||||
for(var/obj/machinery/camera/current in cameranet.cameras)
|
||||
if(user.network != current.network) continue
|
||||
if(!current.status) continue // ignore disabled cameras
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
modtype = "Synd"
|
||||
|
||||
radio = new /obj/item/device/radio/borg(src)
|
||||
if(!scrambledcodes)
|
||||
if(!scrambledcodes && !camera)
|
||||
camera = new /obj/machinery/camera(src)
|
||||
camera.c_tag = real_name
|
||||
camera.network = "SS13"
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
if(BORG_WIRE_CAMERA)
|
||||
if (!isnull(src.camera) && !scrambledcodes)
|
||||
src.camera.status = 1
|
||||
src.camera.deactivate(usr, 0) // Will kick anyone who is watching the Cyborg's camera.
|
||||
|
||||
src.interact(usr)
|
||||
|
||||
|
||||
@@ -26,9 +26,10 @@
|
||||
robot_talk(message)
|
||||
else if ((copytext(message, 1, 3) == ":h") || (copytext(message, 1, 3) == ":H"))
|
||||
if(isAI(src)&&client)//For patching directly into AI holopads.
|
||||
var/mob/living/silicon/ai/U = src
|
||||
message = copytext(message, 3)
|
||||
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
|
||||
holopad_talk(message)
|
||||
U.holopad_talk(message)
|
||||
else//Will not allow anyone by an active AI to use this function.
|
||||
src << "This function is not available to you."
|
||||
return
|
||||
@@ -38,7 +39,7 @@
|
||||
return ..(message)
|
||||
|
||||
//For holopads only. Usable by AI.
|
||||
/mob/living/proc/holopad_talk(var/message)
|
||||
/mob/living/silicon/ai/proc/holopad_talk(var/message)
|
||||
|
||||
log_say("[key_name(src)] : [message]")
|
||||
|
||||
@@ -47,8 +48,8 @@
|
||||
if (!message)
|
||||
return
|
||||
|
||||
var/obj/machinery/hologram/holopad/T = client.eye//Client eye centers on an object.
|
||||
if(istype(T)&&T.hologram&&T.master==src)//If there is a hologram and its master is the user.
|
||||
var/obj/machinery/hologram/holopad/T = locate(/obj/machinery/hologram/holopad) in src.eyeobj.loc
|
||||
if(istype(T) && T.hologram && T.master==src)//If there is a hologram and its master is the user.
|
||||
var/message_a = say_quote(message)
|
||||
|
||||
//Human-like, sorta, heard by those who understand humans.
|
||||
|
||||
@@ -744,6 +744,8 @@
|
||||
if (user.stat)
|
||||
user << "\red You must be conscious to use this [src]!"
|
||||
return 0
|
||||
if(!user.client)
|
||||
return 0
|
||||
if ( ! (istype(user, /mob/living/carbon/human) || \
|
||||
istype(user, /mob/living/silicon) || \
|
||||
istype(user, /mob/living/carbon/monkey) /*&& ticker && ticker.mode.name == "monkey"*/) )
|
||||
|
||||
@@ -49,6 +49,15 @@ should be listed in the changelog upon commit tho. Thanks. -->
|
||||
|
||||
<!-- To take advantage of the pretty new format (well it was new when I wrote this anyway), open the "add-to-changelog.html" file in any browser and add the stuff and then generate the html code and paste it here -->
|
||||
|
||||
<div class="commit sansserif">
|
||||
<h2 class="date">August 25, 2012</h2>
|
||||
<h3 class="author">Giacom updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="experiment">AIs can now look around like a ghost with the exception that they cannot see what cameras cannot see. Meaning if you're in maintenance, and there's no cameras near you, the AI will not know what you are doing. This also means there's no X-Ray vision cameras anymore.</li>
|
||||
<li class="tweak">AIs can add links to Telecommunication Machines. Added some cameras for areas that should have it but instead relied on cameras nearby for vision.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="commit sansserif">
|
||||
<h2 class="date">August 24, 2012</h2>
|
||||
<h3 class="author">Sieve updated:</h3>
|
||||
|
||||
+6292
-6289
File diff suppressed because it is too large
Load Diff
+311
@@ -5,6 +5,266 @@
|
||||
// END_INTERNALS
|
||||
// BEGIN_FILE_DIR
|
||||
#define FILE_DIR .
|
||||
#define FILE_DIR ".svn"
|
||||
#define FILE_DIR ".svn/pristine"
|
||||
#define FILE_DIR ".svn/pristine/00"
|
||||
#define FILE_DIR ".svn/pristine/01"
|
||||
#define FILE_DIR ".svn/pristine/02"
|
||||
#define FILE_DIR ".svn/pristine/03"
|
||||
#define FILE_DIR ".svn/pristine/04"
|
||||
#define FILE_DIR ".svn/pristine/05"
|
||||
#define FILE_DIR ".svn/pristine/06"
|
||||
#define FILE_DIR ".svn/pristine/07"
|
||||
#define FILE_DIR ".svn/pristine/08"
|
||||
#define FILE_DIR ".svn/pristine/09"
|
||||
#define FILE_DIR ".svn/pristine/0a"
|
||||
#define FILE_DIR ".svn/pristine/0b"
|
||||
#define FILE_DIR ".svn/pristine/0c"
|
||||
#define FILE_DIR ".svn/pristine/0d"
|
||||
#define FILE_DIR ".svn/pristine/0e"
|
||||
#define FILE_DIR ".svn/pristine/0f"
|
||||
#define FILE_DIR ".svn/pristine/10"
|
||||
#define FILE_DIR ".svn/pristine/11"
|
||||
#define FILE_DIR ".svn/pristine/12"
|
||||
#define FILE_DIR ".svn/pristine/13"
|
||||
#define FILE_DIR ".svn/pristine/14"
|
||||
#define FILE_DIR ".svn/pristine/15"
|
||||
#define FILE_DIR ".svn/pristine/16"
|
||||
#define FILE_DIR ".svn/pristine/17"
|
||||
#define FILE_DIR ".svn/pristine/18"
|
||||
#define FILE_DIR ".svn/pristine/19"
|
||||
#define FILE_DIR ".svn/pristine/1a"
|
||||
#define FILE_DIR ".svn/pristine/1b"
|
||||
#define FILE_DIR ".svn/pristine/1c"
|
||||
#define FILE_DIR ".svn/pristine/1d"
|
||||
#define FILE_DIR ".svn/pristine/1e"
|
||||
#define FILE_DIR ".svn/pristine/1f"
|
||||
#define FILE_DIR ".svn/pristine/20"
|
||||
#define FILE_DIR ".svn/pristine/21"
|
||||
#define FILE_DIR ".svn/pristine/22"
|
||||
#define FILE_DIR ".svn/pristine/23"
|
||||
#define FILE_DIR ".svn/pristine/24"
|
||||
#define FILE_DIR ".svn/pristine/25"
|
||||
#define FILE_DIR ".svn/pristine/26"
|
||||
#define FILE_DIR ".svn/pristine/27"
|
||||
#define FILE_DIR ".svn/pristine/28"
|
||||
#define FILE_DIR ".svn/pristine/29"
|
||||
#define FILE_DIR ".svn/pristine/2a"
|
||||
#define FILE_DIR ".svn/pristine/2b"
|
||||
#define FILE_DIR ".svn/pristine/2c"
|
||||
#define FILE_DIR ".svn/pristine/2d"
|
||||
#define FILE_DIR ".svn/pristine/2e"
|
||||
#define FILE_DIR ".svn/pristine/2f"
|
||||
#define FILE_DIR ".svn/pristine/30"
|
||||
#define FILE_DIR ".svn/pristine/31"
|
||||
#define FILE_DIR ".svn/pristine/32"
|
||||
#define FILE_DIR ".svn/pristine/33"
|
||||
#define FILE_DIR ".svn/pristine/34"
|
||||
#define FILE_DIR ".svn/pristine/35"
|
||||
#define FILE_DIR ".svn/pristine/36"
|
||||
#define FILE_DIR ".svn/pristine/37"
|
||||
#define FILE_DIR ".svn/pristine/38"
|
||||
#define FILE_DIR ".svn/pristine/39"
|
||||
#define FILE_DIR ".svn/pristine/3a"
|
||||
#define FILE_DIR ".svn/pristine/3b"
|
||||
#define FILE_DIR ".svn/pristine/3c"
|
||||
#define FILE_DIR ".svn/pristine/3d"
|
||||
#define FILE_DIR ".svn/pristine/3e"
|
||||
#define FILE_DIR ".svn/pristine/3f"
|
||||
#define FILE_DIR ".svn/pristine/40"
|
||||
#define FILE_DIR ".svn/pristine/41"
|
||||
#define FILE_DIR ".svn/pristine/42"
|
||||
#define FILE_DIR ".svn/pristine/43"
|
||||
#define FILE_DIR ".svn/pristine/44"
|
||||
#define FILE_DIR ".svn/pristine/45"
|
||||
#define FILE_DIR ".svn/pristine/46"
|
||||
#define FILE_DIR ".svn/pristine/47"
|
||||
#define FILE_DIR ".svn/pristine/48"
|
||||
#define FILE_DIR ".svn/pristine/49"
|
||||
#define FILE_DIR ".svn/pristine/4a"
|
||||
#define FILE_DIR ".svn/pristine/4b"
|
||||
#define FILE_DIR ".svn/pristine/4c"
|
||||
#define FILE_DIR ".svn/pristine/4d"
|
||||
#define FILE_DIR ".svn/pristine/4e"
|
||||
#define FILE_DIR ".svn/pristine/4f"
|
||||
#define FILE_DIR ".svn/pristine/50"
|
||||
#define FILE_DIR ".svn/pristine/51"
|
||||
#define FILE_DIR ".svn/pristine/52"
|
||||
#define FILE_DIR ".svn/pristine/53"
|
||||
#define FILE_DIR ".svn/pristine/54"
|
||||
#define FILE_DIR ".svn/pristine/55"
|
||||
#define FILE_DIR ".svn/pristine/56"
|
||||
#define FILE_DIR ".svn/pristine/57"
|
||||
#define FILE_DIR ".svn/pristine/58"
|
||||
#define FILE_DIR ".svn/pristine/59"
|
||||
#define FILE_DIR ".svn/pristine/5a"
|
||||
#define FILE_DIR ".svn/pristine/5b"
|
||||
#define FILE_DIR ".svn/pristine/5c"
|
||||
#define FILE_DIR ".svn/pristine/5d"
|
||||
#define FILE_DIR ".svn/pristine/5e"
|
||||
#define FILE_DIR ".svn/pristine/5f"
|
||||
#define FILE_DIR ".svn/pristine/60"
|
||||
#define FILE_DIR ".svn/pristine/61"
|
||||
#define FILE_DIR ".svn/pristine/62"
|
||||
#define FILE_DIR ".svn/pristine/63"
|
||||
#define FILE_DIR ".svn/pristine/64"
|
||||
#define FILE_DIR ".svn/pristine/65"
|
||||
#define FILE_DIR ".svn/pristine/66"
|
||||
#define FILE_DIR ".svn/pristine/67"
|
||||
#define FILE_DIR ".svn/pristine/68"
|
||||
#define FILE_DIR ".svn/pristine/69"
|
||||
#define FILE_DIR ".svn/pristine/6a"
|
||||
#define FILE_DIR ".svn/pristine/6b"
|
||||
#define FILE_DIR ".svn/pristine/6c"
|
||||
#define FILE_DIR ".svn/pristine/6d"
|
||||
#define FILE_DIR ".svn/pristine/6e"
|
||||
#define FILE_DIR ".svn/pristine/6f"
|
||||
#define FILE_DIR ".svn/pristine/70"
|
||||
#define FILE_DIR ".svn/pristine/71"
|
||||
#define FILE_DIR ".svn/pristine/72"
|
||||
#define FILE_DIR ".svn/pristine/73"
|
||||
#define FILE_DIR ".svn/pristine/74"
|
||||
#define FILE_DIR ".svn/pristine/75"
|
||||
#define FILE_DIR ".svn/pristine/76"
|
||||
#define FILE_DIR ".svn/pristine/77"
|
||||
#define FILE_DIR ".svn/pristine/78"
|
||||
#define FILE_DIR ".svn/pristine/79"
|
||||
#define FILE_DIR ".svn/pristine/7a"
|
||||
#define FILE_DIR ".svn/pristine/7b"
|
||||
#define FILE_DIR ".svn/pristine/7c"
|
||||
#define FILE_DIR ".svn/pristine/7d"
|
||||
#define FILE_DIR ".svn/pristine/7e"
|
||||
#define FILE_DIR ".svn/pristine/7f"
|
||||
#define FILE_DIR ".svn/pristine/80"
|
||||
#define FILE_DIR ".svn/pristine/81"
|
||||
#define FILE_DIR ".svn/pristine/82"
|
||||
#define FILE_DIR ".svn/pristine/83"
|
||||
#define FILE_DIR ".svn/pristine/84"
|
||||
#define FILE_DIR ".svn/pristine/85"
|
||||
#define FILE_DIR ".svn/pristine/86"
|
||||
#define FILE_DIR ".svn/pristine/87"
|
||||
#define FILE_DIR ".svn/pristine/88"
|
||||
#define FILE_DIR ".svn/pristine/89"
|
||||
#define FILE_DIR ".svn/pristine/8a"
|
||||
#define FILE_DIR ".svn/pristine/8b"
|
||||
#define FILE_DIR ".svn/pristine/8c"
|
||||
#define FILE_DIR ".svn/pristine/8d"
|
||||
#define FILE_DIR ".svn/pristine/8e"
|
||||
#define FILE_DIR ".svn/pristine/8f"
|
||||
#define FILE_DIR ".svn/pristine/90"
|
||||
#define FILE_DIR ".svn/pristine/91"
|
||||
#define FILE_DIR ".svn/pristine/92"
|
||||
#define FILE_DIR ".svn/pristine/93"
|
||||
#define FILE_DIR ".svn/pristine/94"
|
||||
#define FILE_DIR ".svn/pristine/95"
|
||||
#define FILE_DIR ".svn/pristine/96"
|
||||
#define FILE_DIR ".svn/pristine/97"
|
||||
#define FILE_DIR ".svn/pristine/98"
|
||||
#define FILE_DIR ".svn/pristine/99"
|
||||
#define FILE_DIR ".svn/pristine/9a"
|
||||
#define FILE_DIR ".svn/pristine/9b"
|
||||
#define FILE_DIR ".svn/pristine/9c"
|
||||
#define FILE_DIR ".svn/pristine/9d"
|
||||
#define FILE_DIR ".svn/pristine/9e"
|
||||
#define FILE_DIR ".svn/pristine/9f"
|
||||
#define FILE_DIR ".svn/pristine/a0"
|
||||
#define FILE_DIR ".svn/pristine/a1"
|
||||
#define FILE_DIR ".svn/pristine/a2"
|
||||
#define FILE_DIR ".svn/pristine/a3"
|
||||
#define FILE_DIR ".svn/pristine/a4"
|
||||
#define FILE_DIR ".svn/pristine/a5"
|
||||
#define FILE_DIR ".svn/pristine/a6"
|
||||
#define FILE_DIR ".svn/pristine/a7"
|
||||
#define FILE_DIR ".svn/pristine/a8"
|
||||
#define FILE_DIR ".svn/pristine/a9"
|
||||
#define FILE_DIR ".svn/pristine/aa"
|
||||
#define FILE_DIR ".svn/pristine/ab"
|
||||
#define FILE_DIR ".svn/pristine/ac"
|
||||
#define FILE_DIR ".svn/pristine/ad"
|
||||
#define FILE_DIR ".svn/pristine/ae"
|
||||
#define FILE_DIR ".svn/pristine/af"
|
||||
#define FILE_DIR ".svn/pristine/b0"
|
||||
#define FILE_DIR ".svn/pristine/b1"
|
||||
#define FILE_DIR ".svn/pristine/b2"
|
||||
#define FILE_DIR ".svn/pristine/b3"
|
||||
#define FILE_DIR ".svn/pristine/b4"
|
||||
#define FILE_DIR ".svn/pristine/b5"
|
||||
#define FILE_DIR ".svn/pristine/b6"
|
||||
#define FILE_DIR ".svn/pristine/b7"
|
||||
#define FILE_DIR ".svn/pristine/b8"
|
||||
#define FILE_DIR ".svn/pristine/b9"
|
||||
#define FILE_DIR ".svn/pristine/ba"
|
||||
#define FILE_DIR ".svn/pristine/bb"
|
||||
#define FILE_DIR ".svn/pristine/bc"
|
||||
#define FILE_DIR ".svn/pristine/bd"
|
||||
#define FILE_DIR ".svn/pristine/be"
|
||||
#define FILE_DIR ".svn/pristine/bf"
|
||||
#define FILE_DIR ".svn/pristine/c0"
|
||||
#define FILE_DIR ".svn/pristine/c1"
|
||||
#define FILE_DIR ".svn/pristine/c2"
|
||||
#define FILE_DIR ".svn/pristine/c3"
|
||||
#define FILE_DIR ".svn/pristine/c4"
|
||||
#define FILE_DIR ".svn/pristine/c5"
|
||||
#define FILE_DIR ".svn/pristine/c6"
|
||||
#define FILE_DIR ".svn/pristine/c7"
|
||||
#define FILE_DIR ".svn/pristine/c8"
|
||||
#define FILE_DIR ".svn/pristine/c9"
|
||||
#define FILE_DIR ".svn/pristine/ca"
|
||||
#define FILE_DIR ".svn/pristine/cb"
|
||||
#define FILE_DIR ".svn/pristine/cc"
|
||||
#define FILE_DIR ".svn/pristine/cd"
|
||||
#define FILE_DIR ".svn/pristine/ce"
|
||||
#define FILE_DIR ".svn/pristine/cf"
|
||||
#define FILE_DIR ".svn/pristine/d0"
|
||||
#define FILE_DIR ".svn/pristine/d1"
|
||||
#define FILE_DIR ".svn/pristine/d2"
|
||||
#define FILE_DIR ".svn/pristine/d3"
|
||||
#define FILE_DIR ".svn/pristine/d4"
|
||||
#define FILE_DIR ".svn/pristine/d5"
|
||||
#define FILE_DIR ".svn/pristine/d6"
|
||||
#define FILE_DIR ".svn/pristine/d7"
|
||||
#define FILE_DIR ".svn/pristine/d8"
|
||||
#define FILE_DIR ".svn/pristine/d9"
|
||||
#define FILE_DIR ".svn/pristine/da"
|
||||
#define FILE_DIR ".svn/pristine/db"
|
||||
#define FILE_DIR ".svn/pristine/dc"
|
||||
#define FILE_DIR ".svn/pristine/dd"
|
||||
#define FILE_DIR ".svn/pristine/de"
|
||||
#define FILE_DIR ".svn/pristine/df"
|
||||
#define FILE_DIR ".svn/pristine/e0"
|
||||
#define FILE_DIR ".svn/pristine/e1"
|
||||
#define FILE_DIR ".svn/pristine/e2"
|
||||
#define FILE_DIR ".svn/pristine/e3"
|
||||
#define FILE_DIR ".svn/pristine/e4"
|
||||
#define FILE_DIR ".svn/pristine/e5"
|
||||
#define FILE_DIR ".svn/pristine/e6"
|
||||
#define FILE_DIR ".svn/pristine/e7"
|
||||
#define FILE_DIR ".svn/pristine/e8"
|
||||
#define FILE_DIR ".svn/pristine/e9"
|
||||
#define FILE_DIR ".svn/pristine/ea"
|
||||
#define FILE_DIR ".svn/pristine/eb"
|
||||
#define FILE_DIR ".svn/pristine/ec"
|
||||
#define FILE_DIR ".svn/pristine/ed"
|
||||
#define FILE_DIR ".svn/pristine/ee"
|
||||
#define FILE_DIR ".svn/pristine/ef"
|
||||
#define FILE_DIR ".svn/pristine/f0"
|
||||
#define FILE_DIR ".svn/pristine/f1"
|
||||
#define FILE_DIR ".svn/pristine/f2"
|
||||
#define FILE_DIR ".svn/pristine/f3"
|
||||
#define FILE_DIR ".svn/pristine/f4"
|
||||
#define FILE_DIR ".svn/pristine/f5"
|
||||
#define FILE_DIR ".svn/pristine/f6"
|
||||
#define FILE_DIR ".svn/pristine/f7"
|
||||
#define FILE_DIR ".svn/pristine/f8"
|
||||
#define FILE_DIR ".svn/pristine/f9"
|
||||
#define FILE_DIR ".svn/pristine/fa"
|
||||
#define FILE_DIR ".svn/pristine/fb"
|
||||
#define FILE_DIR ".svn/pristine/fc"
|
||||
#define FILE_DIR ".svn/pristine/fd"
|
||||
#define FILE_DIR ".svn/pristine/fe"
|
||||
#define FILE_DIR ".svn/pristine/ff"
|
||||
#define FILE_DIR "bot"
|
||||
#define FILE_DIR "bot/Marakov"
|
||||
#define FILE_DIR "code"
|
||||
#define FILE_DIR "code/ATMOSPHERICS"
|
||||
#define FILE_DIR "code/ATMOSPHERICS/components"
|
||||
@@ -25,6 +285,7 @@
|
||||
#define FILE_DIR "code/game/area"
|
||||
#define FILE_DIR "code/game/asteroid"
|
||||
#define FILE_DIR "code/game/gamemodes"
|
||||
#define FILE_DIR "code/game/gamemodes/alien"
|
||||
#define FILE_DIR "code/game/gamemodes/blob"
|
||||
#define FILE_DIR "code/game/gamemodes/blob/blobs"
|
||||
#define FILE_DIR "code/game/gamemodes/changeling"
|
||||
@@ -121,6 +382,7 @@
|
||||
#define FILE_DIR "code/modules/mob/living/carbon/monkey"
|
||||
#define FILE_DIR "code/modules/mob/living/silicon"
|
||||
#define FILE_DIR "code/modules/mob/living/silicon/ai"
|
||||
#define FILE_DIR "code/modules/mob/living/silicon/ai/freelook"
|
||||
#define FILE_DIR "code/modules/mob/living/silicon/decoy"
|
||||
#define FILE_DIR "code/modules/mob/living/silicon/pai"
|
||||
#define FILE_DIR "code/modules/mob/living/silicon/robot"
|
||||
@@ -172,6 +434,38 @@
|
||||
#define FILE_DIR "code/WorkInProgress/mapload"
|
||||
#define FILE_DIR "code/WorkInProgress/organs"
|
||||
#define FILE_DIR "code/WorkInProgress/virus2"
|
||||
#define FILE_DIR "config"
|
||||
#define FILE_DIR "config/names"
|
||||
#define FILE_DIR "data"
|
||||
#define FILE_DIR "data/logs"
|
||||
#define FILE_DIR "data/logs/2012"
|
||||
#define FILE_DIR "data/logs/2012/07-July"
|
||||
#define FILE_DIR "data/logs/2012/08-August"
|
||||
#define FILE_DIR "data/player_saves"
|
||||
#define FILE_DIR "data/player_saves/c"
|
||||
#define FILE_DIR "data/player_saves/c/calasmere"
|
||||
#define FILE_DIR "data/player_saves/c/cheridan"
|
||||
#define FILE_DIR "data/player_saves/c/cindikate"
|
||||
#define FILE_DIR "data/player_saves/d"
|
||||
#define FILE_DIR "data/player_saves/d/darktechnomancer"
|
||||
#define FILE_DIR "data/player_saves/d/doohl"
|
||||
#define FILE_DIR "data/player_saves/g"
|
||||
#define FILE_DIR "data/player_saves/g/giacomand"
|
||||
#define FILE_DIR "data/player_saves/g/giacomt"
|
||||
#define FILE_DIR "data/player_saves/m"
|
||||
#define FILE_DIR "data/player_saves/m/milofaust"
|
||||
#define FILE_DIR "data/player_saves/n"
|
||||
#define FILE_DIR "data/player_saves/n/nodrak"
|
||||
#define FILE_DIR "data/player_saves/p"
|
||||
#define FILE_DIR "data/player_saves/p/petethegoat"
|
||||
#define FILE_DIR "data/player_saves/r"
|
||||
#define FILE_DIR "data/player_saves/r/rockdtben"
|
||||
#define FILE_DIR "data/player_saves/s"
|
||||
#define FILE_DIR "data/player_saves/s/s0ldi3rkr4s0"
|
||||
#define FILE_DIR "data/player_saves/t"
|
||||
#define FILE_DIR "data/player_saves/t/tanknut"
|
||||
#define FILE_DIR "data/player_saves/t/terranaut"
|
||||
#define FILE_DIR "data/player_saves/t/thunder12345"
|
||||
#define FILE_DIR "html"
|
||||
#define FILE_DIR "icons"
|
||||
#define FILE_DIR "icons/effects"
|
||||
@@ -186,6 +480,7 @@
|
||||
#define FILE_DIR "icons/obj/machines"
|
||||
#define FILE_DIR "icons/obj/pipes"
|
||||
#define FILE_DIR "icons/pda_icons"
|
||||
#define FILE_DIR "icons/PSD files"
|
||||
#define FILE_DIR "icons/spideros_icons"
|
||||
#define FILE_DIR "icons/Testing"
|
||||
#define FILE_DIR "icons/turf"
|
||||
@@ -194,6 +489,7 @@
|
||||
#define FILE_DIR "interface"
|
||||
#define FILE_DIR "maps"
|
||||
#define FILE_DIR "maps/RandomZLevels"
|
||||
#define FILE_DIR "music"
|
||||
#define FILE_DIR "sound"
|
||||
#define FILE_DIR "sound/AI"
|
||||
#define FILE_DIR "sound/ambience"
|
||||
@@ -206,8 +502,18 @@
|
||||
#define FILE_DIR "sound/piano"
|
||||
#define FILE_DIR "sound/voice"
|
||||
#define FILE_DIR "sound/weapons"
|
||||
#define FILE_DIR "SQL"
|
||||
#define FILE_DIR "tools"
|
||||
#define FILE_DIR "tools/Redirector"
|
||||
#define FILE_DIR "tools/Runtime Condenser"
|
||||
#define FILE_DIR "tools/UnstandardnessTestForDM"
|
||||
#define FILE_DIR "tools/UnstandardnessTestForDM/UnstandardnessTestForDM"
|
||||
#define FILE_DIR "tools/UnstandardnessTestForDM/UnstandardnessTestForDM/bin"
|
||||
#define FILE_DIR "tools/UnstandardnessTestForDM/UnstandardnessTestForDM/bin/Debug"
|
||||
#define FILE_DIR "tools/UnstandardnessTestForDM/UnstandardnessTestForDM/obj"
|
||||
#define FILE_DIR "tools/UnstandardnessTestForDM/UnstandardnessTestForDM/obj/x86"
|
||||
#define FILE_DIR "tools/UnstandardnessTestForDM/UnstandardnessTestForDM/obj/x86/Debug"
|
||||
#define FILE_DIR "tools/UnstandardnessTestForDM/UnstandardnessTestForDM/Properties"
|
||||
// END_FILE_DIR
|
||||
|
||||
// BEGIN_PREFERENCES
|
||||
@@ -989,6 +1295,11 @@
|
||||
#include "code\modules\mob\living\silicon\ai\logout.dm"
|
||||
#include "code\modules\mob\living\silicon\ai\move.dm"
|
||||
#include "code\modules\mob\living\silicon\ai\say.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\ai\freelook\read_me.dm"
|
||||
#include "code\modules\mob\living\silicon\ai\freelook\update_triggers.dm"
|
||||
#include "code\modules\mob\living\silicon\decoy\death.dm"
|
||||
#include "code\modules\mob\living\silicon\decoy\decoy.dm"
|
||||
#include "code\modules\mob\living\silicon\decoy\life.dm"
|
||||
|
||||
Reference in New Issue
Block a user