Initial implementation of holomaps!

This commit is contained in:
Leshana
2017-05-19 15:15:46 -04:00
parent f2623513d8
commit 8b34429c3e
13 changed files with 706 additions and 1 deletions

49
code/__defines/holomap.dm Normal file
View File

@@ -0,0 +1,49 @@
//
// Constants and standard colors for the holomap
//
#define WORLD_ICON_SIZE 32 // Size of a standard tile in pixels (world.icon_size)
#define PIXEL_MULTIPLIER WORLD_ICON_SIZE/32 // Convert from normal icon size of 32 to whatever insane thing this server is using.
#define HOLOMAP_ICON 'icons/480x480_vr.dmi' // Icon file to start with when drawing holomaps (to get a 480x480 canvas).
#define ui_holomap "CENTER-7, CENTER-7" // Screen location of the holomap "hud"
// Holomap colors
#define HOLOMAP_OBSTACLE "#FFFFFFDD" // Color of walls and barriers
#define HOLOMAP_PATH "#66666699" // Color of floors
#define HOLOMAP_ROCK "#66666644" // Color of mineral walls
#define HOLOMAP_HOLOFIER "#79FF79" // Whole map is multiplied by this to give it a green holoish look
#define HOLOMAP_AREACOLOR_COMMAND "#0000F099"
#define HOLOMAP_AREACOLOR_SECURITY "#AE121299"
#define HOLOMAP_AREACOLOR_MEDICAL "#447FC299"
#define HOLOMAP_AREACOLOR_SCIENCE "#A154A699"
#define HOLOMAP_AREACOLOR_ENGINEERING "#F1C23199"
#define HOLOMAP_AREACOLOR_CARGO "#E06F0099"
#define HOLOMAP_AREACOLOR_HALLWAYS "#FFFFFF66"
#define HOLOMAP_AREACOLOR_ARRIVALS "#0000FFCC"
#define HOLOMAP_AREACOLOR_ESCAPE "#FF0000CC"
#define HOLOMAP_AREACOLOR_DORMS "#CCCC0099"
// Handy defines to lookup the pixel offsets for this Z-level. Cache these if you use them in a loop tho.
#define HOLOMAP_PIXEL_OFFSET_X(zLevel) ((using_map.holomap_offset_x.len >= zLevel) ? using_map.holomap_offset_x[zLevel] : 0)
#define HOLOMAP_PIXEL_OFFSET_Y(zLevel) ((using_map.holomap_offset_y.len >= zLevel) ? using_map.holomap_offset_y[zLevel] : 0)
#define HOLOMAP_LEGEND_X(zLevel) ((using_map.holomap_legend_x.len >= zLevel) ? using_map.holomap_legend_x[zLevel] : 96)
#define HOLOMAP_LEGEND_Y(zLevel) ((using_map.holomap_legend_y.len >= zLevel) ? using_map.holomap_legend_y[zLevel] : 96)
// VG stuff we probably won't use
// #define HOLOMAP_FILTER_DEATHSQUAD 1
// #define HOLOMAP_FILTER_ERT 2
// #define HOLOMAP_FILTER_NUKEOPS 4
// #define HOLOMAP_FILTER_ELITESYNDICATE 8
// #define HOLOMAP_FILTER_VOX 16
// #define HOLOMAP_FILTER_STATIONMAP 32
// #define HOLOMAP_FILTER_STATIONMAP_STRATEGIC 64//features markers over the captain's office, the armory, the SMES
// #define HOLOMAP_MARKER_SMES "smes"
// #define HOLOMAP_MARKER_DISK "diskspawn"
// #define HOLOMAP_MARKER_SKIPJACK "skipjack"
// #define HOLOMAP_MARKER_SYNDISHUTTLE "syndishuttle"
#define HOLOMAP_EXTRA_STATIONMAP "stationmapformatted"
#define HOLOMAP_EXTRA_STATIONMAPAREAS "stationareas"
#define HOLOMAP_EXTRA_STATIONMAPSMALL "stationmapsmall"

View File

