-
Notifications
You must be signed in to change notification settings - Fork 67
/
Copy pathdocking.dm
223 lines (181 loc) · 8.43 KB
/
docking.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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/// This is the main proc. It instantly moves our mobile port to stationary port `new_dock`.
/obj/docking_port/mobile/proc/initiate_docking(obj/docking_port/stationary/new_dock, movement_direction, force=FALSE)
// Crashing this ship with NO SURVIVORS
if(new_dock.get_docked() == src)
remove_ripples()
return DOCKING_SUCCESS
if(!force)
if(!check_dock(new_dock))
remove_ripples()
return DOCKING_BLOCKED
if(!canMove())
remove_ripples()
return DOCKING_IMMOBILIZED
var/obj/docking_port/stationary/old_dock = get_docked()
// The area that gets placed under where the shuttle moved from
var/underlying_area_type = SHUTTLE_DEFAULT_UNDERLYING_AREA
if(old_dock) //Dock overwrites
underlying_area_type = old_dock.area_type
/**************************************************************************************************************
Both lists are associative with a turf:bitflag structure. (new_turfs bitflag space unused currently)
The bitflag contains the data for what inhabitants of that coordinate should be moved to the new location
The bitflags can be found in __DEFINES/shuttles.dm
*/
var/list/old_turfs = return_ordered_turfs(x, y, z, dir)
var/list/new_turfs = return_ordered_turfs(new_dock.x, new_dock.y, new_dock.z, new_dock.dir)
CHECK_TICK
/**************************************************************************************************************/
// The underlying old area is the area assumed to be under the shuttle's starting location
// If it no longer/has never existed it will be created
var/area/underlying_old_area = GLOB.areas_by_type[underlying_area_type]
if(!underlying_old_area)
underlying_old_area = new underlying_area_type(null)
var/rotation = 0
if(new_dock.dir != dir) //Even when the dirs are the same rotation is coming out as not 0 for some reason
rotation = dir2angle(new_dock.dir)-dir2angle(dir)
if ((rotation % 90) != 0)
rotation += (rotation % 90) //diagonal rotations not allowed, round up
rotation = SIMPLIFY_DEGREES(rotation)
if(!movement_direction)
movement_direction = turn(preferred_direction, 180)
var/list/moved_atoms = list() //Everything not a turf that gets moved in the shuttle
var/list/areas_to_move = list() //unique assoc list of areas on turfs being moved
. = preflight_check(old_turfs, new_turfs, areas_to_move, rotation)
if(.)
remove_ripples()
return
/*******************************************Hiding turfs if necessary*******************************************/
// TODO: Move this somewhere sane
var/list/new_hidden_turfs
if(hidden)
new_hidden_turfs = list()
for(var/i in 1 to old_turfs.len)
CHECK_TICK
var/turf/oldT = old_turfs[i]
if(old_turfs[oldT] & MOVE_TURF)
new_hidden_turfs += new_turfs[i]
SSshuttle.update_hidden_docking_ports(null, new_hidden_turfs)
/***************************************************************************************************************/
if(!force)
if(!check_dock(new_dock))
remove_ripples()
return DOCKING_BLOCKED
if(!canMove())
remove_ripples()
return DOCKING_IMMOBILIZED
// Moving to the new location will trample the ripples there at the exact
// same time any mobs there are trampled, to avoid any discrepancy where
// the ripples go away before it is safe.
takeoff(old_turfs, new_turfs, moved_atoms, rotation, movement_direction, old_dock, underlying_old_area)
CHECK_TICK
cleanup_runway(new_dock, old_turfs, new_turfs, areas_to_move, moved_atoms, rotation, movement_direction, underlying_old_area)
CHECK_TICK
/*******************************************Unhiding turfs if necessary******************************************/
if(new_hidden_turfs)
SSshuttle.update_hidden_docking_ports(hidden_turfs, null)
hidden_turfs = new_hidden_turfs
/****************************************************************************************************************/
check_poddoors()
new_dock.last_dock_time = world.time
setDir(new_dock.dir)
// remove any stragglers just in case, and clear the list
remove_ripples()
return DOCKING_SUCCESS
/obj/docking_port/mobile/proc/preflight_check(list/old_turfs, list/new_turfs, list/areas_to_move, rotation)
for(var/i in 1 to length(old_turfs))
CHECK_TICK
var/turf/oldT = old_turfs[i]
var/turf/newT = new_turfs[i]
if(!newT)
return DOCKING_NULL_DESTINATION
if(!oldT)
return DOCKING_NULL_SOURCE
var/area/old_area = oldT.loc
var/move_mode = old_area.beforeShuttleMove(shuttle_areas) //areas
for(var/atom/movable/moving_atom as anything in oldT.contents)
CHECK_TICK
if(moving_atom.loc != oldT) //fix for multi-tile objects
continue
move_mode = moving_atom.beforeShuttleMove(newT, rotation, move_mode, src) //atoms
move_mode = oldT.fromShuttleMove(newT, move_mode) //turfs
move_mode = newT.toShuttleMove(oldT, move_mode, src) //turfs
if(move_mode & MOVE_AREA)
areas_to_move[old_area] = TRUE
old_turfs[oldT] = move_mode
/obj/docking_port/mobile/proc/takeoff(list/old_turfs, list/new_turfs, list/moved_atoms, rotation, movement_direction, old_dock, area/underlying_old_area)
for(var/i in 1 to old_turfs.len)
var/turf/oldT = old_turfs[i]
var/turf/newT = new_turfs[i]
var/move_mode = old_turfs[oldT]
if(move_mode & MOVE_TURF)
oldT.onShuttleMove(newT, movement_force, movement_direction) //turfs
if(move_mode & MOVE_AREA)
var/area/shuttle_area = oldT.loc
shuttle_area.onShuttleMove(oldT, newT, underlying_old_area) //areas
if(move_mode & MOVE_CONTENTS)
for(var/k in oldT)
var/atom/movable/moving_atom = k
if(moving_atom.loc != oldT) //fix for multi-tile objects
continue
moving_atom.onShuttleMove(newT, oldT, movement_force, movement_direction, old_dock, src) //atoms
moved_atoms[moving_atom] = oldT
/obj/docking_port/mobile/proc/cleanup_runway(obj/docking_port/stationary/new_dock, list/old_turfs, list/new_turfs, list/areas_to_move, list/moved_atoms, rotation, movement_direction, area/underlying_old_area)
underlying_old_area.afterShuttleMove(0)
// Parallax handling
// This needs to be done before the atom after move
var/new_parallax_dir = FALSE
if(istype(new_dock, /obj/docking_port/stationary/transit))
new_parallax_dir = preferred_direction
for(var/i in 1 to areas_to_move.len)
CHECK_TICK
var/area/internal_area = areas_to_move[i]
internal_area.afterShuttleMove(new_parallax_dir) //areas
for(var/i in 1 to old_turfs.len)
CHECK_TICK
if(!(old_turfs[old_turfs[i]] & MOVE_TURF))
continue
var/turf/old_turf = old_turfs[i]
var/turf/new_turf = new_turfs[i]
new_turf.afterShuttleMove(old_turf, rotation) //turfs
var/turf/new_ceiling = GetAbove(new_turf) // check if a ceiling is needed
if(new_ceiling)
// generate ceiling
if(istype(new_ceiling, /turf/open/openspace)) // why is this needed? because we have 2 different typepaths for openspace
new_ceiling.ChangeTurf(/turf/open/floor/engine/hull/ceiling, list(/turf/open/openspace))
else if (istype(new_ceiling, /turf/open/space/openspace))
new_ceiling.ChangeTurf(/turf/open/floor/engine/hull/ceiling, list(/turf/open/space/openspace))
var/turf/old_ceiling = GetAbove(old_turf)
if(old_ceiling && istype(old_ceiling, /turf/open/floor/engine/hull/ceiling)) // check if a ceiling was generated previously
// remove old ceiling
var/turf/open/floor/engine/hull/ceiling/old_shuttle_ceiling = old_ceiling
old_shuttle_ceiling.ChangeTurf(old_shuttle_ceiling.old_turf_type)
for(var/i in 1 to moved_atoms.len)
CHECK_TICK
var/atom/movable/moved_object = moved_atoms[i]
if(QDELETED(moved_object))
continue
var/turf/oldT = moved_atoms[moved_object]
moved_object.afterShuttleMove(oldT, movement_force, dir, preferred_direction, movement_direction, rotation, src)//atoms
// lateShuttleMove (There had better be a really good reason for additional stages beyond this)
underlying_old_area.lateShuttleMove()
for(var/i in 1 to areas_to_move.len)
CHECK_TICK
var/area/internal_area = areas_to_move[i]
internal_area.lateShuttleMove()
for(var/i in 1 to old_turfs.len)
CHECK_TICK
if(!(old_turfs[old_turfs[i]] & MOVE_CONTENTS | MOVE_TURF))
continue
var/turf/oldT = old_turfs[i]
var/turf/newT = new_turfs[i]
newT.lateShuttleMove(oldT)
for(var/i in 1 to moved_atoms.len)
CHECK_TICK
var/atom/movable/moved_object = moved_atoms[i]
if(QDELETED(moved_object))
continue
var/turf/oldT = moved_atoms[moved_object]
moved_object.lateShuttleMove(oldT, movement_force, movement_direction)
///THIS IS PROBABLY NOT THE ANSWER. BUT IT WORKS AND ISN'T TERRIBLY EXPENSIVE.
for(var/turf/T as anything in new_turfs)
SSzas.mark_for_update(T)