-
Notifications
You must be signed in to change notification settings - Fork 103
/
Copy pathareas.dm
177 lines (157 loc) · 6.12 KB
/
areas.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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#define BP_MAX_ROOM_SIZE 300
GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/engineering/main, \
/area/engineering/supermatter, \
/area/engineering/atmospherics_engine, \
/area/ai_monitored/turret_protected/ai))
// Gets an atmos isolated contained space
// Returns an associative list of turf|dirs pairs
// The dirs are connected turfs in the same space
// break_if_found is a typecache of turf/area types to return false if found
// Please keep this proc type agnostic. If you need to restrict it do it elsewhere or add an arg.
/proc/detect_room(turf/origin, list/break_if_found, max_size=INFINITY)
if(origin.blocks_air)
return list(origin)
. = list()
var/list/checked_turfs = list()
var/list/found_turfs = list(origin)
while(length(found_turfs))
var/turf/sourceT = found_turfs[1]
found_turfs.Cut(1, 2)
var/dir_flags = checked_turfs[sourceT]
for(var/dir in GLOB.alldirs)
if(length(.) > max_size)
return
if(dir_flags & dir) // This means we've checked this dir before, probably from the other turf
continue
var/turf/checkT = get_step(sourceT, dir)
if(!checkT)
continue
checked_turfs[sourceT] |= dir
checked_turfs[checkT] |= turn(dir, 180)
.[sourceT] |= dir
.[checkT] |= turn(dir, 180)
if(break_if_found[checkT.type] || break_if_found[checkT.loc.type])
return FALSE
var/static/list/cardinal_cache = list("[NORTH]"=TRUE, "[EAST]"=TRUE, "[SOUTH]"=TRUE, "[WEST]"=TRUE)
if(!cardinal_cache["[dir]"] || !TURFS_CAN_SHARE(sourceT, checkT))
continue
found_turfs += checkT // Since checkT is connected, add it to the list to be processed
/proc/create_area(mob/creator)
// Passed into the above proc as list/break_if_found
var/static/list/area_or_turf_fail_types = typecacheof(list(
/turf/open/space,
/area/shuttle,
))
// Ignore these areas and dont let people expand them. They can expand into them though
var/static/list/blacklisted_areas = typecacheof(list(
/area/space,
))
var/list/turfs = detect_room(get_turf(creator), area_or_turf_fail_types, BP_MAX_ROOM_SIZE*2)
if(!turfs)
to_chat(creator, span_warning("The new area must be completely airtight and not a part of a shuttle."))
return
if(length(turfs) > BP_MAX_ROOM_SIZE)
to_chat(creator, span_warning("The room you're in is too big. It is [length(turfs) >= BP_MAX_ROOM_SIZE *2 ? "more than 100" : ((length(turfs) / BP_MAX_ROOM_SIZE)-1)*100]% larger than allowed."))
return
var/list/areas = list("New Area" = /area)
for(var/i in 1 to length(turfs))
var/area/place = get_area(turfs[i])
if(blacklisted_areas[place.type])
continue
if(!place.requires_power || (place.area_flags & NOTELEPORT) || (place.area_flags & HIDDEN_AREA))
continue // No expanding powerless rooms etc
areas[place.name] = place
var/area_choice = tgui_input_list(creator, "Choose an area to expand or make a new area", "Area Expansion", areas)
if(isnull(area_choice))
to_chat(creator, span_warning("No choice selected. The area remains undefined."))
return
area_choice = areas[area_choice]
var/area/newA
var/area/oldA = get_area(get_turf(creator))
if(!isarea(area_choice))
var/str = tgui_input_text(creator, "New area name", "Blueprint Editing", max_length = MAX_NAME_LEN)
if(!str)
return
newA = new area_choice
newA.setup(str)
newA.has_gravity = oldA.has_gravity
else
newA = area_choice
for(var/i in 1 to length(turfs))
var/turf/thing = turfs[i]
var/area/old_area = thing.loc
newA.contents += thing
thing.change_area(old_area, newA)
newA.reg_in_areas_in_z()
if(!isarea(area_choice) && newA.static_lighting)
newA.create_area_lighting_objects()
var/list/firedoors = oldA.firedoors
for(var/door in firedoors)
var/obj/machinery/door/firedoor/FD = door
FD.CalculateAffectingAreas()
to_chat(creator, span_notice("You have created a new area, named [newA.name]. It is now weather proof, and constructing an APC will allow it to be powered."))
return TRUE
#undef BP_MAX_ROOM_SIZE
//Repopulates sortedAreas list
/proc/repopulate_sorted_areas()
GLOB.sortedAreas = list()
for(var/area/A in world)
GLOB.sortedAreas.Add(A)
sortTim(GLOB.sortedAreas, GLOBAL_PROC_REF(cmp_name_asc))
/area/proc/addSorted()
GLOB.sortedAreas.Add(src)
sortTim(GLOB.sortedAreas, GLOBAL_PROC_REF(cmp_name_asc))
//Takes: Area type as a text string from a variable.
//Returns: Instance for the area in the world.
/proc/get_area_instance_from_text(areatext)
if(istext(areatext))
areatext = text2path(areatext)
return GLOB.areas_by_type[areatext]
//Takes: Area type as text string or as typepath OR an instance of the area.
//Returns: A list of all areas of that type in the world.
/proc/get_areas(areatype, subtypes=TRUE)
if(istext(areatype))
areatype = text2path(areatype)
else if(isarea(areatype))
var/area/areatemp = areatype
areatype = areatemp.type
else if(!ispath(areatype))
return null
var/list/areas = list()
if(subtypes)
var/list/cache = typecacheof(areatype)
for(var/area/area_to_check as anything in GLOB.sortedAreas)
if(cache[area_to_check.type])
areas += area_to_check
else
for(var/area/area_to_check as anything in GLOB.sortedAreas)
if(area_to_check.type == areatype)
areas += area_to_check
return areas
//Takes: Area type as text string or as typepath OR an instance of the area.
//Returns: A list of all turfs in areas of that type of that type in the world.
/proc/get_area_turfs(areatype, target_z = 0, subtypes=FALSE)
if(istext(areatype))
areatype = text2path(areatype)
else if(isarea(areatype))
var/area/areatemp = areatype
areatype = areatemp.type
else if(!ispath(areatype))
return null
var/list/turfs = list()
if(subtypes)
var/list/cache = typecacheof(areatype)
for(var/area/area_to_check as anything in GLOB.sortedAreas)
if(!cache[area_to_check.type])
continue
for(var/turf/turf_in_area in area_to_check)
if(target_z == 0 || target_z == turf_in_area.z)
turfs += turf_in_area
else
for(var/area/area_to_check as anything in GLOB.sortedAreas)
if(area_to_check.type != areatype)
continue
for(var/turf/turf_in_area in area_to_check)
if(target_z == 0 || target_z == turf_in_area.z)
turfs += turf_in_area
return turfs