/
area_access.dm
55 lines (51 loc) · 2.45 KB
/
area_access.dm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/// List (`string (access_*)`). Access requirements for the area. Used for autosetting access on doors, etc.
/area/var/list/req_access = list()
/// Boolean. Whether or not the area is considered 'secure'. Unsecure areas will have doors between them use access diff; secure ones use union.
/area/var/secure = TRUE
// Given two areas, find the minimal req_access needed such that (return value) + (area access) >= (other area access) and vice versa
/proc/req_access_diff(area/first, area/second)
RETURN_TYPE(/list)
if(!length(first.req_access))
return second.req_access.Copy()
if(!length(second.req_access))
return first.req_access.Copy()
. = list()
for(var/requirement in first.req_access)
add_access_requirement(., get_minimal_requirement(second.req_access, requirement))
for(var/requirement in second.req_access)
add_access_requirement(., get_minimal_requirement(first.req_access, requirement))
// Given two areas, find the minimal req_access needed such that req_access >= (area access) + (other area access)
/proc/req_access_union(area/first, area/second)
RETURN_TYPE(/list)
if(!length(first.req_access))
return second.req_access.Copy()
if(!length(second.req_access))
return first.req_access.Copy()
. = first.req_access.Copy()
for(var/requirement in second.req_access)
add_access_requirement(., requirement)
// Comes up with the minimal thing to add to the first argument so that the new list guarantees that the access requirement in the second argument is satisfied.
// Second argument is a number access code or list thereof (like an entry in req_access); the typecasting is false.
/proc/get_minimal_requirement(list/req_access, list/requirement)
RETURN_TYPE(/list)
if(!requirement)
return
if(!islist(requirement))
return (requirement in req_access) ? null : requirement
for(var/req in req_access)
if(req in requirement)
return // have one of the requirements, and these use OR, so we're good
if(islist(req))
var/fully_contained = TRUE // In this case we check if we are already requiring something more stringent than the new thing.
for(var/one_req in req)
if(!(one_req in requirement))
fully_contained = FALSE
break
if(fully_contained)
return
return requirement.Copy()
// Modifies req_access in place. Ensures that the list remains miminal.
/proc/add_access_requirement(list/req_access, requirement)
var/minimal = get_minimal_requirement(req_access, requirement)
if(minimal)
req_access[LIST_PRE_INC(req_access)] = minimal