diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm
index 64bfbc45a1d..bbe7f2763cd 100644
--- a/code/game/jobs/access.dm
+++ b/code/game/jobs/access.dm
@@ -96,24 +96,11 @@
/obj/var/req_one_access_txt = "0"
//returns 1 if this mob has sufficient access to use this object
-/obj/proc/allowed(mob/M)
- //check if it doesn't require any access at all
- if(src.check_access(null))
+/obj/proc/allowed(var/mob/M)
+ if(M.hasFullAccess()) // AI, robots, adminghosts, etc.
return 1
- if(istype(M, /mob/living/silicon))
- //AI can do whatever he wants
- return 1
- else if(istype(M, /mob/living/carbon/human))
- var/mob/living/carbon/human/H = M
- //if they are holding or wearing a card that has access, that works
- if(src.check_access(H.get_active_hand()) || src.check_access(H.wear_id))
- return 1
- else if(istype(M, /mob/living/carbon/monkey) || istype(M, /mob/living/carbon/alien/humanoid))
- var/mob/living/carbon/george = M
- //they can only hold things :(
- if(src.check_access(george.get_active_hand()))
- return 1
- return 0
+ var/list/ACL = M.GetAccess()
+ return can_access(ACL,req_access,req_one_access)
/obj/item/proc/GetAccess()
return list()
@@ -122,42 +109,8 @@
return null
/obj/proc/check_access(obj/item/I)
- //These generations have been moved out of /obj/New() because they were slowing down the creation of objects that never even used the access system.
- if(!src.req_access)
- src.req_access = list()
- if(src.req_access_txt)
- var/list/req_access_str = text2list(req_access_txt,";")
- for(var/x in req_access_str)
- var/n = text2num(x)
- if(n)
- req_access += n
-
- if(!src.req_one_access)
- src.req_one_access = list()
- if(src.req_one_access_txt)
- var/list/req_one_access_str = text2list(req_one_access_txt,";")
- for(var/x in req_one_access_str)
- var/n = text2num(x)
- if(n)
- req_one_access += n
-
- if(!istype(src.req_access, /list)) //something's very wrong
- return 1
-
- var/list/L = src.req_access
- if(!L.len && (!src.req_one_access || !src.req_one_access.len)) //no requirements
- return 1
- if(!I)
- return 0
- for(var/req in src.req_access)
- if(!(req in I.GetAccess())) //doesn't have this access
- return 0
- if(src.req_one_access && src.req_one_access.len)
- for(var/req in src.req_one_access)
- if(req in I.GetAccess()) //has an access from the single access list
- return 1
- return 0
- return 1
+ var/list/ACL = I.GetAccess()
+ return can_access(ACL,req_access,req_one_access)
/obj/proc/check_access_list(var/list/L)
@@ -176,6 +129,37 @@
return 0
return 1
+
+// /vg/ - Generic Access Checks.
+// Allows more flexible access checks.
+/proc/can_access(var/list/L, var/list/req_access=null,var/list/req_one_access=null)
+ // No perms set? He's in.
+ if(!req_access && !req_one_access)
+ return 1
+ // Fucked permissions set? He's in.
+ if(!istype(req_access, /list))
+ return 1
+ // Blank permissions set? He's in.
+ if(!req_access.len && (!req_one_access || !req_one_access.len))
+ return 1
+
+ // User doesn't have any accesses? Fuck off.
+ if(!L) return 0
+ if(!istype(L, /list)) return 0
+
+ // Doesn't have a req_access
+ for(var/req in req_access)
+ if(!(req in L)) //doesn't have this access
+ return 0
+
+ // If he has at least one req_one access, he's in.
+ if(req_one_access && req_one_access.len)
+ for(var/req in req_one_access)
+ if(req in L) //has an access from the single access list
+ return 1
+ return 0
+ return 1
+
/proc/get_centcom_access(job)
switch(job)
if("VIP Guest")
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index 7b5e1b08241..5bf9c1f56c0 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -24,6 +24,7 @@
var/atom/movable/following = null
var/medHUD = 0
+
/mob/dead/observer/New(var/mob/body=null, var/flags=1)
sight |= SEE_TURFS | SEE_MOBS | SEE_OBJS | SEE_SELF
see_invisible = SEE_INVISIBLE_OBSERVER
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index cd3c6a7d5de..585cb42a9e0 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1531,3 +1531,14 @@
M.apply_damage(50,BRUTE)
if(M.stat == 2)
M.gib()
+
+// Get ALL accesses available.
+/mob/living/carbon/human/GetAccess()
+ var/list/ACL=list()
+ var/obj/item/I = get_active_hand()
+ if(istype(I))
+ ACL |= I.GetAccess()
+ if(wear_id)
+ ACL |= wear_id.GetAccess()
+ return ACL
+
diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm
index ed193859ffa..db8bcce5129 100644
--- a/code/modules/mob/living/carbon/monkey/monkey.dm
+++ b/code/modules/mob/living/carbon/monkey/monkey.dm
@@ -497,3 +497,10 @@
if(!ticker.mode.name == "monkey") return 0
return 1
+// Get ALL accesses available.
+/mob/living/carbon/monkey/GetAccess()
+ var/list/ACL=list()
+ var/obj/item/I = get_active_hand()
+ if(istype(I))
+ ACL |= I.GetAccess()
+ return ACL
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index ba8e18c65d0..27d9df71cee 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -11,6 +11,12 @@
var/list/alarm_types_show = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0)
var/list/alarm_types_clear = list("Motion" = 0, "Fire" = 0, "Atmosphere" = 0, "Power" = 0, "Camera" = 0)
+/mob/living/silicon/hasFullAccess()
+ return 1
+
+/mob/living/silicon/GetAccess()
+ return get_all_accesses()
+
/mob/living/silicon/proc/cancelAlarm()
return
@@ -182,7 +188,6 @@
stat(null, "ETA-[(timeleft / 60) % 60]:[add_zero(num2text(timeleft % 60), 2)]")
-
// This adds the basic clock, shuttle recall timer, and malf_ai info to all silicon lifeforms
/mob/living/silicon/Stat()
..()
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index bf5a642abea..1c575eb417a 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -1204,4 +1204,12 @@ mob/proc/yank_out_object()
if(host)
host.ckey = src.ckey
- host << "You are now a mouse. Try to avoid interaction with players, and do not give hints away that you are more than a simple rodent."
\ No newline at end of file
+ host << "You are now a mouse. Try to avoid interaction with players, and do not give hints away that you are more than a simple rodent."
+
+// Mobs tell access what access levels it has.
+/mob/proc/GetAccess()
+ return list()
+
+// Skip over all the complex list checks.
+/mob/proc/hasFullAccess()
+ return 0
\ No newline at end of file