-
-
Notifications
You must be signed in to change notification settings - Fork 452
/
baseturfs.dm
172 lines (143 loc) · 6.1 KB
/
baseturfs.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
/// Take off the top layer turf and replace it with the next baseturf down
/turf/proc/ScrapeAway(amount=1, flags)
if(!amount)
return
if(length(baseturfs))
var/list/new_baseturfs = baseturfs.Copy()
var/turf_type = new_baseturfs[max(1, new_baseturfs.len - amount + 1)]
while(ispath(turf_type, /turf/baseturf_skipover))
amount++
if(amount > new_baseturfs.len)
CRASH("The bottommost baseturf of a turf is a skipover [src]([type])")
turf_type = new_baseturfs[max(1, new_baseturfs.len - amount + 1)]
new_baseturfs.len -= min(amount, new_baseturfs.len - 1) // No removing the very bottom
if(new_baseturfs.len == 1)
new_baseturfs = new_baseturfs[1]
return ChangeTurf(turf_type, new_baseturfs, flags)
if(baseturfs == type)
return src
return ChangeTurf(baseturfs, baseturfs, flags) // The bottom baseturf will never go away
/// Places the given turf on the bottom of the turf stack.
/turf/proc/place_on_bottom(turf/bottom_turf)
baseturfs = baseturfs_string_list(
list(initial(bottom_turf.baseturfs), bottom_turf) + baseturfs,
src
)
/// Places a turf at the top of the stack
/turf/proc/place_on_top(turf/added_layer, flags)
var/list/turf/new_baseturfs = list()
new_baseturfs.Add(baseturfs)
if(isopenturf(src))
new_baseturfs.Add(type)
return ChangeTurf(added_layer, new_baseturfs, flags)
/// Places a turf on top - for map loading
/turf/proc/load_on_top(turf/added_layer, flags)
var/area/our_area = get_area(src)
flags = our_area.PlaceOnTopReact(list(baseturfs), added_layer, flags)
if(flags & CHANGETURF_SKIP) // We haven't been initialized
if(flags_1 & INITIALIZED_1)
stack_trace("CHANGETURF_SKIP was used in a PlaceOnTop call for a turf that's initialized. This is a mistake. [src]([type])")
assemble_baseturfs()
var/turf/new_turf
if(!length(baseturfs))
baseturfs = list(baseturfs)
var/list/old_baseturfs = baseturfs.Copy()
if(!isclosedturf(src))
old_baseturfs += type
new_turf = ChangeTurf(added_layer, null, flags)
new_turf.assemble_baseturfs(initial(added_layer.baseturfs)) // The baseturfs list is created like roundstart
if(!length(new_turf.baseturfs))
new_turf.baseturfs = list(baseturfs)
// The old baseturfs are put underneath, and we sort out the unwanted ones
new_turf.baseturfs = baseturfs_string_list(old_baseturfs + (new_turf.baseturfs - GLOB.blacklisted_automated_baseturfs), new_turf)
return new_turf
// Copy an existing turf and put it on top
// Returns the new turf
/turf/proc/CopyOnTop(turf/copytarget, ignore_bottom=1, depth=INFINITY, copy_air = FALSE, flags)
var/list/new_baseturfs = list()
new_baseturfs += baseturfs
new_baseturfs += type
if(depth)
var/list/target_baseturfs
if(length(copytarget.baseturfs))
// with default inputs this would be Copy(clamp(2, -INFINITY, baseturfs.len))
// Don't forget a lower index is lower in the baseturfs stack, the bottom is baseturfs[1]
target_baseturfs = copytarget.baseturfs.Copy(clamp(1 + ignore_bottom, 1 + copytarget.baseturfs.len - depth, copytarget.baseturfs.len))
else if(!ignore_bottom)
target_baseturfs = list(copytarget.baseturfs)
if(target_baseturfs)
target_baseturfs -= new_baseturfs & GLOB.blacklisted_automated_baseturfs
new_baseturfs += target_baseturfs
var/turf/newT = copytarget.copyTurf(src, copy_air, flags)
newT.baseturfs = baseturfs_string_list(new_baseturfs, newT)
return newT
/// Tries to find the given type in baseturfs.
/// If found, returns how deep it is for use in other baseturf procs, or null if it cannot be found.
/// For example, this number can be passed into ScrapeAway to scrape everything until that point.
/turf/proc/depth_to_find_baseturf(baseturf_type)
if(!islist(baseturfs))
return baseturfs == baseturf_type ? 1 : null
var/index = baseturfs.Find(baseturf_type)
if (index == 0)
return null
return baseturfs.len - index + 1
/// Returns the baseturf at the given depth.
/// For example, baseturf_at_depth(1) will give the baseturf that would show up when scraping once.
/turf/proc/baseturf_at_depth(index)
TEST_ONLY_ASSERT(isnum(index), "baseturf_at_depth must be given a number, received [index]")
if (islist(baseturfs))
return LAZYACCESS(baseturfs, baseturfs.len - index + 1)
else if (index == 1)
return baseturfs
else
return null
/// Replaces all instances of needle_type in baseturfs with replacement_type
/turf/proc/replace_baseturf(needle_type, replacement_type)
if (islist(baseturfs))
var/list/new_baseturfs
while (TRUE)
var/found_index = baseturfs.Find(needle_type)
if (found_index == 0)
break
new_baseturfs ||= baseturfs.Copy()
new_baseturfs[found_index] = replacement_type
if (!isnull(new_baseturfs))
baseturfs = baseturfs_string_list(new_baseturfs, src)
else if (baseturfs == needle_type)
baseturfs = replacement_type
/// Removes all baseturfs that are found in the given typecache.
/turf/proc/remove_baseturfs_from_typecache(list/typecache)
if (islist(baseturfs))
var/list/new_baseturfs
for (var/baseturf in baseturfs)
if (!typecache[baseturf])
continue
new_baseturfs ||= baseturfs.Copy()
new_baseturfs -= baseturf
if (!isnull(new_baseturfs))
baseturfs = baseturfs_string_list(new_baseturfs, src)
else if (typecache[baseturfs])
baseturfs = /turf/baseturf_bottom
/// Returns the total number of baseturfs
/turf/proc/count_baseturfs()
return islist(baseturfs) ? length(baseturfs) : 1
/// Inserts a baseturf at the given level.
/// "Level" here doesn't mean depth.
/// For example, `insert_baseturf(2, /turf/open/floor/plating)` will make it so
/// the 2nd to last turf in the list is plating.
/// This is different from *depth*, since depth is the level from the top.
/turf/proc/insert_baseturf(level, turf_type)
if (!islist(baseturfs))
assemble_baseturfs()
if(!islist(baseturfs))
baseturfs = list(baseturfs)
var/list/baseturfs_copy = baseturfs.Copy()
baseturfs_copy.Insert(level, turf_type)
baseturfs = baseturfs_string_list(baseturfs_copy, src)
/// Places a baseturf ontop of a searched for baseturf.
/turf/proc/stack_ontop_of_baseturf(floor, roof)
if (!islist(baseturfs))
baseturfs = list(baseturfs)
var/floor_position = baseturfs.Find(floor)
if(floor_position != 0)
insert_baseturf(floor_position + 1, roof)