-
Notifications
You must be signed in to change notification settings - Fork 224
/
Copy pathmaps.dm
570 lines (462 loc) · 22.9 KB
/
maps.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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
var/global/datum/map/using_map = new USING_MAP_DATUM
var/global/list/all_maps = list()
var/global/list/votable_maps = list()
var/global/const/MAP_HAS_BRANCH = 1 //Branch system for occupations, toggleable
var/global/const/MAP_HAS_RANK = 2 //Rank system, also toggleable
/proc/initialise_map_list()
for(var/map_type in subtypesof(/datum/map))
var/datum/map/map_instance = map_type
if(TYPE_IS_ABSTRACT(map_instance))
continue
if(map_type == global.using_map.type)
map_instance = global.using_map
map_instance.setup_map()
else if(map_instance::path)
map_instance = new map_instance
else
log_error("Map '[map_type]' does not have a defined path, not adding to map list!")
continue
global.all_maps[map_instance.path] = map_instance
if(map_instance.votable)
global.votable_maps[map_instance.path] = map_instance
return 1
/datum/map
var/name = "Unnamed Map"
var/full_name = "Unnamed Map"
var/path
// TODO: move all the lobby stuff onto this handler.
var/lobby_handler = /decl/lobby_handler
var/list/allowed_jobs //Job datums to use.
//Works a lot better so if we get to a point where three-ish maps are used
//We don't have to C&P ones that are only common between two of them
//That doesn't mean we have to include them with the rest of the jobs though, especially for map specific ones.
//Also including them lets us override already created jobs, letting us keep the datums to a minimum mostly.
//This is probably a lot longer explanation than it needs to be.
var/station_name = "BAD Station"
var/station_short = "Baddy"
var/dock_name = "THE PirateBay"
var/boss_name = "Captain Roger"
var/boss_short = "Cap'"
var/company_name = "BadMan"
var/company_short = "BM"
var/system_name = "Uncharted System"
var/ground_noun = "ground"
var/default_announcement_frequency = "Common"
// Current game year. Uses current system year + game_year num.
var/game_year = 288
/**
* Associative list of network URIs to a list with their display name, color, and "req_access formated" needed access list.
* EX: list("BIG_BOSS.COM" = list("name" = "Big boss", "color" = "#00ff00", "access" = list(list(access_heads, access_clown))))
*/
var/list/map_admin_faxes
var/map_tech_level = MAP_TECH_LEVEL_SPACE
var/shuttle_docked_message
var/shuttle_leaving_dock
var/shuttle_called_message
var/shuttle_recall_message
var/emergency_shuttle_docked_message
var/emergency_shuttle_leaving_dock
var/emergency_shuttle_recall_message
var/list/holodeck_programs = list() // map of string ids to /datum/holodeck_program instances
var/list/holodeck_supported_programs = list() // map of maps - first level maps from list-of-programs string id (e.g. "BarPrograms") to another map
// this is in order to support multiple holodeck program listings for different holodecks
// second level maps from program friendly display names ("Picnic Area") to program string ids ("picnicarea")
// as defined in holodeck_programs
var/list/holodeck_restricted_programs = list() // as above... but EVIL!
var/list/holodeck_default_program = list() // map of program list string ids to default program string id
var/list/holodeck_off_program = list() // as above... but for being off i guess
var/allowed_latejoin_spawns = list(
/decl/spawnpoint/arrivals
)
var/default_spawn = /decl/spawnpoint/arrivals
var/flags = 0
var/evac_controller_type = /datum/evacuation_controller
var/list/overmap_ids // Assoc list of overmap ID to overmap type, leave empty to disable overmap.
var/pray_reward_type = /obj/item/food/cookie // What reward should be given by admin when a prayer is received?
// The list of lobby screen images to pick() from.
var/list/lobby_screens = list('icons/default_lobby.png')
var/current_lobby_screen
// The track that will play in the lobby screen.
var/decl/music_track/lobby_track
// The list of lobby tracks to pick() from. If left unset will randomly select among all available /music_track subtypes.
var/list/lobby_tracks = list()
// A server logo displayed on the taskbar and top-left part of the window. Leave null for the default DM icon.
var/window_icon
// Sounds played on roundstart
var/list/welcome_sound = 'sound/AI/welcome.ogg'
// Sounds played with end titles (credits)
var/list/credit_sound = list('sound/music/THUNDERDOME.ogg', 'sound/music/europa/Chronox_-_03_-_In_Orbit.ogg', 'sound/music/europa/asfarasitgets.ogg')
// Sounds played on server reboot
var/list/reboot_sound = list('sound/AI/newroundsexy.ogg','sound/misc/apcdestroyed.ogg','sound/misc/bangindonk.ogg')
var/default_law_type = /datum/ai_laws/asimov // The default lawset use by synth units, if not overriden by their laws var.
var/security_state = /decl/security_state/default // The default security state system to use.
var/hud_icons = 'icons/screen/hud.dmi' // Used by the ID HUD (primarily sechud) overlay.
var/implant_hud_icons = 'icons/screen/hud_implants.dmi'
var/med_hud_icons = 'icons/screen/hud_med.dmi'
var/num_exoplanets = 0
var/force_exoplanet_type // Used to override exoplanet weighting and always pick the same exoplanet.
//dimensions of planet zlevels, defaults to world size if smaller, INCREASES world size if larger.
//Due to how maps are generated, must be (2^n+1) e.g. 17,33,65,129 etc. Map will just round up to those if set to anything other.
var/list/planet_size = list()
///The amount of z-levels generated for exoplanets. Default is 1. Be careful with this, since exoplanets are already pretty expensive.
var/planet_depth = 1
var/away_site_budget = 0
var/list/loadout_blacklist //list of types of loadout items that will not be pickable
//Economy stuff
var/starting_money = 75000 // Money in station account
var/department_money = 5000 // Money in department accounts
var/salary_modifier = 1 // Multiplier to starting character money
var/passport_type = /obj/item/passport // Item type to grant people on join.
var/list/station_departments = list()//Gets filled automatically depending on jobs allowed
var/default_species = SPECIES_HUMAN
// Can this map be voted for by players?
var/votable = TRUE
var/list/available_background_info = list(
/decl/background_category/homeworld = list(/decl/background_detail/location/other),
/decl/background_category/faction = list(/decl/background_detail/faction/other),
/decl/background_category/heritage = list(/decl/background_detail/heritage/other),
/decl/background_category/religion = list(/decl/background_detail/religion/other)
)
var/list/default_background_info = list(
/decl/background_category/homeworld = /decl/background_detail/location/other,
/decl/background_category/faction = /decl/background_detail/faction/other,
/decl/background_category/heritage = /decl/background_detail/heritage/other,
/decl/background_category/religion = /decl/background_detail/religion/other
)
var/access_modify_region = list(
ACCESS_REGION_SECURITY = list(access_hos, access_change_ids),
ACCESS_REGION_MEDBAY = list(access_cmo, access_change_ids),
ACCESS_REGION_RESEARCH = list(access_rd, access_change_ids),
ACCESS_REGION_ENGINEERING = list(access_ce, access_change_ids),
ACCESS_REGION_COMMAND = list(access_change_ids),
ACCESS_REGION_GENERAL = list(access_change_ids),
ACCESS_REGION_SUPPLY = list(access_change_ids)
)
var/secrets_directory
/// A list of /decl/loadout_category types which will be available for characters made on this map. Uses all categories if null.
var/list/decl/loadout_category/loadout_categories
/// A list of survival box types selectable for this map. If null, defaults to all defined decls. At runtime, this is an associative list of decl type -> decl.
var/list/decl/survival_box_option/survival_box_choices
// A list of cash spawn options, similar to above.
var/list/decl/starting_cash_choice/starting_cash_choices
/// A reagent used to prefill lanterns.
var/default_liquid_fuel_type = /decl/material/liquid/fuel
/// Decl list of backpacks available to outfits and in character generation.
var/list/_available_backpacks
var/backpacks_setup = FALSE
var/list/char_preview_bgstate_options = list(
"000",
"midgrey",
"FFF",
"white",
"steel",
"techmaint",
"dark",
"plating",
"reinforced"
)
var/background_categories_generated = FALSE
var/list/_background_categories
var/default_ui_style
/datum/map/New()
..()
default_ui_style ||= DEFAULT_UI_STYLE
/datum/map/proc/get_background_categories()
if(!background_categories_generated)
if(isnull(_background_categories))
_background_categories = decls_repository.get_decls_of_type(/decl/background_category)
else
for(var/cat_type in _background_categories)
_background_categories[cat_type] = GET_DECL(cat_type)
background_categories_generated = TRUE
return _background_categories
/datum/map/proc/get_random_location()
var/list/options = list()
for(var/cat_type in available_background_info)
var/decl/background_category/background_cat = GET_DECL(cat_type)
if(istype(background_cat) && (background_cat.background_flags & BACKGROUND_FLAG_LOCATION))
options |= available_background_info[cat_type]
if(length(options))
return GET_DECL(pick(options))
return GET_DECL(/decl/background_detail/location/other)
/datum/map/proc/get_lobby_track(var/exclude)
var/lobby_track_type
if(LAZYLEN(lobby_tracks) == 1)
lobby_track_type = lobby_tracks[1]
else if(LAZYLEN(lobby_tracks))
lobby_track_type = pickweight(lobby_tracks - exclude)
else
lobby_track_type = pick(decls_repository.get_decl_paths_of_subtype(/decl/music_track) - exclude)
return GET_DECL(lobby_track_type)
/datum/map/proc/get_available_backpacks()
if(!backpacks_setup)
backpacks_setup = TRUE
if(length(_available_backpacks))
for(var/backpack_type in _available_backpacks)
_available_backpacks[backpack_type] = GET_DECL(backpack_type)
_available_backpacks[/decl/backpack_outfit/nothing] = GET_DECL(/decl/backpack_outfit/nothing)
else
_available_backpacks = decls_repository.get_decls_of_subtype(/decl/backpack_outfit)
return _available_backpacks
/datum/map/proc/setup_map()
if(!length(loadout_categories))
loadout_categories = list()
for(var/decl_type in decls_repository.get_decls_of_type(/decl/loadout_category))
loadout_categories += decl_type
for(var/loadout_category in loadout_categories)
loadout_categories -= loadout_category
loadout_categories += GET_DECL(loadout_category)
if(isnull(survival_box_choices)) // an empty list is a valid option here, a null one is not
survival_box_choices = decls_repository.get_decls_of_subtype(/decl/survival_box_option)
else if(length(survival_box_choices))
survival_box_choices = decls_repository.get_decls(survival_box_choices)
if(isnull(starting_cash_choices))
starting_cash_choices = decls_repository.get_decls_of_subtype(/decl/starting_cash_choice)
else if(length(starting_cash_choices))
starting_cash_choices = decls_repository.get_decls(starting_cash_choices)
if(secrets_directory)
secrets_directory = trim(lowertext(secrets_directory))
if(!length(secrets_directory))
log_warning("[type] secrets_directory is zero length after trim.")
if(copytext(secrets_directory, -1) != "/")
secrets_directory = "[secrets_directory]/"
if(!fexists(secrets_directory))
log_warning("[type] secrets_directory does not exist.")
SSsecrets.load_directories |= secrets_directory
if(!allowed_jobs)
allowed_jobs = list()
for(var/datum/job/job as anything in subtypesof(/datum/job))
if(!TYPE_IS_ABSTRACT(job) && job::available_by_default)
allowed_jobs += job
if(ispath(default_job_type, /datum/job))
var/datum/job/J = default_job_type
default_job_title = initial(J.title)
if(default_spawn && !(default_spawn in allowed_latejoin_spawns))
PRINT_STACK_TRACE("Map datum [type] has default spawn point [default_spawn] not in the allowed spawn list.")
for(var/spawn_type in allowed_latejoin_spawns)
allowed_latejoin_spawns -= spawn_type
allowed_latejoin_spawns += GET_DECL(spawn_type)
if(!SSmapping.map_levels)
SSmapping.map_levels = SSmapping.station_levels.Copy()
if(!LAZYLEN(planet_size))
planet_size = list(world.maxx, world.maxy)
if(planet_depth <= 0)
planet_depth = 1
game_year = (text2num(time2text(world.realtime, "YYYY")) + game_year)
setup_admin_faxes()
lobby_track = get_lobby_track()
update_titlescreen()
world.update_status()
///Generates the default admin faxes addresses
/datum/map/proc/setup_admin_faxes()
LAZYSET(map_admin_faxes, uppertext(replacetext("[boss_name].COM", " ", "_")), list("name" = "[boss_name]", "color" = "#006100", "access" = list(access_heads)))
LAZYSET(map_admin_faxes, uppertext(replacetext("[boss_short]_SUPPLY.COM", " ", "_")), list("name" = "[boss_short] Supply", "color" = "#5f4519", "access" = list(access_heads)))
LAZYSET(map_admin_faxes, uppertext(replacetext("[system_name]_POLICE.GOV", " ", "_")), list("name" = "[system_name] Police", "color" = "#1f66a0", "access" = list(access_heads)))
/datum/map/proc/setup_job_lists()
// Populate blacklists for any default-blacklisted species.
for(var/decl/species/species as anything in decls_repository.get_decls_of_subtype_unassociated(/decl/species))
if(!species.job_blacklist_by_default)
continue
var/found_whitelisted_job = FALSE
for(var/datum/job/job as anything in SSjobs.primary_job_datums)
if((species.type in job_to_species_whitelist[job.type]) || (job.type in species_to_job_whitelist[species.type]))
found_whitelisted_job = TRUE
else
LAZYDISTINCTADD(species_to_job_blacklist[species.type], job.type)
LAZYDISTINCTADD(job_to_species_blacklist[job.type], species.type)
// If no jobs are available for the main map, mark the species as unavailable to avoid player confusion.
if(!found_whitelisted_job && src == global.using_map)
species.spawn_flags &= ~SPECIES_CAN_JOIN
species.spawn_flags |= SPECIES_IS_RESTRICTED
/datum/map/proc/send_welcome()
return
/datum/map/proc/build_away_sites()
#ifdef UNIT_TEST
report_progress("Unit testing, so not loading away sites")
return // don't build away sites during unit testing
#else
report_progress("Loading away sites...")
var/list/sites_by_spawn_weight = list()
var/list/away_sites_templates = SSmapping.get_templates_by_category(MAP_TEMPLATE_CATEGORY_AWAYSITE)
for (var/site_name in away_sites_templates)
var/datum/map_template/site = away_sites_templates[site_name]
if((site.template_flags & TEMPLATE_FLAG_SPAWN_GUARANTEED) && site.load_new_z()) // no check for budget, but guaranteed means guaranteed
report_progress("Loaded guaranteed away site [site]!")
away_site_budget -= site.get_template_cost()
continue
sites_by_spawn_weight[site] = site.get_spawn_weight()
while (away_site_budget > 0 && sites_by_spawn_weight.len)
var/datum/map_template/selected_site = pickweight(sites_by_spawn_weight)
if (!selected_site)
break
sites_by_spawn_weight -= selected_site
var/site_cost = selected_site.get_template_cost()
if(site_cost > away_site_budget)
continue
if (selected_site.load_new_z())
report_progress("Loaded away site [selected_site]!")
away_site_budget -= site_cost
report_progress("Finished loading away sites, remaining budget [away_site_budget], remaining sites [sites_by_spawn_weight.len]")
#endif
/datum/map/proc/build_planets()
#ifdef UNIT_TEST
report_progress("Unit testing, so not loading planets.")
return
#else
report_progress("Instantiating planets...")
var/list/planets_spawn_weight = list()
var/list/planets_to_spawn = list()
//Fill up our lists of planets to spawn
generate_planet_spawn_lists(get_all_planet_templates(), planets_spawn_weight, planets_to_spawn)
//Pick the random planets we want to spawn
var/datum/map_template/planetoid/forced_planet = ispath(force_exoplanet_type)? SSmapping.get_template_by_type(force_exoplanet_type) : null
var/random_planets_to_pick = max(num_exoplanets - length(planets_to_spawn), 0) //subtract guaranteed planets
for(var/i = 0, i < random_planets_to_pick, i++)
planets_to_spawn += forced_planet || pickweight(planets_spawn_weight)
//Actually spawn the templates
spawn_planet_templates(planets_to_spawn)
report_progress("Finished instantiating planets.")
#endif
///Returns an associative list of all the planet templates we get to pick from. The key is the template name, and the value is the template instance.
/datum/map/proc/get_all_planet_templates()
. = list()
var/list/exoplanet_templates = SSmapping.get_templates_by_category(MAP_TEMPLATE_CATEGORY_EXOPLANET)
if(islist(exoplanet_templates))
. |= exoplanet_templates
var/list/planets_templates = SSmapping.get_templates_by_category(MAP_TEMPLATE_CATEGORY_PLANET)
if(islist(planets_templates))
. |= planets_templates
///Fill up the list of planet_spawn_weight and guaranteed_planets
/datum/map/proc/generate_planet_spawn_lists(var/list/planets_templates, var/list/planets_spawn_weight, var/list/guaranteed_planets)
for(var/template_name in planets_templates)
var/datum/map_template/planetoid/E = planets_templates[template_name]
if((E.template_flags & TEMPLATE_FLAG_SPAWN_GUARANTEED))
guaranteed_planets += E
else
planets_spawn_weight[E] = E.get_spawn_weight()
///Spawns all the templates in the given list, one after the other
/datum/map/proc/spawn_planet_templates(var/list/templates_to_spawn)
for(var/datum/map_template/planetoid/PT in templates_to_spawn)
PT.load_new_z()
#ifdef UNIT_TEST
log_unit_test("Loaded template '[PT]' ([PT.type]) at Z-level [world.maxz] with a tallness of [PT.tallness]")
#endif
// By default return a random accessible z-level, or the current level if one is unavailable
/datum/map/proc/get_transit_zlevel(var/current_z_level)
var/list/candidates = SSmapping.accessible_z_levels.Copy()
candidates.Remove(num2text(current_z_level))
if(!candidates.len)
return current_z_level
return text2num(pickweight(candidates))
/datum/map/proc/setup_economy()
news_network.CreateFeedChannel("News Daily", "Minister of Information", 1, 1)
news_network.CreateFeedChannel("The Gibson Gazette", "Editor Mike Hammers", 1, 1)
if(!station_account)
station_account = create_account("[station_name()] Primary Account", "[station_name()]", starting_money, ACCOUNT_TYPE_DEPARTMENT)
for(var/job in allowed_jobs)
var/datum/job/J = SSjobs.get_by_path(job)
var/list/dept = J.department_types
if(LAZYLEN(dept))
station_departments |= dept
for(var/department in station_departments)
var/decl/department/dept = SSjobs.get_department_by_type(department)
if(istype(dept))
department_accounts[department] = create_account("[dept.name] Account", "[dept.name]", department_money, ACCOUNT_TYPE_DEPARTMENT)
department_accounts["Vendor"] = create_account("Vendor Account", "Vendor", 0, ACCOUNT_TYPE_DEPARTMENT)
vendor_account = department_accounts["Vendor"]
/datum/map/proc/map_info(var/client/victim)
to_chat(victim, "<h2>Current map information</h2>")
to_chat(victim, get_map_info())
/datum/map/proc/get_map_info()
return "No map information available"
/datum/map/proc/bolt_saferooms()
return
/datum/map/proc/unbolt_saferooms()
return
/datum/map/proc/make_maint_all_access(var/radstorm = 0)
maint_all_access = 1
priority_announcement.Announce("The maintenance access requirement has been revoked on all maintenance airlocks.", "Attention!")
/datum/map/proc/revoke_maint_all_access(var/radstorm = 0)
maint_all_access = 0
priority_announcement.Announce("The maintenance access requirement has been readded on all maintenance airlocks.", "Attention!")
/datum/map/proc/show_titlescreen(client/C)
set waitfor = FALSE
winset(C, "lobbybrowser", "is-disabled=false;is-visible=true")
show_browser(C, current_lobby_screen, "file=titlescreen.gif;display=0")
if(isnewplayer(C.mob))
var/mob/new_player/player = C.mob
show_browser(C, player.get_lobby_browser_html(), "window=lobbybrowser")
/datum/map/proc/hide_titlescreen(client/C)
if(C.mob) // Check if the client is still connected to something
// Hide title screen, allowing player to see the map
winset(C, "lobbybrowser", "is-disabled=true;is-visible=false")
/datum/map/proc/update_titlescreen(new_screen)
current_lobby_screen = new_screen || pick(lobby_screens)
refresh_lobby_browsers()
/datum/map/proc/refresh_lobby_browsers()
for(var/mob/new_player/player in global.player_list)
show_titlescreen(player.client)
player.show_lobby_menu()
/datum/map/proc/create_trade_hubs()
new /datum/trade_hub/singleton
/datum/map/proc/get_radio_chatter_types()
return
/datum/map/proc/get_universe_end_evac_areas()
. = list(/area/space)
/datum/map/proc/get_specops_area()
return
/datum/map/proc/summarize_roundend_for(var/mob/player)
if(!player)
return
if(player.stat != DEAD)
var/turf/playerTurf = get_turf(player)
if(SSevac.evacuation_controller && SSevac.evacuation_controller.round_over() && SSevac.evacuation_controller.emergency_evacuation)
if(isNotAdminLevel(playerTurf.z))
to_chat(player, SPAN_NEUTRAL("<b>You managed to survive, but were marooned on [station_name()] as [player.real_name]...</b>"))
else
to_chat(player, SPAN_GOOD("<b>You managed to survive the events on [station_name()] as [player.real_name].</b>"))
else if(isAdminLevel(playerTurf.z))
to_chat(player, SPAN_GOOD("<b>You successfully underwent crew transfer after events on [station_name()] as [player.real_name].</b>"))
else if(issilicon(player))
to_chat(player, SPAN_GOOD("<b>You remain operational after the events on [station_name()] as [player.real_name].</b>"))
else
to_chat(player, SPAN_NEUTRAL("<b>You got through just another workday on [station_name()] as [player.real_name].</b>"))
else
if(isghost(player))
var/mob/observer/ghost/O = player
if(!O.started_as_observer)
to_chat(player, SPAN_BAD("<b>You did not survive the events on [station_name()]...</b>"))
else
to_chat(player, SPAN_BAD("<b>You did not survive the events on [station_name()]...</b>"))
/datum/map/proc/create_passport(var/mob/living/human/H)
if(!passport_type)
return
var/obj/item/passport/pass = new passport_type(get_turf(H))
if(istype(pass))
pass.set_info(H)
if(!H.equip_to_slot(pass, slot_in_backpack_str))
H.put_in_hands(pass)
/datum/map/proc/populate_overmap_events()
for(var/overmap_id in global.overmaps_by_name)
SSmapping.overmap_event_handler.create_events(global.overmaps_by_name[overmap_id])
/datum/map/proc/finalize_map_generation()
return
/datum/map/proc/validate()
. = TRUE
if(!length(SSmapping.player_levels))
log_error("[name] has no player levels!")
. = FALSE
if(!length(SSmapping.station_levels))
log_error("[name] has no station levels!")
. = FALSE
// TODO: add an admin level loaded from template for maps like tradeship (generic admin level modpack?)
/*
if(!length(SSmapping.admin_levels))
log_error("[name] has no admin levels!")
. = FALSE
*/
if(!length(SSmapping.contact_levels))
log_error("[name] has no contact levels!")
. = FALSE
/datum/map/proc/get_available_submap_archetypes()
return decls_repository.get_decls_of_subtype_unassociated(/decl/submap_archetype)