@@ -12,7 +12,8 @@ var/list/global_huds = list(
global_hud.nvg,
global_hud.thermal,
global_hud.meson,
global_hud.science
global_hud.science,
global_hud.holomap
)
/datum/hud/var/obj/screen/grab_intent
@@ -30,6 +31,7 @@ var/list/global_huds = list(
var/obj/screen/thermal
var/obj/screen/meson
var/obj/screen/science
var/obj/screen/holomap
/datum/global_hud/proc/setup_overlay(var/icon_state)
var/obj/screen/screen = new /obj/screen()
@@ -69,6 +71,18 @@ var/list/global_huds = list(
meson = setup_overlay("meson_hud")
science = setup_overlay("science_hud")
// The holomap screen object is actually totally invisible.
// Station maps work by setting it as an images location before sending to client, not
// actually changing the icon or icon state of the screen object itself!
// Why do they work this way? I don't know really, that is how /vg designed them, but since they DO
// work this way, we can take advantage of their immutability by making them part of
// the global_hud (something we have and /vg doesn't) instead of an instance per mob.
holomap = new /obj/screen()
holomap.name = "holomap"
holomap.icon = null
holomap.screen_loc = ui_holomap
holomap.mouse_opacity = 0
var/obj/screen/O
var/i
//that nasty looking dither you get when you're short-sighted

View File

@@ -0,0 +1,204 @@
//
// Holomap generation.
// Based on /vg/station but trimmed down (without antag stuff) and massively optimized (you should have seen it before!) ~Leshana
//
// Define what criteria makes a turf a path or not
// Hack because we don't have catwalks
/obj/structure/catwalk
name = "catwalk"
// End hack
// Turfs that will be colored as HOLOMAP_ROCK
#define IS_ROCK(tile) (istype(tile, /turf/simulated/mineral) && tile.density)
// Turfs that will be colored as HOLOMAP_OBSTACLE
#define IS_OBSTACLE(tile) ((!istype(tile, /turf/space) && istype(tile.loc, /area/mine/unexplored)) \
|| istype(tile, /turf/simulated/wall) \
|| istype(tile, /turf/unsimulated/mineral) \
|| (istype(tile, /turf/unsimulated/wall) && !istype(tile, /turf/unsimulated/wall/planetary)) \
/*|| istype(tile, /turf/simulated/shuttle/wall)*/ \
|| (locate(/obj/structure/grille) in tile) \
/*|| (locate(/obj/structure/window/full) in tile)*/)
// Turfs that will be colored as HOLOMAP_PATH
#define IS_PATH(tile) ((istype(tile, /turf/simulated/floor) && !istype(tile, /turf/simulated/floor/outdoors)) \
|| istype(tile, /turf/unsimulated/floor) \
/*|| istype(tile, /turf/simulated/shuttle/floor)*/ \
|| (locate(/obj/structure/catwalk) in tile))
// WARNING - TOTAL HACK - HOOKING INIT
/datum/controller/game_controller/setup_objects()
..()
generateHoloMinimaps()
/// Generates all the holo minimaps, initializing it all nicely, probably.
// TODO - This should be a subsystem ~Leshana
var/global/holomaps_initialized = FALSE
var/global/list/holoMiniMaps = list()
var/global/list/extraMiniMaps = list()
/proc/generateHoloMinimaps()
var/start_time = world.timeofday
// Build the base map for each z level
for (var/z = 1 to world.maxz)
global.holoMiniMaps |= z // hack, todo fix
global.holoMiniMaps[z] = generateHoloMinimap(z)
// Generate the area overlays, small maps, etc for the station levels.
for (var/z in using_map.station_levels)
generateStationMinimap(z)
if(using_map.holomap_smoosh)
for(var/smoosh_list in using_map.holomap_smoosh)
smooshTetherHolomaps(smoosh_list)
global.holomaps_initialized = TRUE
admin_notice("<span class='notice'>Holomaps initialized in [round(0.1*(world.timeofday-start_time),0.1)] seconds.</span>", R_DEBUG)
// TODO - Check - They had a delayed init perhaps?
for (var/obj/machinery/station_map/S in station_holomaps)
S.initialize()
// Generates the "base" holomap for one z-level, showing only the physical structure of walls and paths.
/proc/generateHoloMinimap(var/zLevel = 1)
//log_debug("Generating base minimap for z=[zLevel]")
// Save these values now to avoid a bazillion array lookups
var/offset_x = HOLOMAP_PIXEL_OFFSET_X(zLevel)
var/offset_y = HOLOMAP_PIXEL_OFFSET_Y(zLevel)
// Sanity checks - Better to generate a helpful error message now than have DrawBox() runtime
var/icon/canvas = icon(HOLOMAP_ICON, "blank")
if(world.maxx + offset_x > canvas.Width())
crash_with("Minimap for z=[zLevel] : world.maxx ([world.maxx]) + holomap_offset_x ([offset_x]) must be <= [canvas.Width()]")
if(world.maxy + offset_y > canvas.Height())
crash_with("Minimap for z=[zLevel] : world.maxy ([world.maxy]) + holomap_offset_y ([offset_y]) must be <= [canvas.Height()]")
for(var/x = 1 to world.maxx)
for(var/y = 1 to world.maxy)
var/turf/tile = locate(x, y, zLevel)
if(tile && tile.loc:holomapAlwaysDraw())
if(IS_ROCK(tile))
canvas.DrawBox(HOLOMAP_ROCK, x + offset_x, y + offset_y)
if(IS_OBSTACLE(tile))
canvas.DrawBox(HOLOMAP_OBSTACLE, x + offset_x, y + offset_y)
else if(IS_PATH(tile))
canvas.DrawBox(HOLOMAP_PATH, x + offset_x, y + offset_y)
// Check sleeping after each row to avoid *completely* destroying the server
if(world.tick_usage >= 80) sleep(world.tick_lag * 0.2)
return canvas
// Okay, what does this one do?
// This seems to do the drawing thing, but draws only the areas, having nothing to do with the tiles.
// Leshana: I'm guessing this map will get overlayed on top of the base map at runtime? We'll see.
// Wait, seems we actually blend the area map on top of it right now! Huh.
// It does a bunch of other stuff too tho, lets check what that is.
/proc/generateStationMinimap(var/zLevel)
//log_debug("Generating station minimap for z=[zLevel]")
// Save these values now to avoid a bazillion array lookups
var/offset_x = HOLOMAP_PIXEL_OFFSET_X(zLevel)
var/offset_y = HOLOMAP_PIXEL_OFFSET_Y(zLevel)
// Sanity checks - Better to generate a helpful error message now than have DrawBox() runtime
var/icon/canvas = icon(HOLOMAP_ICON, "blank")
if(world.maxx + offset_x > canvas.Width())
crash_with("Minimap for z=[zLevel] : world.maxx ([world.maxx]) + holomap_offset_x ([offset_x]) must be <= [canvas.Width()]")
if(world.maxy + offset_y > canvas.Height())
crash_with("Minimap for z=[zLevel] : world.maxy ([world.maxy]) + holomap_offset_y ([offset_y]) must be <= [canvas.Height()]")
for(var/x = 1 to world.maxx)
for(var/y = 1 to world.maxy)
var/turf/tile = locate(x, y, zLevel)
if(tile && tile.loc)
var/area/areaToPaint = tile.loc
if(areaToPaint.holomap_color)
canvas.DrawBox(areaToPaint.holomap_color, x + offset_x, y + offset_y)
// Save this nice area-colored canvas in case we want to layer it or something I guess
extraMiniMaps["[HOLOMAP_EXTRA_STATIONMAPAREAS]_[zLevel]"] = canvas
var/icon/map_base = icon(holoMiniMaps[zLevel])
map_base.Blend(HOLOMAP_HOLOFIER, ICON_MULTIPLY)
// Generate the full sized map by blending the base and areas onto the backdrop
var/icon/big_map = icon(HOLOMAP_ICON, "stationmap")
big_map.Blend(map_base, ICON_OVERLAY)
big_map.Blend(canvas, ICON_OVERLAY)
extraMiniMaps["[HOLOMAP_EXTRA_STATIONMAP]_[zLevel]"] = big_map
// Generate the "small" map (I presume for putting on wall map things?)
var/icon/small_map = icon(HOLOMAP_ICON, "blank")
small_map.Blend(map_base, ICON_OVERLAY)
small_map.Blend(canvas, ICON_OVERLAY)
small_map.Scale(WORLD_ICON_SIZE, WORLD_ICON_SIZE)
// And rotate it in every direction of course!
var/icon/actual_small_map = icon(small_map)
actual_small_map.Insert(new_icon = small_map, dir = SOUTH)
actual_small_map.Insert(new_icon = turn(small_map, 90), dir = WEST)
actual_small_map.Insert(new_icon = turn(small_map, 180), dir = NORTH)
actual_small_map.Insert(new_icon = turn(small_map, 270), dir = EAST)
extraMiniMaps["[HOLOMAP_EXTRA_STATIONMAPSMALL]_[zLevel]"] = actual_small_map
// For tiny multi-z maps like the tether, we want to smoosh em together into a nice big one!
/proc/smooshTetherHolomaps(var/list/zlevels)
var/icon/big_map = icon(HOLOMAP_ICON, "stationmap")
var/icon/small_map = icon(HOLOMAP_ICON, "blank")
// For each zlevel in turn, overlay them on top of each other
for(var/zLevel in zlevels)
var/icon/z_terrain = icon(holoMiniMaps[zLevel])
z_terrain.Blend(HOLOMAP_HOLOFIER, ICON_MULTIPLY)
big_map.Blend(z_terrain, ICON_OVERLAY)
small_map.Blend(z_terrain, ICON_OVERLAY)
var/icon/z_areas = extraMiniMaps["[HOLOMAP_EXTRA_STATIONMAPAREAS]_[zLevel]"]
big_map.Blend(z_areas, ICON_OVERLAY)
small_map.Blend(z_areas, ICON_OVERLAY)
// Then scale and rotate to make the actual small map we will use
small_map.Scale(WORLD_ICON_SIZE, WORLD_ICON_SIZE)
var/icon/actual_small_map = icon(small_map)
actual_small_map.Insert(new_icon = small_map, dir = SOUTH)
actual_small_map.Insert(new_icon = turn(small_map, 90), dir = WEST)
actual_small_map.Insert(new_icon = turn(small_map, 180), dir = NORTH)
actual_small_map.Insert(new_icon = turn(small_map, 270), dir = EAST)
// Then assign this icon as the icon for all those levels!
for(var/zLevel in zlevels)
extraMiniMaps["[HOLOMAP_EXTRA_STATIONMAP]_[zLevel]"] = big_map
extraMiniMaps["[HOLOMAP_EXTRA_STATIONMAPSMALL]_[zLevel]"] = actual_small_map
//
// ## Debugging and Testing ##
//
/client/verb/debug_map()
set category = "Debug"
set name = "Debug Map Datum"
debug_variables(using_map)
// TODO - Holomap Markers!
// /proc/generateMinimapMarkers(var/zLevel)
// // Save these values now to avoid a bazillion array lookups
// var/offset_x = HOLOMAP_PIXEL_OFFSET_X(zLevel)
// var/offset_y = HOLOMAP_PIXEL_OFFSET_Y(zLevel)
// // TODO - Holomap markers
// for(var/filter in list(HOLOMAP_FILTER_STATIONMAP))
// var/icon/canvas = icon(HOLOMAP_ICON, "blank")
// for(/datum/holomap_marker/holomarker in holomap_markers)
// if(holomarker.z == zLevel && holomarker.filter & filter)
// canvas.Blend(icon(holomarker.icon, holomarker.icon_state), ICON_OVERLAY, holomarker.x + offset_x, holomarker.y + offset_y)
// extraMiniMaps["[HOLOMAP_EXTRA_MARKERS]_[filter]_[zLevel]"] = canvas
// /datum/holomap_marker
// var/x
// var/y
// var/z
// var/filter
// var/icon = 'icons/holomap_markers.dmi'
// var/icon_state
#undef IS_ROCK
#undef IS_OBSTACLE
#undef IS_PATH

