diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 9d1558f2724ce..f0d946a2df7eb 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -98,9 +98,6 @@ data["network"] = network data["mapRef"] = cam_screen.assigned_map data["cameras"] = GLOB.cameranet.get_available_cameras_data(network) - - update_available_z_levels(data["cameras"]) // BANDASTATION ADDITION - Nanomap - return data /obj/machinery/computer/security/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) @@ -115,8 +112,6 @@ if(isnull(active_camera)) return TRUE - current_z_level_index = z_levels.Find("[active_camera.z]") // BANDASTATION ADDITION - Nanomap - update_active_camera_screen() return TRUE diff --git a/icons/_nanomaps/Birdshot Station_nanomap_z1.png b/icons/_nanomaps/Birdshot Station_nanomap_z1.png index f982f4fc0281e..ffffd679a3dce 100644 Binary files a/icons/_nanomaps/Birdshot Station_nanomap_z1.png and b/icons/_nanomaps/Birdshot Station_nanomap_z1.png differ diff --git a/icons/_nanomaps/Cyberiad_nanomap_z1.png b/icons/_nanomaps/Cyberiad_nanomap_z1.png index 85fd1cd2e74f7..521609457c81f 100644 Binary files a/icons/_nanomaps/Cyberiad_nanomap_z1.png and b/icons/_nanomaps/Cyberiad_nanomap_z1.png differ diff --git a/icons/_nanomaps/Cyberiad_nanomap_z2.png b/icons/_nanomaps/Cyberiad_nanomap_z2.png index 64e47d2441294..97678cda40691 100644 Binary files a/icons/_nanomaps/Cyberiad_nanomap_z2.png and b/icons/_nanomaps/Cyberiad_nanomap_z2.png differ diff --git a/icons/_nanomaps/Delta Station_nanomap_z1.png b/icons/_nanomaps/Delta Station_nanomap_z1.png index 527e8e3905df5..4ef5a19372a2f 100644 Binary files a/icons/_nanomaps/Delta Station_nanomap_z1.png and b/icons/_nanomaps/Delta Station_nanomap_z1.png differ diff --git a/icons/_nanomaps/Ice Box Station_nanomap_z1.png b/icons/_nanomaps/Ice Box Station_nanomap_z1.png index 6c4c31016aca3..82971a84e371e 100644 Binary files a/icons/_nanomaps/Ice Box Station_nanomap_z1.png and b/icons/_nanomaps/Ice Box Station_nanomap_z1.png differ diff --git a/icons/_nanomaps/Ice Box Station_nanomap_z2.png b/icons/_nanomaps/Ice Box Station_nanomap_z2.png index 4f537daa63cb5..24d31ddb131f9 100644 Binary files a/icons/_nanomaps/Ice Box Station_nanomap_z2.png and b/icons/_nanomaps/Ice Box Station_nanomap_z2.png differ diff --git a/icons/_nanomaps/Ice Box Station_nanomap_z3.png b/icons/_nanomaps/Ice Box Station_nanomap_z3.png index 99ea6e96654c9..1bbcb17fe6252 100644 Binary files a/icons/_nanomaps/Ice Box Station_nanomap_z3.png and b/icons/_nanomaps/Ice Box Station_nanomap_z3.png differ diff --git a/icons/_nanomaps/Lavaland_nanomap_z1.png b/icons/_nanomaps/Lavaland_nanomap_z1.png index 9fc8f1246f930..d70be0be65ff2 100644 Binary files a/icons/_nanomaps/Lavaland_nanomap_z1.png and b/icons/_nanomaps/Lavaland_nanomap_z1.png differ diff --git a/icons/_nanomaps/MetaStation_nanomap_z1.png b/icons/_nanomaps/MetaStation_nanomap_z1.png index 6a98aefc205a8..c1b56ebe4676b 100644 Binary files a/icons/_nanomaps/MetaStation_nanomap_z1.png and b/icons/_nanomaps/MetaStation_nanomap_z1.png differ diff --git a/icons/_nanomaps/NebulaStation_nanomap_z1.png b/icons/_nanomaps/NebulaStation_nanomap_z1.png index bddec1132e3cf..3f4dcc1bd34b2 100644 Binary files a/icons/_nanomaps/NebulaStation_nanomap_z1.png and b/icons/_nanomaps/NebulaStation_nanomap_z1.png differ diff --git a/icons/_nanomaps/NebulaStation_nanomap_z2.png b/icons/_nanomaps/NebulaStation_nanomap_z2.png index 57ecaa590a7b0..93e5d134e48af 100644 Binary files a/icons/_nanomaps/NebulaStation_nanomap_z2.png and b/icons/_nanomaps/NebulaStation_nanomap_z2.png differ diff --git a/icons/_nanomaps/Tramstation_nanomap_z1.png b/icons/_nanomaps/Tramstation_nanomap_z1.png index 6f3f5e6aaec0e..990609140dc41 100644 Binary files a/icons/_nanomaps/Tramstation_nanomap_z1.png and b/icons/_nanomaps/Tramstation_nanomap_z1.png differ diff --git a/icons/_nanomaps/Tramstation_nanomap_z2.png b/icons/_nanomaps/Tramstation_nanomap_z2.png index 083366e1f9254..e1f278cd2c8b0 100644 Binary files a/icons/_nanomaps/Tramstation_nanomap_z2.png and b/icons/_nanomaps/Tramstation_nanomap_z2.png differ diff --git a/icons/_nanomaps/Wawastation_nanomap_z1.png b/icons/_nanomaps/Wawastation_nanomap_z1.png index 7589eff8fc84a..3e31eb47d2b90 100644 Binary files a/icons/_nanomaps/Wawastation_nanomap_z1.png and b/icons/_nanomaps/Wawastation_nanomap_z1.png differ diff --git a/icons/_nanomaps/Wawastation_nanomap_z2.png b/icons/_nanomaps/Wawastation_nanomap_z2.png index ed52e78198908..990d839f1542a 100644 Binary files a/icons/_nanomaps/Wawastation_nanomap_z2.png and b/icons/_nanomaps/Wawastation_nanomap_z2.png differ diff --git a/modular_bandastation/aesthetics/_aesthetics.dme b/modular_bandastation/aesthetics/_aesthetics.dme index 0c7202eceee19..93f481d69e969 100644 --- a/modular_bandastation/aesthetics/_aesthetics.dme +++ b/modular_bandastation/aesthetics/_aesthetics.dme @@ -11,12 +11,12 @@ #include "clothing/centcom/code/head/hat.dm" #include "clothing/centcom/code/head/winterhood.dm" #include "clothing/centcom/code/mask/mask.dm" +#include "clothing/centcom/code/mod/mod_theme.dm" +#include "clothing/centcom/code/mod/mod_types.dm" #include "clothing/centcom/code/suits/armor.dm" #include "clothing/centcom/code/suits/jacket.dm" #include "clothing/centcom/code/suits/wintercoats.dm" #include "clothing/centcom/code/under/centcom.dm" -#include "clothing/centcom/code/mod/mod_theme.dm" -#include "clothing/centcom/code/mod/mod_types.dm" #include "disposal/code/disposal.dm" #include "dresser/code/dresser.dm" #include "firealarm/code/firealarm.dm" @@ -29,6 +29,7 @@ #include "radio/code/radio.dm" #include "railings/code/railings.dm" #include "smes/code/smes.dm" +#include "smoothing/code/smoothing.dm" #include "soap/code/soap.dm" #include "supply_pods/code/supply_pods.dm" #include "vending/code/vending.dm" diff --git a/modular_bandastation/aesthetics/smoothing/code/smoothing.dm b/modular_bandastation/aesthetics/smoothing/code/smoothing.dm new file mode 100644 index 0000000000000..9d3a2572de239 --- /dev/null +++ b/modular_bandastation/aesthetics/smoothing/code/smoothing.dm @@ -0,0 +1,149 @@ +/** + * Перезапись флагов у сглаживаемых объектов + * + * Используется в проде. + * При изменении флагов не забудьте обновить перезаписи перезаписей... + */ + +// MARK: Windows +/obj/structure/window/fulltile + smoothing_groups = SMOOTH_GROUP_WINDOW_FULLTILE + canSmoothWith = SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS + +/obj/structure/window/reinforced/fulltile + smoothing_groups = SMOOTH_GROUP_WINDOW_FULLTILE + canSmoothWith = SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS + +/obj/structure/window/reinforced/tinted/fulltile + smoothing_groups = SMOOTH_GROUP_WINDOW_FULLTILE + canSmoothWith = SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS + +/obj/structure/window/plasma/fulltile + smoothing_groups = SMOOTH_GROUP_WINDOW_FULLTILE + canSmoothWith = SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS + +/obj/structure/window/reinforced/plasma/fulltile + smoothing_groups = SMOOTH_GROUP_WINDOW_FULLTILE + canSmoothWith = SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS + +/obj/structure/window/reinforced/shuttle + smoothing_groups = SMOOTH_GROUP_SHUTTLE_PARTS + SMOOTH_GROUP_WINDOW_FULLTILE_SHUTTLE + canSmoothWith = SMOOTH_GROUP_SHUTTLE_PARTS + SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE_SHUTTLE + SMOOTH_GROUP_TITANIUM_WALLS + +/turf/closed/indestructible/fakeglass + smoothing_groups = SMOOTH_GROUP_WINDOW_FULLTILE + canSmoothWith = SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS + +// MARK: Walls +/turf/closed/wall + smoothing_groups = SMOOTH_GROUP_WALLS + SMOOTH_GROUP_CLOSED_TURFS + canSmoothWith = SMOOTH_GROUP_GIRDER + SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS + +/turf/closed/wall/mineral/titanium + smoothing_groups = SMOOTH_GROUP_TITANIUM_WALLS + SMOOTH_GROUP_CLOSED_TURFS + canSmoothWith = SMOOTH_GROUP_SHUTTLE_PARTS + SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE_SHUTTLE + SMOOTH_GROUP_TITANIUM_WALLS + +/turf/closed/wall/mineral/cult + canSmoothWith = SMOOTH_GROUP_GIRDER + SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS + +/turf/closed/wall/material + smoothing_groups = SMOOTH_GROUP_WALLS + SMOOTH_GROUP_CLOSED_TURFS + canSmoothWith = SMOOTH_GROUP_GIRDER + SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS + +/turf/closed/indestructible/riveted + smoothing_groups = SMOOTH_GROUP_WALLS + SMOOTH_GROUP_CLOSED_TURFS + canSmoothWith = SMOOTH_GROUP_GIRDER + SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS + +/turf/closed/indestructible/reinforced + canSmoothWith = SMOOTH_GROUP_GIRDER + SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS + +/turf/closed/indestructible/cult + canSmoothWith = SMOOTH_GROUP_GIRDER + SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS + +/obj/structure/falsewall + canSmoothWith = SMOOTH_GROUP_GIRDER + SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS + +/obj/structure/girder + canSmoothWith = SMOOTH_GROUP_GIRDER + SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS + +// MARK: Other +/obj/structure/lattice + smoothing_groups = SMOOTH_GROUP_LATTICE + canSmoothWith = SMOOTH_GROUP_LATTICE + SMOOTH_GROUP_WALLS + SMOOTH_GROUP_OPEN_FLOOR + +/** + * Это перезаписи перезаписей для рендера наномап и интерактивных карт. + * + * Я рот блять ебал этой хуйни, но это единственный способ который я вижу, + * дабы сделать хорошее, красивое сглаживание на рендерах. + */ +#ifndef CBT +// MARK: Windows +/obj/structure/window/fulltile + smoothing_groups = list(SMOOTH_GROUP_WINDOW_FULLTILE) + canSmoothWith = list(SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_WINDOW_FULLTILE, SMOOTH_GROUP_WALLS) + +/obj/structure/window/reinforced/fulltile + smoothing_groups = list(SMOOTH_GROUP_WINDOW_FULLTILE) + canSmoothWith = list(SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_WINDOW_FULLTILE, SMOOTH_GROUP_WALLS) + +/obj/structure/window/reinforced/tinted/fulltile + smoothing_groups = list(SMOOTH_GROUP_WINDOW_FULLTILE) + canSmoothWith = list(SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_WINDOW_FULLTILE, SMOOTH_GROUP_WALLS) + +/obj/structure/window/plasma/fulltile + smoothing_groups = list(SMOOTH_GROUP_WINDOW_FULLTILE) + canSmoothWith = list(SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_WINDOW_FULLTILE, SMOOTH_GROUP_WALLS) + +/obj/structure/window/reinforced/plasma/fulltile + smoothing_groups = list(SMOOTH_GROUP_WINDOW_FULLTILE) + canSmoothWith = list(SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_WINDOW_FULLTILE, SMOOTH_GROUP_WALLS) + +/obj/structure/window/reinforced/shuttle + smoothing_groups = list(SMOOTH_GROUP_SHUTTLE_PARTS, SMOOTH_GROUP_WINDOW_FULLTILE_SHUTTLE) + canSmoothWith = list(SMOOTH_GROUP_SHUTTLE_PARTS, SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_WINDOW_FULLTILE_SHUTTLE, SMOOTH_GROUP_TITANIUM_WALLS) + +/turf/closed/indestructible/fakeglass + smoothing_groups = list(SMOOTH_GROUP_WINDOW_FULLTILE) + canSmoothWith = list(SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_WINDOW_FULLTILE, SMOOTH_GROUP_WALLS) + +// MARK: Walls +/turf/closed/wall + smoothing_groups = list(SMOOTH_GROUP_WALLS, SMOOTH_GROUP_CLOSED_TURFS) + canSmoothWith = list(SMOOTH_GROUP_GIRDER, SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_WINDOW_FULLTILE, SMOOTH_GROUP_WALLS) + +/turf/closed/wall/mineral/titanium + smoothing_groups = list(SMOOTH_GROUP_TITANIUM_WALLS, SMOOTH_GROUP_CLOSED_TURFS) + canSmoothWith = list(SMOOTH_GROUP_SHUTTLE_PARTS, SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_WINDOW_FULLTILE_SHUTTLE, SMOOTH_GROUP_TITANIUM_WALLS) + +/turf/closed/wall/mineral/cult + canSmoothWith = list(SMOOTH_GROUP_GIRDER, SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_WINDOW_FULLTILE, SMOOTH_GROUP_WALLS) + +/turf/closed/wall/material + smoothing_groups = list(SMOOTH_GROUP_WALLS, SMOOTH_GROUP_CLOSED_TURFS) + canSmoothWith = list(SMOOTH_GROUP_GIRDER, SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_WINDOW_FULLTILE, SMOOTH_GROUP_WALLS) + +/turf/closed/indestructible/riveted + smoothing_groups = list(SMOOTH_GROUP_WALLS, SMOOTH_GROUP_CLOSED_TURFS) + canSmoothWith = list(SMOOTH_GROUP_GIRDER, SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_WINDOW_FULLTILE, SMOOTH_GROUP_WALLS) + +/turf/closed/indestructible/reinforced + canSmoothWith = list(SMOOTH_GROUP_GIRDER, SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_WINDOW_FULLTILE, SMOOTH_GROUP_WALLS) + +/turf/closed/indestructible/cult + canSmoothWith = list(SMOOTH_GROUP_GIRDER, SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_WINDOW_FULLTILE, SMOOTH_GROUP_WALLS) + +/obj/structure/falsewall + canSmoothWith = list(SMOOTH_GROUP_GIRDER, SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_WINDOW_FULLTILE, SMOOTH_GROUP_WALLS) + +/obj/structure/girder + canSmoothWith = list(SMOOTH_GROUP_GIRDER, SMOOTH_GROUP_AIRLOCK, SMOOTH_GROUP_WINDOW_FULLTILE, SMOOTH_GROUP_WALLS) + +// MARK: Other +/obj/machinery/door/airlock + smoothing_groups = list(SMOOTH_GROUP_AIRLOCK) + +/obj/structure/lattice + smoothing_groups = list(SMOOTH_GROUP_LATTICE) + canSmoothWith = list(SMOOTH_GROUP_LATTICE, SMOOTH_GROUP_WALLS, SMOOTH_GROUP_OPEN_FLOOR) +#endif diff --git a/modular_bandastation/aesthetics/walls/code/rocks.dm b/modular_bandastation/aesthetics/walls/code/rocks.dm index 64164cd330644..6c3494fa738cd 100644 --- a/modular_bandastation/aesthetics/walls/code/rocks.dm +++ b/modular_bandastation/aesthetics/walls/code/rocks.dm @@ -18,6 +18,13 @@ color = rock_color(ROCK_COLOR) transform = null +/turf/closed/mineral/minimap + name = "DO NOT USE!!!" + icon = DEFAULT_ROCKS + icon_state = "smoothrocks-0" + base_icon_state = "smoothrocks" + color = ROCK_COLOR + /turf/closed/mineral/strong icon = MAP_SWITCH(CONTRAST_ROCKS, MAPPING_ROCKS) icon_state = rock_icon_state("rock2") diff --git a/modular_bandastation/aesthetics/walls/code/walls.dm b/modular_bandastation/aesthetics/walls/code/walls.dm index dc493ba26929e..a44088464cd94 100644 --- a/modular_bandastation/aesthetics/walls/code/walls.dm +++ b/modular_bandastation/aesthetics/walls/code/walls.dm @@ -3,7 +3,6 @@ icon = 'icons/bandastation/walls/wall.dmi' icon_state = "wall-0" base_icon_state = "wall" - canSmoothWith = SMOOTH_GROUP_GIRDER + SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS /turf/closed/wall/rust icon = 'icons/bandastation/walls/wall.dmi' @@ -20,42 +19,31 @@ icon_state = "reinforced_wall-0" base_icon_state = "reinforced_wall" -/turf/closed/wall/mineral/titanium - smoothing_groups = SMOOTH_GROUP_TITANIUM_WALLS + SMOOTH_GROUP_CLOSED_TURFS - canSmoothWith = SMOOTH_GROUP_SHUTTLE_PARTS + SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE_SHUTTLE + SMOOTH_GROUP_TITANIUM_WALLS - /turf/closed/wall/mineral/cult icon = 'icons/bandastation/walls/cult_wall.dmi' icon_state = "cult_wall-0" base_icon_state = "cult_wall" - canSmoothWith = SMOOTH_GROUP_GIRDER + SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS /turf/closed/wall/material icon = 'icons/bandastation/walls/material_wall.dmi' icon_state = "material_wall-0" base_icon_state = "material_wall" - smoothing_groups = SMOOTH_GROUP_WALLS + SMOOTH_GROUP_CLOSED_TURFS - canSmoothWith = SMOOTH_GROUP_GIRDER + SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS // MARK: Indestructible walls /turf/closed/indestructible/riveted icon = 'icons/bandastation/walls/reinforced_wall.dmi' icon_state = "reinforced_wall-0" base_icon_state = "reinforced_wall" - smoothing_groups = SMOOTH_GROUP_WALLS + SMOOTH_GROUP_CLOSED_TURFS - canSmoothWith = SMOOTH_GROUP_GIRDER + SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS /turf/closed/indestructible/reinforced icon = 'icons/bandastation/walls/reinforced_wall.dmi' icon_state = "reinforced_wall-0" base_icon_state = "reinforced_wall" - canSmoothWith = SMOOTH_GROUP_GIRDER + SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS /turf/closed/indestructible/cult icon = 'icons/bandastation/walls/cult_wall.dmi' icon_state = "cult_wall-0" base_icon_state = "cult_wall" - canSmoothWith = SMOOTH_GROUP_GIRDER + SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS // MARK: Falsewalls /obj/structure/falsewall @@ -63,7 +51,6 @@ base_icon_state = "wall" icon_state = "wall-open" fake_icon = 'icons/bandastation/walls/wall.dmi' - canSmoothWith = SMOOTH_GROUP_GIRDER + SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS /obj/structure/falsewall/reinforced icon_state = "reinforced_wall-open" @@ -112,7 +99,3 @@ /obj/structure/falsewall/material icon = 'icons/turf/walls/false_walls.dmi' - -// MARK: Girder -/obj/structure/girder - canSmoothWith = SMOOTH_GROUP_GIRDER + SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS diff --git a/modular_bandastation/aesthetics/windows/code/full_tile_windows.dm b/modular_bandastation/aesthetics/windows/code/full_tile_windows.dm index 1608e2bc569c3..231b264c675a7 100644 --- a/modular_bandastation/aesthetics/windows/code/full_tile_windows.dm +++ b/modular_bandastation/aesthetics/windows/code/full_tile_windows.dm @@ -22,12 +22,31 @@ edge_overlay.color = edge_overlay_color . += edge_overlay +/** + * Рамки окон но как отдельный объект. + * НЕ ИСПОЛЬЗОВАТЬ!!! + * + * Только для рендера карт. + */ +/obj/structure/window/fulltile/frame + name = "DONT USE THIS" + icon = 'icons/bandastation/windows/window_edges.dmi' + icon_state = "edge-0" + base_icon_state = "edge" + color = EDGE_OVERLAY_COLOR + +/obj/structure/window/reinforced/fulltile/frame + name = "DONT USE THIS" + icon = 'icons/bandastation/windows/reinforced_window_edges.dmi' + icon_state = "edge-0" + base_icon_state = "edge" + color = EDGE_OVERLAY_COLOR + /obj/structure/window/fulltile icon = 'icons/bandastation/windows/window.dmi' edge_overlay_file = 'icons/bandastation/windows/window_edges.dmi' icon_state = "window-0" base_icon_state = "window" - canSmoothWith = SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS color = WINDOW_COLOR /obj/structure/window/reinforced/fulltile @@ -35,7 +54,6 @@ edge_overlay_file = 'icons/bandastation/windows/reinforced_window_edges.dmi' icon_state = "reinforced_window-0" base_icon_state = "reinforced_window" - canSmoothWith = SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS color = WINDOW_COLOR /obj/structure/window/reinforced/tinted/fulltile @@ -43,7 +61,6 @@ edge_overlay_file = 'icons/bandastation/windows/reinforced_window_edges.dmi' icon_state = "reinforced_window-0" base_icon_state = "reinforced_window" - canSmoothWith = SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS flags_1 = UNPAINTABLE_1 color = TINTED_WINDOW_COLOR @@ -52,7 +69,6 @@ edge_overlay_file = 'icons/bandastation/windows/window_edges.dmi' icon_state = "window-0" base_icon_state = "window" - canSmoothWith = SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS flags_1 = UNPAINTABLE_1 color = PLASMA_WINDOW_COLOR @@ -61,13 +77,9 @@ edge_overlay_file = 'icons/bandastation/windows/reinforced_window_edges.dmi' icon_state = "reinforced_window-0" base_icon_state = "reinforced_window" - canSmoothWith = SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS flags_1 = UNPAINTABLE_1 color = PLASMA_WINDOW_COLOR -/obj/structure/window/reinforced/shuttle - canSmoothWith = SMOOTH_GROUP_SHUTTLE_PARTS + SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE_SHUTTLE + SMOOTH_GROUP_TITANIUM_WALLS - /obj/structure/window/reinforced/fulltile/ice edge_overlay_file = null @@ -75,6 +87,24 @@ /obj/effect/spawner/structure/window icon = 'modular_bandastation/aesthetics/windows/icons/spawners.dmi' +/obj/effect/spawner/structure/window + spawn_list = MAP_SWITCH(list(/obj/structure/grille, /obj/structure/window/fulltile), list(/obj/structure/grille, /obj/structure/window/fulltile, /obj/structure/window/fulltile/frame)) + +/obj/effect/spawner/structure/window/reinforced + spawn_list = MAP_SWITCH(list(/obj/structure/grille, /obj/structure/window/reinforced/fulltile), list(/obj/structure/grille, /obj/structure/window/reinforced/fulltile, /obj/structure/window/reinforced/fulltile/frame)) + +/obj/effect/spawner/structure/window/reinforced/tinted + spawn_list = MAP_SWITCH(list(/obj/structure/grille, /obj/structure/window/reinforced/tinted/fulltile), list(/obj/structure/grille, /obj/structure/window/reinforced/tinted/fulltile, /obj/structure/window/reinforced/fulltile/frame)) + +/obj/effect/spawner/structure/window/plasma + spawn_list = MAP_SWITCH(list(/obj/structure/grille, /obj/structure/window/plasma/fulltile), list(/obj/structure/grille, /obj/structure/window/plasma/fulltile, /obj/structure/window/fulltile/frame)) + +/obj/effect/spawner/structure/window/reinforced/plasma + spawn_list = MAP_SWITCH(list(/obj/structure/grille, /obj/structure/window/reinforced/plasma/fulltile), list(/obj/structure/grille, /obj/structure/window/reinforced/plasma/fulltile, /obj/structure/window/reinforced/fulltile/frame)) + +/obj/effect/spawner/structure/window/reinforced/indestructible + spawn_list = MAP_SWITCH(list(/obj/structure/grille/indestructible, /obj/structure/window/reinforced/fulltile/indestructible), list(/obj/structure/grille/indestructible, /obj/structure/window/reinforced/fulltile/indestructible, /obj/structure/window/reinforced/fulltile/frame)) + // Override to original /obj/effect/spawner/structure/window/bronze icon = 'icons/obj/structures_spawners.dmi' @@ -99,7 +129,6 @@ icon = 'icons/bandastation/windows/reinforced_window.dmi' icon_state = "reinforced_window-0" base_icon_state = "reinforced_window" - canSmoothWith = SMOOTH_GROUP_AIRLOCK + SMOOTH_GROUP_WINDOW_FULLTILE + SMOOTH_GROUP_WALLS color = WINDOW_COLOR /// Used to define what file the edging sprite is contained within var/edge_overlay_file = 'icons/bandastation/windows/reinforced_window_edges.dmi' diff --git a/modular_bandastation/nanomap/_nanomap.dme b/modular_bandastation/nanomap/_nanomap.dme index 6baaf15eb274b..342ab11bf4aac 100644 --- a/modular_bandastation/nanomap/_nanomap.dme +++ b/modular_bandastation/nanomap/_nanomap.dme @@ -1,4 +1,5 @@ #include "_nanomap.dm" -#include "code/camera.dm" -#include "code/nanomaps_asset.dm" +#include "code/camera_console.dm" +#include "code/nanomap_assets.dm" +#include "code/nanomap_datum.dm" diff --git a/modular_bandastation/nanomap/code/camera.dm b/modular_bandastation/nanomap/code/camera.dm deleted file mode 100644 index dee5f4a6bc301..0000000000000 --- a/modular_bandastation/nanomap/code/camera.dm +++ /dev/null @@ -1,64 +0,0 @@ -/obj/machinery/camera - var/nanomap_png - -/obj/machinery/camera/Initialize(mapload, should_add_to_cameranet) - . = ..() - var/datum/space_level/z_level = LAZYACCESS(SSmapping.z_list, z) - if(isnull(z_level)) - return - if(z_level.name == "Lavaland") - nanomap_png = "Lavaland_nanomap_z1.png" - return - if(!findtext(z_level.name, "Station")) - return - nanomap_png = "[SSmapping.current_map.map_name]_nanomap_z[z-1].png" // Station starts at Z-level 2 - -/obj/machinery/computer/security - var/list/z_levels = list() // Assoc list, "z_level":"nanomap.png" - var/current_z_level_index - -/obj/machinery/computer/security/ui_assets(mob/user) - return list( - get_asset_datum(/datum/asset/simple/nanomaps), - ) - -/obj/machinery/computer/security/ui_act(action, params) - . = ..() - if(.) - return - if(action == "switch_z_level") - var/z_dir = params["z_dir"] - current_z_level_index = clamp(current_z_level_index + z_dir, 1, length(z_levels)) - return TRUE - -/obj/machinery/computer/security/ui_data() - var/list/data = ..() - if(!length(z_levels)) - return data - if(isnull(current_z_level_index)) - current_z_level_index = clamp(z_levels.Find("[z]"), 1, length(z_levels)) - else - current_z_level_index = clamp(current_z_level_index, 1, length(z_levels)) - // On null, it doesn't give runtime errors on tgui side; empty map - data["mapUrl"] = LAZYACCESS(z_levels, "[z_levels[current_z_level_index]]") - data["selected_z_level"] = LAZYACCESS(z_levels, current_z_level_index) - return data - -/obj/machinery/computer/security/ui_static_data() - var/list/data = ..() - // Sort it by z levels - z_levels = sort_list(z_levels) - return data - -/obj/machinery/computer/security/proc/update_available_z_levels(list/cameras_data) - PRIVATE_PROC(TRUE) - - for(var/list/entry as anything in cameras_data) - if(z_levels["[entry["z"]]"]) - continue - - var/obj/machinery/camera/camera = locate(entry["ref"]) - if(isnull(camera?.nanomap_png)) - continue - - z_levels["[camera.z]"] = camera.nanomap_png diff --git a/modular_bandastation/nanomap/code/camera_console.dm b/modular_bandastation/nanomap/code/camera_console.dm new file mode 100644 index 0000000000000..5d7d44f01b720 --- /dev/null +++ b/modular_bandastation/nanomap/code/camera_console.dm @@ -0,0 +1,9 @@ +/obj/machinery/computer/security/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/simple/nanomaps), + ) + +/obj/machinery/computer/security/ui_static_data() + var/list/data = ..() + data["mapData"] = SSmapping.get_map_ui_data() + return data diff --git a/modular_bandastation/nanomap/code/nanomaps_asset.dm b/modular_bandastation/nanomap/code/nanomap_assets.dm similarity index 100% rename from modular_bandastation/nanomap/code/nanomaps_asset.dm rename to modular_bandastation/nanomap/code/nanomap_assets.dm diff --git a/modular_bandastation/nanomap/code/nanomap_datum.dm b/modular_bandastation/nanomap/code/nanomap_datum.dm new file mode 100644 index 0000000000000..51dde2fc3e370 --- /dev/null +++ b/modular_bandastation/nanomap/code/nanomap_datum.dm @@ -0,0 +1,25 @@ +/** + * Returns a list of data for the nanomap map UI + */ +/datum/controller/subsystem/mapping/proc/get_map_ui_data() + if(!initialized) + stack_trace("get_map_ui_data called before initialization") + return list() + + var/static/list/map_ui_data = list() + if(!length(map_ui_data)) + var/list/station_z_levels = levels_by_trait(ZTRAIT_STATION) + var/min_station_z_level = station_z_levels[1] + var/main_station_z_level = isnull(current_map.main_floor) ? min_station_z_level : min_station_z_level + current_map.main_floor - 1 + var/max_station_z_level = station_z_levels[length(station_z_levels)] + + var/list/mining_levels = levels_by_trait(ZTRAIT_MINING) + var/lavaland_z_level = length(mining_levels) ? mining_levels[1] : null + + map_ui_data["name"] = current_map.map_name + map_ui_data["minFloor"] = min_station_z_level + map_ui_data["mainFloor"] = main_station_z_level + map_ui_data["maxFloor"] = max_station_z_level + map_ui_data["lavalandLevel"] = lavaland_z_level + + return map_ui_data diff --git a/tgui/packages/tgui/interfaces/CameraConsole220.tsx b/tgui/packages/tgui/interfaces/CameraConsole220.tsx index 46b32a26738a4..f85af36bcea77 100644 --- a/tgui/packages/tgui/interfaces/CameraConsole220.tsx +++ b/tgui/packages/tgui/interfaces/CameraConsole220.tsx @@ -11,10 +11,11 @@ import { } from 'tgui-core/components'; import { BooleanLike, classes } from 'tgui-core/react'; import { createSearch } from 'tgui-core/string'; +import { useLocalStorage } from 'usehooks-ts'; import { useBackend } from '../backend'; import { Window } from '../layouts'; -import { NanoMap } from './common/NanoMap'; +import { type MapData, NanoMap } from './common/NanoMap'; type Data = { activeCamera: Camera & { status: BooleanLike }; @@ -22,8 +23,7 @@ type Data = { can_spy: BooleanLike; mapRef: string; network: string[]; - mapUrl: string; - selected_z_level: number; + mapData: MapData; }; type Camera = { @@ -147,7 +147,7 @@ export const CameraContent = (props) => { - + ); @@ -206,45 +206,64 @@ const CameraListSelector = (props) => { export const CameraMapSelector = (props) => { const { act, data } = useBackend(); + const { activeCamera, mapData } = data; const cameras = selectCameras(data.cameras, ''); - const [zoom, setZoom] = useState(1); - const { activeCamera, mapUrl, selected_z_level } = data; + const [zoom, setZoom] = useState(); + const [selectedLevel, setSelectedLevel] = useState(mapData.mainFloor); + const [tracking, setTracking] = useLocalStorage( + 'camera-console-tracking', + false, + ); return ( - - - setZoom(v)} mapUrl={mapUrl}> - {cameras - .filter((cam) => cam.z === Number(selected_z_level)) - .map((cm) => ( - - ))} - - - + setTracking(!tracking)} + /> + } + > + {cameras.map((camera) => ( + + act('switch_camera', { + camera: camera.ref, + }) + } + /> + ))} + ); }; -const CameraControls = (props: { searchText: string; selectedTab: string }) => { +const CameraControls = (props: { searchText: string }) => { const { act, data } = useBackend(); const { activeCamera, can_spy, mapRef } = data; - const { searchText, selectedTab } = props; + const { searchText } = props; const cameras = selectCameras(data.cameras, searchText); - const [prevCamera, nextCamera] = prevNextCamera(cameras, activeCamera); return ( @@ -295,9 +314,7 @@ const CameraControls = (props: { searchText: string; selectedTab: string }) => { { - if (e.stopPropagation) { - e.stopPropagation(); - } - if (e.preventDefault) { - e.preventDefault(); - } - e.cancelBubble = true; - e.returnValue = false; - return false; -}; - -export class NanoMap extends Component { - constructor(props) { - super(props); - - this.state = { - offsetX: -32, - offsetY: 64, - transform: 'none', - dragging: false, - originX: null, - originY: null, - zoom: 1, - }; - - // Dragging - this.handleDragStart = (e) => { - this.ref = e.target; - this.setState({ - dragging: false, - originX: e.screenX, - originY: e.screenY, - }); - document.addEventListener('mousemove', this.handleDragMove); - document.addEventListener('mouseup', this.handleDragEnd); - pauseEvent(e); - }; - - this.handleDragMove = (e) => { - this.setState((prevState) => { - const state = { ...prevState }; - const newOffsetX = e.screenX - state.originX; - const newOffsetY = e.screenY - state.originY; - if (prevState.dragging) { - state.offsetX += newOffsetX; - state.offsetY += newOffsetY; - state.originX = e.screenX; - state.originY = e.screenY; - } else { - state.dragging = true; - } - return state; - }); - pauseEvent(e); - }; - - this.handleDragEnd = (e) => { - this.setState({ - dragging: false, - originX: null, - originY: null, - }); - document.removeEventListener('mousemove', this.handleDragMove); - document.removeEventListener('mouseup', this.handleDragEnd); - pauseEvent(e); - }; - - this.handleZoom = (_e, value) => { - this.setState((state) => { - const newZoom = Math.min(Math.max(value, 1), 8); - let zoomDiff = (newZoom - state.zoom) * 1.5; - state.zoom = newZoom; - state.offsetX = state.offsetX - 256 * zoomDiff; - state.offsetY = state.offsetY - 256 * zoomDiff; - if (props.onZoom) { - props.onZoom(state.zoom); - } - return state; - }); - }; - } - - render() { - const { config } = useBackend(this.context); - const { dragging, offsetX, offsetY, zoom = 1 } = this.state; - const { children } = this.props; - - const mapUrl = this.props.mapUrl || null; - const mapSize = 510 * zoom + 'px'; - const newStyle = { - width: mapSize, - height: mapSize, - 'margin-top': offsetY + 'px', - 'margin-left': offsetX + 'px', - overflow: 'hidden', - position: 'absolute', - 'background-size': 'cover', - 'background-repeat': 'no-repeat', - 'text-align': 'center', - cursor: dragging ? 'move' : 'auto', - }; - const mapStyle = { - width: '100%', - height: '100%', - position: 'absolute', - top: '50%', - left: '50%', - transform: 'translate(-50%, -50%)', - '-ms-interpolation-mode': 'nearest-neighbor', // TODO: Remove with 516 - 'image-rendering': 'pixelated', - }; - - return ( - - - - - - - - - - - - - - - - {children} - - - ); - } -} - -const NanoMapMarker = (props, context) => { - const { x, y, zoom = 1, icon, tooltip, color } = props; - const rx = x * 2 * zoom - zoom - 3; - const ry = y * 2 * zoom - zoom - 3; - return ( - - - - - - - - ); -}; - -NanoMap.Marker = NanoMapMarker; - -const NanoMapZoomer = (props, context) => { - return ( - - - v + 'x'} - value={props.zoom} - onDrag={(e, v) => props.onZoom(e, v)} - /> - - - ); -}; - -NanoMap.Zoomer = NanoMapZoomer; - -let ActiveButton; -class NanoButton extends Component { - constructor(props) { - super(props); - const { act } = useBackend(this.props.context); - this.state = { - color: this.props.color, - }; - this.handleClick = (e) => { - if (ActiveButton !== undefined) { - ActiveButton.setState({ - color: 'blue', - }); - } - act('switch_camera', { - camera: this.props.cam_ref, - }); - ActiveButton = this; - this.setState({ - color: 'green', - }); - }; - } - render() { - let rx = this.props.x * 2 * this.props.zoom - this.props.zoom - 3; - let ry = this.props.y * 2 * this.props.zoom - this.props.zoom - 3; - return ( - - ); - } -} -NanoMap.NanoButton = NanoButton; - -const NanoMapZSelector = (props, context) => { - const { act, data } = useBackend(context); - return ( - - - act('switch_z_level', { z_dir: -1 })} - /> - - - act('switch_z_level', { z_dir: 1 })} - /> - - - ); -}; diff --git a/tgui/packages/tgui/interfaces/common/NanoMap.tsx b/tgui/packages/tgui/interfaces/common/NanoMap.tsx new file mode 100644 index 0000000000000..ec3851b4472b2 --- /dev/null +++ b/tgui/packages/tgui/interfaces/common/NanoMap.tsx @@ -0,0 +1,420 @@ +import '../../styles/interfaces/NanoMap.scss'; + +import { type ReactNode, useMemo, useState } from 'react'; +import { + KeepScale, + MiniMap, + TransformComponent, + TransformWrapper, + useControls, +} from 'react-zoom-pan-pinch'; +import { + Button, + Icon, + Image, + LabeledList, + Modal, + Section, + Stack, +} from 'tgui-core/components'; +import { clamp01 } from 'tgui-core/math'; +import { BooleanLike, classes } from 'tgui-core/react'; +import { debounce } from 'tgui-core/timer'; +import { useLocalStorage } from 'usehooks-ts'; + +import { resolveAsset } from '../../assets'; +import { useSharedState } from '../../backend'; + +export type MapData = { + name: string; + minFloor: number; + mainFloor: number; + maxFloor: number; + lavalandLevel: number; +}; + +type Props = { + /** Content on map. Like buttons. Use only NanoMap.xxx components */ + children?: ReactNode; + /** Additional control buttons container */ + buttons?: ReactNode; + /** Enables centering on selected target */ + selectedTarget?: BooleanLike; + /** Allows you to disable minimap */ + minimapDisabled?: BooleanLike; + /** + * Changes minimap position. + ** Allowed values: 'top-left', 'top-right', 'bottom-left', 'bottom-right' + ** Default: 'top-left' + */ + minimapPosition?: MinimapPosition; + /** All needed map data from backend */ + mapData: MapData; + /** UI name for shared state */ + uiName?: string; + /** Called when level changes. Returns current level */ + onLevelChange: (level: number) => void; + /** Called when zoom level changes. Returns zoom level */ + onZoomChange?: (zoom: number) => void; +}; + +type MinimapPosition = + | 'top-left' + | 'top-right' + | 'bottom-left' + | 'bottom-right'; + +const defaultScale = 0.125; +const maxScale = defaultScale * 8; + +const defaultMapSize = 4080; +const tileSize = defaultMapSize / 255; + +/** Converts object position to pixel position.*/ +function posToPx(pos: number) { + return `${pos * tileSize - tileSize}px`; +} + +export function NanoMap(props: Props) { + const { + children, + buttons, + mapData, + uiName, + minimapDisabled, + minimapPosition, + selectedTarget, + onLevelChange, + onZoomChange, + } = props; + + const [prefs, setPrefs] = useState(false); + const [mapPrefs, setMapPrefs] = useLocalStorage('nanomap-preferences', { + velocity: true, + minimap: true, + minimapPosition: 'top-left', + }); + const [mapState, setMapState] = uiName + ? useSharedState(`${uiName}-nanomap`, { + scale: defaultScale, + positionX: 0, + positionY: 0, + currentLevel: mapData.mainFloor, + }) + : useState({ + scale: defaultScale, + positionX: 0, + positionY: 0, + currentLevel: mapData.mainFloor, + }); + + function getMapImage(level) { + const { name, lavalandLevel, minFloor } = mapData; + let imageAsset; + if (level === lavalandLevel && lavalandLevel !== minFloor) { + imageAsset = resolveAsset(`Lavaland_nanomap_z1.png`); + } else { + imageAsset = resolveAsset(`${name}_nanomap_z${level - 1}.png`); + } + return ( + + ); + } + + // Send component data to UI, if he has useState for them. + onLevelChange && onLevelChange(mapState.currentLevel); + const handleTransformed = useMemo( + () => + debounce(({ state }) => { + setMapState({ + scale: state.scale, + positionX: state.positionX, + positionY: state.positionY, + currentLevel: mapState.currentLevel, + }); + + if (onZoomChange) { + onZoomChange(state.scale); + } + }, 125), + [mapState.currentLevel], + ); + + return ( + + + {prefs && ( + + )} + + + + + {buttons} + + {!minimapDisabled && mapPrefs.minimap && ( + + {getMapImage(mapState.currentLevel)} + + )} + + + + {getMapImage(mapState.currentLevel)} + {children} + + + + + + ); +} + +function NanoMapControls(props) { + const { zoom, selectedTarget } = props; + const { zoomIn, zoomOut, centerView, zoomToElement } = useControls(); + return ( + + zoomIn(maxScale)} /> + + selectedTarget ? zoomToElement('selected', 200) : centerView() + } + > + + Центр + + zoomOut(maxScale)} /> + + ); +} + +function NanoMapButtons(props) { + const { children, prefs, setPrefs, mapData, mapState, setMapState } = props; + return ( + + + + + {children} + + setPrefs(!prefs)} + /> + + + ); +} + +function NanoMapLevelSelector(props) { + const { mapData, mapState, setMapState } = props; + const { minFloor, maxFloor, mainFloor, lavalandLevel } = mapData; + const { currentLevel } = mapState; + + function setLevel(level: number) { + setMapState({ + scale: mapState.scale, + positionX: mapState.positionX, + positionY: mapState.positionY, + currentLevel: level, + }); + } + + return ( + + {minFloor !== maxFloor && ( + <> + + = maxFloor} + onClick={() => setLevel(currentLevel + 1)} + /> + + + maxFloor || currentLevel <= minFloor} + onClick={() => setLevel(currentLevel - 1)} + /> + + > + )} + {lavalandLevel > maxFloor && ( + + + setLevel( + currentLevel === lavalandLevel ? mainFloor : lavalandLevel, + ) + } + /> + + )} + + ); +} + +function NanoMapPreferences(props) { + const { mapPrefs, setMapPrefs, setPrefs, minimapDisabled } = props; + const minimapPositions: Record = { + 'top-left': -90, + 'top-right': 0, + 'bottom-left': 180, + 'bottom-right': 90, + }; + + const cannotSetPrefText = minimapDisabled + ? 'В данном интерфейсе нельзя изменять параметры мини-карты, и её состояние.' + : undefined; + + return ( + + setPrefs(false)} /> + } + > + + + + {Object.keys(minimapPositions).map((key) => ( + + setMapPrefs((old) => ({ ...old, minimapPosition: key })) + } + > + + + ))} + + + + + setMapPrefs((old) => ({ ...old, velocity: !old.velocity })) + } + /> + + + + setMapPrefs((old) => ({ ...old, minimap: !old.minimap })) + } + /> + + + + + ); +} + +/** TODO: Add types when types will exported */ +function MapButton(props) { + const { tracking = false, zoom, posX, posY, hidden, ...rest } = props; + const { zoomToElement } = useControls(); + const buttonId = `${posX}_${posY}`; + + return ( + + + { + tracking && zoomToElement(buttonId, zoom, 200); + if (props.onClick) { + props.onClick(event); + } + }} + /> + + + ); +} + +NanoMap.Button = MapButton; diff --git a/tgui/packages/tgui/package.json b/tgui/packages/tgui/package.json index 0840a97b89b0d..efca9446fcdf5 100644 --- a/tgui/packages/tgui/package.json +++ b/tgui/packages/tgui/package.json @@ -18,8 +18,10 @@ "react": "^18.3.1", "react-dom": "^18.3.1", "react-popper": "^2.3.0", + "react-zoom-pan-pinch": "^3.7.0", "tgui-core": "^1.8.1", "tgui-dev-server": "workspace:*", - "tgui-polyfill": "workspace:*" + "tgui-polyfill": "workspace:*", + "usehooks-ts": "^3.1.1" } } diff --git a/tgui/packages/tgui/styles/interfaces/NanoMap.scss b/tgui/packages/tgui/styles/interfaces/NanoMap.scss index a8406cc9fefd9..ceff51dd2b9b6 100644 --- a/tgui/packages/tgui/styles/interfaces/NanoMap.scss +++ b/tgui/packages/tgui/styles/interfaces/NanoMap.scss @@ -1,29 +1,202 @@ -$background-color: rgba(0, 0, 0, 0.33) !default; +@use '../colors.scss' as colors; +@use '../functions.scss' as *; -.NanoMap__container { - overflow: hidden; - position: relative; - z-index: 1; -} +$background-color: hsla(0, 0%, 10%, 0.85); +$border-color: hsla(255, 255%, 255%, 0.1); +$border-radius: 0.5rem; +$box-shadow: 0 1px 0.2rem hsla(0, 0%, 0%, 0.75); +$blur: saturate(150%) blur(12px); -.NanoMap__toolbar { - width: 49%; - z-index: 2; -} +@mixin nanoButton() { + cursor: pointer; + pointer-events: all; + background-color: $background-color; + color: hsla(255, 255%, 255%, 0.66); + border: 1px solid $border-color; + border-radius: $border-radius; + box-shadow: $box-shadow; + backdrop-filter: $blur; + + &:hover { + background-color: lighten($background-color, 25%); + color: hsla(255, 255%, 255%, 1); + } -.NanoMap__marker { - z-index: 10; - padding: 0px; - margin: 0px; + &--selected { + color: colors.$green; + + &:hover { + color: lighten(colors.$green, 25%); + } + } + + &--disabled { + cursor: unset; + background-color: lighten($background-color, 25%) !important; + color: lighten(colors.$red, 25%) !important; + } } -.NanoMap__button { - padding: 3px 3px; - font-size: 6px; - border: 2px solid black; - height: 10px; +.NanoMap { + &__Controls { + display: flex; + align-items: baseline; + justify-content: center; + text-align: center; + gap: 0.25rem; + padding: 0 0.5rem; + z-index: 3; + + .Button { + @include nanoButton(); + } + + &--zoom { + position: absolute; + inset: 0; + height: 100%; + background-color: rgba(lighten(colors.$green, 25%), 0.33); + border-radius: $border-radius; + transition: width 0.2s; + z-index: -1; + } + } + + &__Buttons { + padding: 0.5rem 0; + z-index: 3; + + .Button { + @include nanoButton(); + } + } + + &__Minimap { + user-select: none; + background-color: $background-color; + border: 1px solid $border-color; + border-radius: $border-radius; + box-shadow: $box-shadow; + backdrop-filter: $blur; + + .rzpp-preview { + border: 1px solid rgba($border-color, 0.33) !important; + box-shadow: rgba(0, 0, 0, 0.2) 0px 0px 0px 9999px !important; + } + } + + &__Object { + cursor: pointer; + font-size: 6px; + line-height: 0; + padding: 0; + height: 2em; + width: 2em; + border: 2px solid rgba(0, 0, 0, 0.66); + border-radius: 0.25rem; + + &--wrapper { + position: absolute; + transform: translate(17.5%, 5%); + z-index: 2; + } + + &--hidden { + display: none; + } + } } -.NanoMap__button:hover { - background-color: greenyellow; +/** Positioning */ +.NanoMap { + position: relative; + + &__Controls, + &__Buttons, + &__Minimap--container { + position: absolute; + } + + &__Minimap--container { + top: 0.25rem; + left: 0.25rem; + z-index: 3; + } + + &__Controls { + right: 0; + bottom: -2.25rem; + left: 0; + } + + &__Buttons { + top: 0; + right: -2.25rem; + bottom: 0; + } + + &--top-right, + &--bottom-right { + .NanoMap__Minimap--container { + right: 0.25rem; + left: unset; + } + } + + &--bottom-left, + &--bottom-right { + .NanoMap__Minimap--container { + top: unset; + bottom: 0.25rem; + } + } + + &--bottom-left, + &--bottom-right { + .NanoMap__Controls { + top: -2.1rem; + bottom: unset; + } + } + + &--top-right, + &--bottom-right { + .NanoMap__Buttons { + right: unset; + left: -2.25rem; + } + } + + /** Disabled minimap layout */ + &__Minimap--disabled { + pointer-events: none; + inset: 0 !important; + display: flex; + margin: 0.25rem; + align-items: flex-start; + justify-content: space-between; + + .NanoMap__Controls, + .NanoMap__Buttons { + position: relative; + pointer-events: all; + inset: unset; + padding: 0; + + * { + flex-basis: unset !important; + } + } + + .NanoMap__Controls { + width: 150px; + } + } + + &--bottom-left, + &--bottom-right { + .NanoMap__Minimap--disabled { + align-items: flex-end; + } + } } diff --git a/tgui/yarn.lock b/tgui/yarn.lock index ddbb0433c9014..538d4b8119b2f 100644 --- a/tgui/yarn.lock +++ b/tgui/yarn.lock @@ -16347,6 +16347,16 @@ __metadata: languageName: node linkType: hard +"react-zoom-pan-pinch@npm:^3.7.0": + version: 3.7.0 + resolution: "react-zoom-pan-pinch@npm:3.7.0" + peerDependencies: + react: "*" + react-dom: "*" + checksum: 10c0/96889849800a953128fe7f9e42bed0d5cbc48d03024995b136f5e972146236688efb24d7381d8e6f09598f5512b4897d2420f62d828a665fdf24b745b7d55911 + languageName: node + linkType: hard + "react@npm:^17.0.1": version: 17.0.2 resolution: "react@npm:17.0.2" @@ -18850,9 +18860,11 @@ __metadata: react: "npm:^18.3.1" react-dom: "npm:^18.3.1" react-popper: "npm:^2.3.0" + react-zoom-pan-pinch: "npm:^3.7.0" tgui-core: "npm:^1.8.1" tgui-dev-server: "workspace:*" tgui-polyfill: "workspace:*" + usehooks-ts: "npm:^3.1.1" languageName: unknown linkType: soft @@ -19642,6 +19654,17 @@ __metadata: languageName: node linkType: hard +"usehooks-ts@npm:^3.1.1": + version: 3.1.1 + resolution: "usehooks-ts@npm:3.1.1" + dependencies: + lodash.debounce: "npm:^4.0.8" + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 || ^19.0.0-rc + checksum: 10c0/8bbebf52b063f2e705eb27364f08ec2eff987b9e8d28d82a28248652dd89ef53cb514e1f2ee1cbc6ac6e083a8dce86310301c3e92a99902b98c32a26381202d7 + languageName: node + linkType: hard + "util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" diff --git a/tools/nanomap_renderer/README.MD b/tools/nanomap_renderer/README.MD index 74b31f5bdd699..6887f14a3ecc9 100644 --- a/tools/nanomap_renderer/README.MD +++ b/tools/nanomap_renderer/README.MD @@ -2,5 +2,5 @@ This folder contains all the script and tools required for GitHub actions. If you add something to this directory, **PLEASE** document it in here -- `nanomap-renderer` - A linux application to render NanoMap images of the ingame maps automatically. Based off of SpacemanDMM (Modified source [here](https://github.com/AffectedArc07/ParaSpacemanDMM), original source [here](https://github.com/Spacemaniac/SpacemanDMM)) +- `nanomap-renderer` - A linux application to render NanoMap images of the ingame maps automatically. Based off of SpacemanDMM (Modified source [here](https://github.com/ss220club/BandaStationSDMM), Original modified source [here](https://github.com/AffectedArc07/ParaSpacemanDMM), original source [here](https://github.com/Spacemaniac/SpacemanDMM)) - `nanomap-renderer-invoker.sh` - A script which invokes the render tool and clones the maps to the correct directory diff --git a/tools/nanomap_renderer/nanomap-renderer b/tools/nanomap_renderer/nanomap-renderer index 8f5dfdd19da9a..b63cf28649aef 100755 Binary files a/tools/nanomap_renderer/nanomap-renderer and b/tools/nanomap_renderer/nanomap-renderer differ diff --git a/tools/nanomap_renderer/nanomap-renderer-invoker.sh b/tools/nanomap_renderer/nanomap-renderer-invoker.sh index 42ad0701056ea..17e45bfe89195 100755 --- a/tools/nanomap_renderer/nanomap-renderer-invoker.sh +++ b/tools/nanomap_renderer/nanomap-renderer-invoker.sh @@ -11,35 +11,29 @@ tools/nanomap_renderer/nanomap-renderer minimap --w 2040 --h 2040 "./_maps/map_f tools/nanomap_renderer/nanomap-renderer minimap --w 2040 --h 2040 "./_maps/map_files/wawastation/wawastation.dmm" tools/nanomap_renderer/nanomap-renderer minimap --w 2040 --h 2040 "./_maps/map_files/Mining/Lavaland.dmm" # Move and rename files so the game understands them -cd "data/minimaps" -mv "birdshot-1.png" "Birdshot Station_nanomap_z1.png" -mv "Cyberiad-1.png" "Cyberiad_nanomap_z1.png" -mv "Cyberiad-2.png" "Cyberiad_nanomap_z2.png" -mv "DeltaStation2-1.png" "Delta Station_nanomap_z1.png" -mv "IceBoxStation-1.png" "Ice Box Station_nanomap_z1.png" -mv "IceBoxStation-2.png" "Ice Box Station_nanomap_z2.png" -mv "IceBoxStation-3.png" "Ice Box Station_nanomap_z3.png" -mv "MetaStation-1.png" "MetaStation_nanomap_z1.png" -mv "NebulaStation-1.png" "NebulaStation_nanomap_z1.png" -mv "NebulaStation-2.png" "NebulaStation_nanomap_z2.png" -mv "tramstation-1.png" "Tramstation_nanomap_z1.png" -mv "tramstation-2.png" "Tramstation_nanomap_z2.png" -mv "wawastation-1.png" "Wawastation_nanomap_z1.png" -mv "wawastation-2.png" "Wawastation_nanomap_z2.png" -mv "Lavaland-1.png" "Lavaland_nanomap_z1.png" +cd "data/nanomaps" +mv "birdshot_nanomap_z1.png" "Birdshot Station_nanomap_z1.png" +mv "DeltaStation2_nanomap_z1.png" "Delta Station_nanomap_z1.png" +mv "IceBoxStation_nanomap_z1.png" "Ice Box Station_nanomap_z1.png" +mv "IceBoxStation_nanomap_z2.png" "Ice Box Station_nanomap_z2.png" +mv "IceBoxStation_nanomap_z3.png" "Ice Box Station_nanomap_z3.png" +mv "tramstation_nanomap_z1.png" "Tramstation_nanomap_z1.png" +mv "tramstation_nanomap_z2.png" "Tramstation_nanomap_z2.png" +mv "wawastation_nanomap_z1.png" "Wawastation_nanomap_z1.png" +mv "wawastation_nanomap_z2.png" "Wawastation_nanomap_z2.png" cd "../../" -cp "data/minimaps/Birdshot Station_nanomap_z1.png" "icons/_nanomaps" -cp "data/minimaps/Cyberiad_nanomap_z1.png" "icons/_nanomaps" -cp "data/minimaps/Cyberiad_nanomap_z2.png" "icons/_nanomaps" -cp "data/minimaps/Delta Station_nanomap_z1.png" "icons/_nanomaps" -cp "data/minimaps/Ice Box Station_nanomap_z1.png" "icons/_nanomaps" -cp "data/minimaps/Ice Box Station_nanomap_z2.png" "icons/_nanomaps" -cp "data/minimaps/Ice Box Station_nanomap_z3.png" "icons/_nanomaps" -cp "data/minimaps/MetaStation_nanomap_z1.png" "icons/_nanomaps" -cp "data/minimaps/NebulaStation_nanomap_z1.png" "icons/_nanomaps" -cp "data/minimaps/NebulaStation_nanomap_z2.png" "icons/_nanomaps" -cp "data/minimaps/Tramstation_nanomap_z1.png" "icons/_nanomaps" -cp "data/minimaps/Tramstation_nanomap_z2.png" "icons/_nanomaps" -cp "data/minimaps/Wawastation_nanomap_z1.png" "icons/_nanomaps" -cp "data/minimaps/Wawastation_nanomap_z2.png" "icons/_nanomaps" -cp "data/minimaps/Lavaland_nanomap_z1.png" "icons/_nanomaps" +cp "data/nanomaps/Birdshot Station_nanomap_z1.png" "icons/_nanomaps" +cp "data/nanomaps/Cyberiad_nanomap_z1.png" "icons/_nanomaps" +cp "data/nanomaps/Cyberiad_nanomap_z2.png" "icons/_nanomaps" +cp "data/nanomaps/Delta Station_nanomap_z1.png" "icons/_nanomaps" +cp "data/nanomaps/Ice Box Station_nanomap_z1.png" "icons/_nanomaps" +cp "data/nanomaps/Ice Box Station_nanomap_z2.png" "icons/_nanomaps" +cp "data/nanomaps/Ice Box Station_nanomap_z3.png" "icons/_nanomaps" +cp "data/nanomaps/MetaStation_nanomap_z1.png" "icons/_nanomaps" +cp "data/nanomaps/NebulaStation_nanomap_z1.png" "icons/_nanomaps" +cp "data/nanomaps/NebulaStation_nanomap_z2.png" "icons/_nanomaps" +cp "data/nanomaps/Tramstation_nanomap_z1.png" "icons/_nanomaps" +cp "data/nanomaps/Tramstation_nanomap_z2.png" "icons/_nanomaps" +cp "data/nanomaps/Wawastation_nanomap_z1.png" "icons/_nanomaps" +cp "data/nanomaps/Wawastation_nanomap_z2.png" "icons/_nanomaps" +cp "data/nanomaps/Lavaland_nanomap_z1.png" "icons/_nanomaps"