/
shuttle.dm
161 lines (134 loc) · 7.22 KB
/
shuttle.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
SUBSYSTEM_DEF(shuttle)
name = "Shuttle"
wait = 2 SECONDS
priority = SS_PRIORITY_SHUTTLE
init_order = SS_INIT_SHUTTLE //Should be initialized after all maploading is over and atoms are initialized, to ensure that landmarks have been initialized.
var/overmap_halted = FALSE //Whether ships can move on the overmap; used for adminbus.
var/list/ships = list() //List of all ships.
var/list/shuttles = list() //maps shuttle tags to shuttle datums, so that they can be looked up.
var/list/process_shuttles = list() //simple list of shuttles, for processing
var/list/registered_shuttle_landmarks = list()
var/last_landmark_registration_time
var/list/shuttle_logs = list() //Keeps records of shuttle movement, format is list(datum/shuttle = datum/shuttle_log)
var/list/shuttle_areas = list() //All the areas of all shuttles.
var/list/docking_registry = list() //Docking controller tag -> docking controller program, mostly for init purposes.
var/list/landmarks_awaiting_sector = list() //Stores automatic landmarks that are waiting for a sector to finish loading.
var/list/landmarks_still_needed = list() //Stores landmark_tags that need to be assigned to the sector (landmark_tag = sector) when registered.
var/list/shuttles_to_initialize //A queue for shuttles to initialize at the appropriate time.
var/list/sectors_to_initialize //Used to find all sector objects at the appropriate time.
var/block_queue = TRUE
var/list/working_shuttles
/datum/controller/subsystem/shuttle/Initialize(start_uptime)
last_landmark_registration_time = world.time
for(var/shuttle_type in subtypesof(/datum/shuttle)) // This accounts for most shuttles, though away maps can queue up more.
var/datum/shuttle/shuttle = shuttle_type
if(!initial(shuttle.defer_initialisation))
LAZYDISTINCTADD(shuttles_to_initialize, shuttle_type)
block_queue = FALSE
clear_init_queue()
/datum/controller/subsystem/shuttle/fire(resumed = FALSE)
if (!resumed)
working_shuttles = process_shuttles.Copy()
while (length(working_shuttles))
var/datum/shuttle/shuttle = working_shuttles[length(working_shuttles)]
LIST_DEC(working_shuttles)
if(shuttle.process_state && (shuttle.Process(wait, times_fired, src) == PROCESS_KILL))
process_shuttles -= shuttle
if (MC_TICK_CHECK)
return
/datum/controller/subsystem/shuttle/proc/clear_init_queue()
if(block_queue)
return
initialize_shuttles()
initialize_sectors()
/datum/controller/subsystem/shuttle/proc/initialize_shuttles()
var/list/shuttles_made = list()
for(var/shuttle_type in shuttles_to_initialize)
var/shuttle = initialize_shuttle(shuttle_type)
if(shuttle)
shuttles_made += shuttle
hook_up_motherships(shuttles_made)
shuttles_to_initialize = null
/datum/controller/subsystem/shuttle/proc/initialize_sectors()
for(var/sector in sectors_to_initialize)
initialize_sector(sector)
sectors_to_initialize = null
/datum/controller/subsystem/shuttle/proc/register_landmark(shuttle_landmark_tag, obj/shuttle_landmark/shuttle_landmark)
if (registered_shuttle_landmarks[shuttle_landmark_tag])
CRASH("Attempted to register shuttle landmark with tag [shuttle_landmark_tag], but it is already registered!")
if (istype(shuttle_landmark))
registered_shuttle_landmarks[shuttle_landmark_tag] = shuttle_landmark
last_landmark_registration_time = world.time
var/obj/overmap/visitable/O = landmarks_still_needed[shuttle_landmark_tag]
if(O) //These need to be added to sectors, which we handle.
try_add_landmark_tag(shuttle_landmark_tag, O)
landmarks_still_needed -= shuttle_landmark_tag
else if(istype(shuttle_landmark, /obj/shuttle_landmark/automatic)) //These find their sector automatically
O = map_sectors["[shuttle_landmark.z]"]
O ? O.add_landmark(shuttle_landmark, shuttle_landmark.shuttle_restricted) : (landmarks_awaiting_sector += shuttle_landmark)
/datum/controller/subsystem/shuttle/proc/get_landmark(shuttle_landmark_tag)
return registered_shuttle_landmarks[shuttle_landmark_tag]
//Checks if the given sector's landmarks have initialized; if so, registers them with the sector, if not, marks them for assignment after they come in.
//Also adds automatic landmarks that were waiting on their sector to spawn.
/datum/controller/subsystem/shuttle/proc/initialize_sector(obj/overmap/visitable/given_sector)
given_sector.populate_sector_objects() // This is a late init operation that sets up the sector's map_z and does non-overmap-related init tasks.
for(var/landmark_tag in given_sector.initial_generic_waypoints)
if(!try_add_landmark_tag(landmark_tag, given_sector))
landmarks_still_needed[landmark_tag] = given_sector
for(var/shuttle_name in given_sector.initial_restricted_waypoints)
for(var/landmark_tag in given_sector.initial_restricted_waypoints[shuttle_name])
if(!try_add_landmark_tag(landmark_tag, given_sector))
landmarks_still_needed[landmark_tag] = given_sector
var/landmarks_to_check = landmarks_awaiting_sector.Copy()
for(var/thing in landmarks_to_check)
var/obj/shuttle_landmark/automatic/landmark = thing
if(landmark.z in given_sector.map_z)
given_sector.add_landmark(landmark, landmark.shuttle_restricted)
landmarks_awaiting_sector -= landmark
/datum/controller/subsystem/shuttle/proc/try_add_landmark_tag(landmark_tag, obj/overmap/visitable/given_sector)
var/obj/shuttle_landmark/landmark = get_landmark(landmark_tag)
if(!landmark)
return
if(landmark.landmark_tag in given_sector.initial_generic_waypoints)
given_sector.add_landmark(landmark)
. = 1
for(var/shuttle_name in given_sector.initial_restricted_waypoints)
if(landmark.landmark_tag in given_sector.initial_restricted_waypoints[shuttle_name])
given_sector.add_landmark(landmark, shuttle_name)
. = 1
/datum/controller/subsystem/shuttle/proc/initialize_shuttle(shuttle_type)
var/datum/shuttle/shuttle = shuttle_type
if(initial(shuttle.category) != shuttle_type)
shuttle = new shuttle()
shuttle_areas |= shuttle.shuttle_area
return shuttle
/datum/controller/subsystem/shuttle/proc/hook_up_motherships(shuttles_list)
for(var/datum/shuttle/S in shuttles_list)
if(S.mothershuttle && !S.motherdock)
var/datum/shuttle/mothership = shuttles[S.mothershuttle]
if(mothership)
S.motherdock = S.current_location.landmark_tag
mothership.shuttle_area |= S.shuttle_area
else
error("Shuttle [S] was unable to find mothership [mothership]!")
/datum/controller/subsystem/shuttle/proc/toggle_overmap(new_setting)
if(overmap_halted == new_setting)
return
overmap_halted = !overmap_halted
for(var/ship in ships)
var/obj/overmap/visitable/ship/ship_effect = ship
overmap_halted ? ship_effect.halt() : ship_effect.unhalt()
/datum/controller/subsystem/shuttle/proc/ship_by_name(name)
for (var/obj/overmap/visitable/ship/ship in ships)
if (ship.name == name)
return ship
return null
/datum/controller/subsystem/shuttle/proc/ship_by_type(type)
for (var/obj/overmap/visitable/ship/ship in ships)
if (ship.type == type)
return ship
return null
/datum/controller/subsystem/shuttle/UpdateStat(time)
if (PreventUpdateStat(time))
return ..()
..("Shuttles [length(shuttles)] Ships [length(ships)] Landmarks [length(registered_shuttle_landmarks)] Halted [overmap_halted ? "Y" : "N"]")