View File

@@ -0,0 +1,78 @@
/*
** Holomap vars and procs on /area
*/
/area
var/holomap_color = null // Color of this area on station holomap
/area/rnd
holomap_color = HOLOMAP_AREACOLOR_SCIENCE
/area/outpost/research
holomap_color = HOLOMAP_AREACOLOR_SCIENCE
/area/server
holomap_color = HOLOMAP_AREACOLOR_SCIENCE
/area/assembly
holomap_color = HOLOMAP_AREACOLOR_SCIENCE
/area/bridge
holomap_color = HOLOMAP_AREACOLOR_COMMAND
/area/teleporter
holomap_color = HOLOMAP_AREACOLOR_COMMAND
/area/teleporter/departing
holomap_color = null
/area/security
holomap_color = HOLOMAP_AREACOLOR_SECURITY
/area/tether/surfacebase/security
holomap_color = HOLOMAP_AREACOLOR_SECURITY
/area/medical
holomap_color = HOLOMAP_AREACOLOR_MEDICAL
/area/tether/surfacebase/medical
holomap_color = HOLOMAP_AREACOLOR_MEDICAL
/area/engineering
holomap_color = HOLOMAP_AREACOLOR_ENGINEERING
/area/maintenance/substation/engineering
holomap_color = HOLOMAP_AREACOLOR_ENGINEERING
/area/storage/tech
holomap_color = HOLOMAP_AREACOLOR_ENGINEERING
/area/quartermaster
holomap_color = HOLOMAP_AREACOLOR_CARGO
/area/tether/surfacebase/mining_main
holomap_color = HOLOMAP_AREACOLOR_CARGO
/area/hallway
holomap_color = HOLOMAP_AREACOLOR_HALLWAYS
/area/bridge/hallway
holomap_color = HOLOMAP_AREACOLOR_HALLWAYS
/area/crew_quarters/sleep
holomap_color = HOLOMAP_AREACOLOR_DORMS
/area/crew_quarters/sleep/cryo
holomap_color = null
// Heads
/area/crew_quarters/captain
holomap_color = HOLOMAP_AREACOLOR_COMMAND
/area/crew_quarters/heads/hop
holomap_color = HOLOMAP_AREACOLOR_COMMAND
/area/crew_quarters/heads/hor
holomap_color = HOLOMAP_AREACOLOR_SCIENCE
/area/crew_quarters/heads/chief
holomap_color = HOLOMAP_AREACOLOR_ENGINEERING
/area/crew_quarters/heads/hos
holomap_color = HOLOMAP_AREACOLOR_SECURITY
/area/crew_quarters/heads/cmo
holomap_color = HOLOMAP_AREACOLOR_MEDICAL
/area/crew_quarters/medbreak
holomap_color = HOLOMAP_AREACOLOR_MEDICAL
// ### PROCS ###
// Whether the turfs in the area should be drawn onto the "base" holomap.
/area/proc/holomapAlwaysDraw()
return TRUE
/area/shuttle/holomapAlwaysDraw()
return FALSE

