/
minimap.dm
140 lines (121 loc) · 5.04 KB
/
minimap.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
var/datum/subsystem/minimap/SSminimap
/datum/subsystem/minimap
name = "Minimap"
init_order = -2
flags = SS_NO_FIRE
var/const/MINIMAP_SIZE = 2048
var/const/TILE_SIZE = 8
var/list/z_levels = list(ZLEVEL_STATION)
/datum/subsystem/minimap/New()
NEW_SS_GLOBAL(SSminimap)
/datum/subsystem/minimap/Initialize(timeofday)
var/hash = md5(file2text("_maps/[MAP_PATH]/[MAP_FILE]"))
if(config.generate_minimaps)
if(hash == trim(file2text(hash_path())))
for(var/z in z_levels) //We have these files cached, let's register them
register_asset("minimap_[z].png", fcopy_rsc(map_path(z)))
return ..()
for(var/z in z_levels)
generate(z)
register_asset("minimap_[z].png", fcopy_rsc(map_path(z)))
fdel(hash_path())
text2file(hash, hash_path())
else
world << "<span class='boldannounce'>Minimap generation disabled. Loading from cache...</span>"
var/fileloc = 0
if(check_files(0)) //Let's first check if we have maps cached in the data folder. NOTE: This will override the backup files even if this map is older.
world.log << "cache"
if(hash != trim(file2text(hash_path())))
world << "<span class='boldannounce'>Loaded cached minimap is outdated. There may be minor discrepancies in layout.</span>" //Disclaimer against players saying map is wrong.
fileloc = 0
else
if(!check_files(1))
world << "<span class='boldannounce'>Failed to load backup minimap file. Aborting.</span>" //We couldn't find something. Bail to prevent issues with null files
return
fileloc = 1 //No map image cached with the current map, and we have a backup. Let's fall back to it.
world << "<span class='boldannounce'>No cached minimaps detected. Backup files loaded.</span>"
for(var/z in z_levels)
register_asset("minimap_[z].png", fcopy_rsc(map_path(z,fileloc)))
..()
/datum/subsystem/minimap/proc/check_files(backup) // If the backup argument is true, looks in the icons folder. If false looks in the data folder.
for(var/z in z_levels)
if(!fexists(file(map_path(z,backup)))) //Let's make sure we have a file for this map
if(backup)
world.log << "Failed to find backup file for map [MAP_NAME] on zlevel [z]."
return FALSE
return TRUE
/datum/subsystem/minimap/proc/hash_path(backup)
if(backup)
return "icons/minimaps/[MAP_NAME].md5"
else
return "data/minimaps/[MAP_NAME].md5"
/datum/subsystem/minimap/proc/map_path(z,backup)
if(backup)
return "icons/minimaps/[MAP_NAME]_[z].png"
else
return "data/minimaps/[MAP_NAME]_[z].png"
/datum/subsystem/minimap/proc/send(client/client)
for(var/z in z_levels)
send_asset(client, "minimap_[z].png")
/datum/subsystem/minimap/proc/generate(z = 1, x1 = 1, y1 = 1, x2 = world.maxx, y2 = world.maxy)
// Load the background.
var/icon/minimap = new /icon('icons/minimap.dmi')
// Scale it up to our target size.
minimap.Scale(MINIMAP_SIZE, MINIMAP_SIZE)
var/counter = 512
// Loop over turfs and generate icons.
for(var/T in block(locate(x1, y1, z), locate(x2, y2, z)))
generate_tile(T, minimap)
//byond bug, this fixes OOM crashes by flattening and reseting the minimap icon holder every so and so tiles
counter--
if(counter <= 0)
counter = 512
var/icon/flatten = new /icon()
flatten.Insert(minimap, "", SOUTH, 1, 0)
del(minimap)
minimap = flatten
stoplag() //we have to sleep in order to get byond to clear out the proc's garbage bin
CHECK_TICK
// Create a new icon and insert the generated minimap, so that BYOND doesn't generate different directions.
var/icon/final = new /icon()
final.Insert(minimap, "", SOUTH, 1, 0)
fcopy(final, map_path(z))
/datum/subsystem/minimap/proc/generate_tile(turf/tile, icon/minimap)
var/icon/tile_icon
var/obj/obj
var/list/obj_icons = list()
// Don't use icons for space, just add objects in space if they exist.
if(istype(tile, /turf/open/space))
obj = locate(/obj/structure/lattice/catwalk) in tile
if(obj)
tile_icon = new /icon('icons/obj/smooth_structures/catwalk.dmi', "catwalk", SOUTH)
obj = locate(/obj/structure/lattice) in tile
if(obj)
tile_icon = new /icon('icons/obj/smooth_structures/lattice.dmi', "lattice", SOUTH)
obj = locate(/obj/structure/grille) in tile
if(obj)
tile_icon = new /icon('icons/obj/structures.dmi', "grille", SOUTH)
obj = locate(/obj/structure/transit_tube) in tile
if(obj)
tile_icon = new /icon('icons/obj/atmospherics/pipes/transit_tube.dmi', obj.icon_state, obj.dir)
else
tile_icon = new /icon(tile.icon, tile.icon_state, tile.dir)
obj_icons.Cut()
obj = locate(/obj/structure) in tile
if(obj)
obj_icons += getFlatIcon(obj)
obj = locate(/obj/machinery) in tile
if(obj)
obj_icons += new /icon(obj.icon, obj.icon_state, obj.dir, 1, 0)
obj = locate(/obj/structure/window) in tile
if(obj)
obj_icons += new /icon('icons/obj/smooth_structures/window.dmi', "window", SOUTH)
for(var/I in obj_icons)
var/icon/obj_icon = I
tile_icon.Blend(obj_icon, ICON_OVERLAY)
if(tile_icon)
// Scale the icon.
tile_icon.Scale(TILE_SIZE, TILE_SIZE)
// Add the tile to the minimap.
minimap.Blend(tile_icon, ICON_OVERLAY, ((tile.x - 1) * TILE_SIZE), ((tile.y - 1) * TILE_SIZE))
del(tile_icon)