View File

@@ -0,0 +1,40 @@
// Simple datum to keep track of a running holomap. Each machine capable of displaying the holomap will have one.
/datum/station_holomap
var/image/station_map
var/image/cursor
var/image/legend
/datum/station_holomap/proc/initialize_holomap(var/turf/T, var/isAI = null, var/mob/user = null, var/reinit = FALSE)
if(!station_map || reinit)
station_map = image(extraMiniMaps["[HOLOMAP_EXTRA_STATIONMAP]_[T.z]"])
if(!cursor || reinit)
cursor = image('icons/holomap_markers_vr.dmi', "you")
if(!legend || reinit)
legend = image('icons/effects/64x64_vr.dmi', "legend")
if(isAI)
T = get_turf(user.client.eye)
cursor.pixel_x = (T.x - 6 + HOLOMAP_PIXEL_OFFSET_X(T.z)) * PIXEL_MULTIPLIER
cursor.pixel_y = (T.y - 6 + HOLOMAP_PIXEL_OFFSET_Y(T.z)) * PIXEL_MULTIPLIER
legend.pixel_x = HOLOMAP_LEGEND_X(T.z)
legend.pixel_y = HOLOMAP_LEGEND_Y(T.z)
station_map.overlays |= cursor
station_map.overlays |= legend
/datum/station_holomap/proc/initialize_holomap_bogus()
station_map = image('icons/480x480_vr.dmi', "stationmap")
legend = image('icons/effects/64x64_vr.dmi', "notfound")
legend.pixel_x = 7 * WORLD_ICON_SIZE
legend.pixel_y = 7 * WORLD_ICON_SIZE
station_map.overlays |= legend
// TODO - Strategic Holomap support
// /datum/station_holomap/strategic/initialize_holomap(var/turf/T, var/isAI=null, var/mob/user=null)
// ..()
// station_map = image(extraMiniMaps[HOLOMAP_EXTRA_STATIONMAP_STRATEGIC])
// legend = image('icons/effects/64x64.dmi', "strategic")
// legend.pixel_x = 3*WORLD_ICON_SIZE
// legend.pixel_y = 3*WORLD_ICON_SIZE
// station_map.overlays |= legend

View File

@@ -0,0 +1,44 @@
//
// An enhancement to /datum/map to store more and better meta-info about Z-levels
//
// Structure to hold zlevel info together in one nice convenient package.
// Wouldn't this be nicer than having to do those dumb arrays?
/datum/map_z_level
var/name // Friendly name of the zlevel
var/z = -1 // Actual z-index of the zlevel. This had better be right!
var/holomap_offset_x = 0 // Number of pixels to offset right (for centering)
var/holomap_offset_y = 0 // Number of pixels to offset up (for centering)
var/holomap_legend_x = 96 // x position of the holomap legend for this z
var/holomap_legend_y = 96 // y position of the holomap legend for this z
/datum/map_z_level/New(z, name, holomap_zoom = initial(holomap_zoom), holomap_offset_x = initial(holomap_offset_x), holomap_offset_y = initial(holomap_offset_y))
src.z = z
src.name = name
src.holomap_offset_x = holomap_offset_x
src.holomap_offset_y = holomap_offset_y
// Map datum stuff we need
// TODO - Put this into ~map_system/maps.dm
/datum/map
var/list/zlevels = list()
// LEGACY - This is how /vg does it, and how the code uses it. I'm in transition to use my new way (above)
// but for now lets just initialize this stuff so the code works.
/datum/map
var/list/holomap_smoosh // List of lists of zlevels to smoosh into single icons
var/list/holomap_offset_x = list()
var/list/holomap_offset_y = list()
var/list/holomap_legend_x = list()
var/list/holomap_legend_y = list()
/datum/map/New()
..()
// Auto-calculate any missing holomap offsets to center them, assuming they are full sized maps.
for(var/i in (holomap_offset_x.len + 1) to world.maxx)
holomap_offset_x += ((480 - world.maxx) / 2)
for(var/i in (holomap_offset_y.len + 1) to world.maxy)
holomap_offset_y += ((480 - world.maxy) / 2)
for(var/z in 1 to world.maxz)
holomap_legend_x += 96
holomap_legend_y += 96

View File

@@ -0,0 +1,246 @@
var/global/list/station_holomaps = list()
/obj/machinery/station_map
name = "station holomap"
desc = "A virtual map of the surrounding station."
icon = 'icons/obj/machines/stationmap_vr.dmi'
icon_state = "station_map"
anchored = 1
density = 0
use_power = 1
idle_power_usage = 10
active_power_usage = 500
auto_init = 0 // We handle our own special initialization needs. // TODO - Make this not ~Leshana
circuit = /obj/item/weapon/circuitboard/station_map
// TODO - Port use_auto_lights from /vg - for now declare here
var/use_auto_lights = 1
var/light_power_on = 1
var/light_range_on = 2
light_color = "#64C864"
layer = ABOVE_WINDOW_LAYER
var/mob/watching_mob = null
var/image/small_station_map = null
var/image/floor_markings = null
var/image/panel = null
var/original_zLevel = 1 // zLevel on which the station map was initialized.
var/bogus = TRUE // set to 0 when you initialize the station map on a zLevel that has its own icon formatted for use by station holomaps.
var/datum/station_holomap/holomap_datum
/obj/machinery/station_map/New()
..()
holomap_datum = new()
original_zLevel = loc.z
station_holomaps += src
flags |= ON_BORDER // Why? It doesn't help if its not density
if(ticker && holomaps_initialized)
spawn(1) // Tragically we need to spawn this in order to give the frame construcing us time to set pixel_x/y
initialize()
/obj/machinery/station_map/Destroy()
station_holomaps -= src
stopWatching()
holomap_datum = null
..()
/obj/machinery/station_map/initialize()
bogus = FALSE
var/turf/T = get_turf(src)
original_zLevel = T.z
if(!("[HOLOMAP_EXTRA_STATIONMAP]_[original_zLevel]" in extraMiniMaps))
bogus = TRUE
holomap_datum.initialize_holomap_bogus()
update_icon()
return
holomap_datum.initialize_holomap(T, reinit = TRUE)
small_station_map = image(extraMiniMaps["[HOLOMAP_EXTRA_STATIONMAPSMALL]_[original_zLevel]"], dir = dir)
// small_station_map.plane = LIGHTING_PLANE // Not until we do planes ~Leshana
// small_station_map.layer = LIGHTING_LAYER+1 // Weird things will happen!
floor_markings = image('icons/obj/machines/stationmap_vr.dmi', "decal_station_map")
floor_markings.dir = src.dir
// floor_markings.plane = ABOVE_TURF_PLANE // Not until we do planes ~Leshana
// floor_markings.layer = DECAL_LAYER
update_icon()
/obj/machinery/station_map/attack_hand(var/mob/user)
if(watching_mob && (watching_mob != user))
to_chat(user, "<span class='warning'>Someone else is currently watching the holomap.</span>")
return
if(user.loc != loc)
to_chat(user, "<span class='warning'>You need to stand in front of \the [src].</span>")
return
startWatching(user)
// Let people bump up against it to watch
/obj/machinery/station_map/Bumped(var/atom/movable/AM)
if(!watching_mob && isliving(AM) && AM.loc == loc)
startWatching(AM)
// In order to actually get Bumped() we need to block movement. We're (visually) on a wall, so people
// couldn't really walk into us anyway. But in reality we are on the turf in front of the wall, so bumping
// against where we seem is actually trying to *exit* our real loc
/obj/machinery/station_map/CheckExit(atom/movable/mover as mob|obj, turf/target as turf)
// log_debug("[src] (dir=[dir]) CheckExit([mover], [target]) get_dir() = [get_dir(target, loc)]")
if(get_dir(target, loc) == dir) // Opposite of "normal" since we are visually in the next turf over
return FALSE
else
return TRUE
/obj/machinery/station_map/proc/startWatching(var/mob/user)
// Okay, does this belong on a screen thing or what?
// One argument is that this is an "in game" object becuase its in the world.
// But I think it actually isn't. The map isn't holo projected into the whole room, (maybe strat one is!)
// But for this, the on screen object just represents you leaning in and looking at it closely.
// So it SHOULD be a screen object.
// But it is not QUITE a hud either. So I think it shouldn't go in /datum/hud
// Okay? Yeah. Lets use screen objects but manage them manually here in the item.
// That might be a mistake... I'd rather they be managed by some central hud management system.
// But the /vg code, while the screen obj is managed, its still adding and removing image, so this is
// just as good.
// EH JUST HACK IT FOR NOW SO WE CAN SEE HOW IT LOOKS! STOP OBSESSING, ITS BEEN AN HOUR NOW!
// TODO - This part!! ~Leshana
if(isliving(user) && anchored && !(stat & (NOPOWER|BROKEN)))
if(user.client)
holomap_datum.station_map.loc = global_hud.holomap // Put the image on the holomap hud
holomap_datum.station_map.alpha = 0 // Set to transparent so we can fade in
animate(holomap_datum.station_map, alpha = 255, time = 5, easing = LINEAR_EASING)
flick("station_map_activate", src)
// Wait, if wea re not modifying the holomap_obj... can't it be part of the global hud?
user.client.screen |= global_hud.holomap // TODO - HACK! This should be there permenently really.
user.client.images |= holomap_datum.station_map
watching_mob = user
moved_event.register(watching_mob, src, /obj/machinery/station_map/proc/checkPosition)
dir_set_event.register(watching_mob, src, /obj/machinery/station_map/proc/checkPosition)
destroyed_event.register(watching_mob, src, /obj/machinery/station_map/proc/stopWatching)
update_use_power(2)
if(bogus)
to_chat(user, "<span class='warning'>The holomap failed to initialize. This area of space cannot be mapped.</span>")
else
to_chat(user, "<span class='notice'>A hologram of the station appears before your eyes.</span>")
/obj/machinery/station_map/attack_ai(var/mob/living/silicon/robot/user)
return // TODO - Implement for AI ~Leshana
// user.station_holomap.toggleHolomap(user, isAI(user))
/obj/machinery/station_map/process()
if((stat & (NOPOWER|BROKEN)) || !anchored)
stopWatching()
/obj/machinery/station_map/proc/checkPosition()
if(!watching_mob || (watching_mob.loc != loc) || (dir != watching_mob.dir))
stopWatching()
/obj/machinery/station_map/proc/stopWatching()
if(watching_mob)
if(watching_mob.client)
animate(holomap_datum.station_map, alpha = 0, time = 5, easing = LINEAR_EASING)
var/mob/M = watching_mob
spawn(5) //we give it time to fade out
M.client.images -= holomap_datum.station_map
moved_event.unregister(watching_mob, src)
dir_set_event.unregister(watching_mob, src)
destroyed_event.unregister(watching_mob, src)
watching_mob = null
update_use_power(1)
/obj/machinery/station_map/power_change()
. = ..()
update_icon()
// TODO - Port use_auto_lights from /vg - For now implement it manually here
if(stat & NOPOWER)
set_light(0)
else
set_light(light_range_on, light_power_on)
/obj/machinery/station_map/proc/set_broken()
stat |= BROKEN
update_icon()
/obj/machinery/station_map/update_icon()
overlays.Cut()
if(stat & BROKEN)
icon_state = "station_mapb"
else if((stat & NOPOWER) || !anchored)
icon_state = "station_map0"
else
icon_state = "station_map"
if(bogus)
holomap_datum.initialize_holomap_bogus()
else
small_station_map.icon = extraMiniMaps["[HOLOMAP_EXTRA_STATIONMAPSMALL]_[original_zLevel]"]
overlays |= small_station_map
holomap_datum.initialize_holomap(get_turf(src))
// Put the little "map" overlay down where it looks nice
if(floor_markings)
floor_markings.dir = src.dir
floor_markings.pixel_x = -src.pixel_x
floor_markings.pixel_y = -src.pixel_y
overlays += floor_markings
if(panel_open)
overlays += "station_map-panel"
else
overlays -= "station_map-panel"
/obj/machinery/station_map/attackby(obj/item/weapon/W as obj, mob/user as mob)
src.add_fingerprint(user)
if(default_deconstruction_screwdriver(user, W))
return
if(default_deconstruction_crowbar(user, W))
return
return ..()
/obj/machinery/station_map/ex_act(severity)
switch(severity)
if(1)
qdel(src)
if(2)
if (prob(50))
qdel(src)
else
set_broken()
if(3)
if (prob(25))
set_broken()
/datum/frame/frame_types/station_map
name = "Station Map Frame"
frame_class = "display"
frame_size = 3
frame_style = "wall"
x_offset = WORLD_ICON_SIZE
y_offset = WORLD_ICON_SIZE
circuit = /obj/item/weapon/circuitboard/station_map
icon_override = 'icons/obj/machines/stationmap_vr.dmi'
/datum/frame/frame_types/station_map/get_icon_state(var/state)
return "station_map_frame_[state]"
/obj/structure/frame
layer = ABOVE_WINDOW_LAYER
/obj/item/weapon/circuitboard/station_map
name = T_BOARD("Station Map")
board_type = new /datum/frame/frame_types/station_map
build_path = /obj/machinery/station_map
origin_tech = list(TECH_DATA = 3, TECH_ENGINEERING = 2)
req_components = list()
// TODO
// //Portable holomaps, currently AI/Borg/MoMMI only
// TODO
// OHHHH YEAH - STRATEGIC HOLOMAP! NICE!
// It will need to wait until later tho.

BIN
icons/480x480_vr.dmi Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
icons/effects/64x64_vr.dmi Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -144,3 +144,27 @@
new /datum/random_map/noise/ore(null, 1, 1, Z_LEVEL_SOLARS, 64, 64) // Create the mining ore distribution map.
return 1
// TODO - Re-Implement this using the /datum/map_z_level
/datum/map/tether/New()
..()
holomap_offset_y[1] = 60
holomap_offset_y[2] = 180
holomap_offset_y[3] = 300
holomap_offset_x[1] = 100
holomap_offset_x[2] = 100
holomap_offset_x[3] = 100
holomap_offset_x[5] = 260
holomap_offset_x[7] = 260
holomap_offset_x[6] = 260
holomap_offset_y[5] = 60
holomap_offset_y[6] = 180
holomap_offset_y[7] = 300
for(var/z in list(1,2,3,5,6,7))
holomap_legend_x[z] = 220
holomap_legend_y[z] = 160
holomap_smoosh = list(list(1,2,3,5,6,7))

View File

@@ -29,6 +29,7 @@
#include "code\__defines\damage_organs.dm"
#include "code\__defines\dna.dm"
#include "code\__defines\gamemode.dm"
#include "code\__defines\holomap.dm"
#include "code\__defines\inventory_sizes.dm"
#include "code\__defines\items_clothing.dm"
#include "code\__defines\lighting.dm"
@@ -1510,6 +1511,11 @@
#include "code\modules\holodeck\HolodeckControl.dm"
#include "code\modules\holodeck\HolodeckObjects.dm"
#include "code\modules\holodeck\HolodeckPrograms.dm"
#include "code\modules\holomap\generate_holomap.dm"
#include "code\modules\holomap\holomap_area.dm"
#include "code\modules\holomap\holomap_datum.dm"
#include "code\modules\holomap\holomap_zlevel.dm"
#include "code\modules\holomap\station_holomap.dm"
#include "code\modules\hydroponics\_hydro_setup.dm"
#include "code\modules\hydroponics\grown.dm"
#include "code\modules\hydroponics\grown_inedible.dm"