diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index 9a55bb7127b..b8b361b8747 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -14985,9 +14985,7 @@ /obj/structure/window/reinforced{ dir = 1 }, -/obj/machinery/computer/exodrone_control_console{ - dir = 2 - }, +/obj/machinery/computer/exodrone_control_console, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -46663,8 +46661,14 @@ /area/maintenance/port/aft) "gKR" = ( /obj/structure/table/wood, -/obj/item/paper_bin, -/obj/item/pen, +/obj/item/paper_bin{ + pixel_x = 5; + pixel_y = 3 + }, +/obj/item/pen{ + pixel_x = 5; + pixel_y = 3 + }, /obj/machinery/status_display/evac/directional/south, /obj/effect/turf_decal/tile/neutral{ dir = 1 @@ -46676,6 +46680,13 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/item/folder{ + pixel_x = -6; + pixel_y = 2 + }, +/obj/item/laser_pointer{ + pixel_x = 3 + }, /turf/open/floor/iron/dark, /area/service/library) "gKX" = ( @@ -58013,9 +58024,7 @@ /obj/structure/window/reinforced{ dir = 1 }, -/obj/machinery/computer/exoscanner_control{ - dir = 2 - }, +/obj/machinery/computer/exoscanner_control, /obj/effect/turf_decal/stripes/line{ dir = 1 }, @@ -84306,8 +84315,7 @@ }, /obj/structure/table/reinforced, /obj/item/paper_bin{ - pixel_x = -7; - pixel_y = 0 + pixel_x = -7 }, /obj/item/pen{ pixel_x = -7 @@ -110737,12 +110745,10 @@ /area/medical/surgery/room_b) "xNJ" = ( /obj/machinery/light/directional/south, -/obj/structure/table/wood, -/obj/item/folder, -/obj/item/laser_pointer{ - pixel_x = 3 - }, /obj/item/radio/intercom/directional/south, +/obj/machinery/modular_computer/console/preset/curator{ + dir = 1 + }, /turf/open/floor/iron/dark, /area/service/library) "xNR" = ( diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index 8eb51b423b7..30289a58aa9 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -27843,9 +27843,15 @@ /area/maintenance/space_hut/cabin) "gZl" = ( /obj/structure/table/wood, -/obj/item/pen/red, +/obj/item/paper_bin{ + pixel_x = -4; + pixel_y = 3 + }, +/obj/item/pen/red{ + pixel_x = -6 + }, /obj/item/pen/blue{ - pixel_x = 5; + pixel_x = -1; pixel_y = 5 }, /turf/open/floor/wood, @@ -40696,7 +40702,9 @@ /turf/open/floor/iron/dark, /area/ai_monitored/command/nuke_storage) "osm" = ( -/obj/machinery/libraryscanner, +/obj/machinery/modular_computer/console/preset/curator{ + dir = 8 + }, /turf/open/floor/wood, /area/service/library) "oss" = ( @@ -52282,10 +52290,7 @@ /area/medical/virology) "uSm" = ( /obj/structure/table/wood, -/obj/item/paper_bin{ - pixel_x = 1; - pixel_y = 9 - }, +/obj/machinery/libraryscanner, /turf/open/floor/wood, /area/service/library) "uSw" = ( diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm index 317b9c4acde..b60b387d8b0 100644 --- a/_maps/map_files/KiloStation/KiloStation.dmm +++ b/_maps/map_files/KiloStation/KiloStation.dmm @@ -53935,9 +53935,17 @@ pixel_x = -4; pixel_y = 4 }, -/obj/item/camera, /obj/machinery/computer/security/telescreen/entertainment/directional/south, /obj/effect/decal/cleanable/dirt, +/obj/item/taperecorder{ + pixel_x = 5; + pixel_y = 4 + }, +/obj/item/camera, +/obj/item/pen{ + pixel_x = -7; + pixel_y = -5 + }, /turf/open/floor/iron/dark, /area/service/library) "iKn" = ( @@ -58302,6 +58310,10 @@ /obj/machinery/light_switch/directional/north, /obj/machinery/newscaster/security_unit/directional/west, /obj/effect/decal/cleanable/dirt, +/obj/item/storage/fancy/candle_box{ + pixel_x = 4; + pixel_y = 4 + }, /turf/open/floor/iron/dark, /area/service/library) "kBH" = ( @@ -70583,19 +70595,12 @@ /obj/effect/turf_decal/tile/neutral{ dir = 1 }, -/obj/structure/table/wood, -/obj/item/storage/fancy/candle_box{ - pixel_x = 4; - pixel_y = 4 - }, -/obj/item/taperecorder{ - pixel_x = -4; - pixel_y = 4 - }, -/obj/item/pen, /obj/machinery/light/small/directional/south, /obj/item/radio/intercom/directional/south, /obj/effect/decal/cleanable/dirt, +/obj/machinery/modular_computer/console/preset/curator{ + dir = 1 + }, /turf/open/floor/iron/dark, /area/service/library) "pSI" = ( diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 76f11155bc1..253c8cdb987 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -69964,6 +69964,9 @@ /area/commons/dorms) "uRq" = ( /obj/machinery/light_switch/directional/east, +/obj/machinery/modular_computer/console/preset/curator{ + dir = 8 + }, /turf/open/floor/wood, /area/service/library) "uRy" = ( diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index d89b4fbb130..e4f87b4ae88 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -1980,8 +1980,20 @@ "ahj" = ( /obj/structure/table/wood, /obj/effect/turf_decal/siding/wood/corner, +/obj/item/clipboard, /obj/item/folder, -/obj/item/pen/red, +/obj/item/pen/red{ + pixel_x = -5 + }, +/obj/item/pen{ + pixel_x = 5 + }, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/structure/window/reinforced{ + dir = 1 + }, /turf/open/floor/wood, /area/service/library) "ahl" = ( @@ -5284,12 +5296,13 @@ /area/cargo/qm) "arj" = ( /obj/structure/table/wood, +/obj/structure/window/reinforced, /obj/item/camera_film{ pixel_x = 3; pixel_y = 3 }, /obj/item/camera_film, -/obj/structure/window/reinforced, +/obj/item/storage/photo_album/library, /turf/open/floor/wood, /area/service/library) "ark" = ( @@ -72049,13 +72062,15 @@ /turf/open/floor/iron/white, /area/medical/virology) "xNF" = ( -/obj/structure/table/wood, /obj/effect/turf_decal/siding/wood{ dir = 4 }, -/obj/item/clipboard, -/obj/item/pen, -/obj/item/storage/photo_album/library, +/obj/structure/window/reinforced{ + dir = 4 + }, +/obj/machinery/modular_computer/console/preset/curator{ + dir = 8 + }, /turf/open/floor/wood, /area/service/library) "xNN" = ( diff --git a/code/__DEFINES/art.dm b/code/__DEFINES/art.dm new file mode 100644 index 00000000000..473f7f3565e --- /dev/null +++ b/code/__DEFINES/art.dm @@ -0,0 +1,5 @@ + +///tgui tab portrait categories- they're the same across all portrait tguis. +#define TAB_LIBRARY 1 +#define TAB_SECURE 2 +#define TAB_PRIVATE 3 diff --git a/code/game/objects/structures/artstuff.dm b/code/game/objects/structures/artstuff.dm index f3c0f75e5eb..11c566b5a6f 100644 --- a/code/game/objects/structures/artstuff.dm +++ b/code/game/objects/structures/artstuff.dm @@ -52,6 +52,8 @@ var/author_ckey var/icon_generated = FALSE var/icon/generated_icon + ///boolean that blocks persistence from saving it. enabled from printing copies, because we do not want to save copies. + var/no_save = FALSE // Painting overlay offset when framed var/framed_offset_x = 11 @@ -372,7 +374,7 @@ update_appearance() /obj/structure/sign/painting/proc/save_persistent() - if(!persistence_id || !current_canvas) + if(!persistence_id || !current_canvas || current_canvas.no_save) return if(sanitize_filename(persistence_id) != persistence_id) stack_trace("Invalid persistence_id - [persistence_id]") diff --git a/code/modules/mob/living/silicon/ai/ai_portrait_picker.dm b/code/modules/mob/living/silicon/ai/ai_portrait_picker.dm index ba785251b77..45ddb425039 100644 --- a/code/modules/mob/living/silicon/ai/ai_portrait_picker.dm +++ b/code/modules/mob/living/silicon/ai/ai_portrait_picker.dm @@ -1,14 +1,10 @@ -//Portrait picker! It's a tgui window that lets you look through all the portraits, and choose one as your AI. - -//very similar to centcom_podlauncher in terms of how this is coded, so i kept a lot of comments from it -//^ wow! it's the second time i've said this! i'm a real coder now, copying my statement of copying other people's stuff. - - -#define TAB_LIBRARY 1 -#define TAB_SECURE 2 -#define TAB_PRIVATE 3 - +/** + * ## Portrait picker!! + * + * It's a tgui window that lets you look through all the portraits, and choose one as your AI. + * very similar to centcom_podlauncher in terms of how this is coded, so i kept a lot of comments from it + */ /datum/portrait_picker var/client/holder //client of whoever is using this datum diff --git a/code/modules/modular_computers/computers/machinery/console_presets.dm b/code/modules/modular_computers/computers/machinery/console_presets.dm index 5909faf0767..e5cc515d119 100644 --- a/code/modules/modular_computers/computers/machinery/console_presets.dm +++ b/code/modules/modular_computers/computers/machinery/console_presets.dm @@ -107,6 +107,17 @@ hard_drive.store_file(new/datum/computer_file/program/chatclient()) hard_drive.store_file(new/datum/computer_file/program/arcade()) +// curator +/obj/machinery/modular_computer/console/preset/curator + console_department = "Civilian" + name = "curator console" + desc = "A stationary computer. This one comes preloaded with art programs." + _has_printer = TRUE + +/obj/machinery/modular_computer/console/preset/curator/install_programs() + var/obj/item/computer_hardware/hard_drive/hard_drive = cpu.all_components[MC_HDD] + hard_drive.store_file(new/datum/computer_file/program/portrait_printer()) + // ===== CARGO CHAT CONSOLES ===== /obj/machinery/modular_computer/console/preset/cargochat name = "cargo chatroom console" diff --git a/code/modules/modular_computers/file_system/programs/portrait_printer.dm b/code/modules/modular_computers/file_system/programs/portrait_printer.dm new file mode 100644 index 00000000000..b622cde0798 --- /dev/null +++ b/code/modules/modular_computers/file_system/programs/portrait_printer.dm @@ -0,0 +1,83 @@ + +///how much paper it takes from the printer to create a canvas. +#define CANVAS_PAPER_COST 10 + +/** + * ## portrait printer! + * + * Program that lets the curator browse all of the portraits in the database + * They are free to print them out as they please. + */ +/datum/computer_file/program/portrait_printer + filename = "PortraitPrinter" + filedesc = "Marlowe Treeby's Art Galaxy" + category = PROGRAM_CATEGORY_CREW + program_icon_state = "dummy" + extended_desc = "This program connects to a Spinward Sector community art site for viewing and printing art." + transfer_access = ACCESS_LIBRARY + usage_flags = PROGRAM_CONSOLE + requires_ntnet = TRUE + size = 9 + tgui_id = "NtosPortraitPrinter" + program_icon = "paint-brush" + +/datum/computer_file/program/portrait_printer/ui_data(mob/user) + var/list/data = list() + data["library"] = SSpersistence.paintings["library"] ? SSpersistence.paintings["library"] : 0 + data["library_secure"] = SSpersistence.paintings["library_secure"] ? SSpersistence.paintings["library_secure"] : 0 + data["library_private"] = SSpersistence.paintings["library_private"] ? SSpersistence.paintings["library_private"] : 0 //i'm gonna regret this, won't i? + return data + +/datum/computer_file/program/portrait_printer/ui_assets(mob/user) + return list( + get_asset_datum(/datum/asset/simple/portraits/library), + get_asset_datum(/datum/asset/simple/portraits/library_secure), + get_asset_datum(/datum/asset/simple/portraits/library_private) + ) + +/datum/computer_file/program/portrait_printer/ui_act(action, params) + . = ..() + if(.) + return + + //printer check! + var/obj/item/computer_hardware/printer/printer + if(computer) + printer = computer.all_components[MC_PRINT] + if(!printer) + to_chat(usr, "Hardware error: A printer is required to print a canvas.") + return + if(printer.stored_paper < CANVAS_PAPER_COST) + to_chat(usr, "Printing error: Your printer needs at least [CANVAS_PAPER_COST] paper to print a canvas.") + return + printer.stored_paper -= CANVAS_PAPER_COST + + //canvas printing! + var/list/tab2key = list(TAB_LIBRARY = "library", TAB_SECURE = "library_secure", TAB_PRIVATE = "library_private") + var/folder = tab2key[params["tab"]] + var/list/current_list = SSpersistence.paintings[folder] + var/list/chosen_portrait = current_list[params["selected"]] + var/author = chosen_portrait["author"] + var/title = chosen_portrait["title"] + var/png = "data/paintings/[folder]/[chosen_portrait["md5"]].png" + var/icon/art_icon = new(png) + var/obj/item/canvas/printed_canvas + var/art_width = art_icon.Width() + var/art_height = art_icon.Height() + for(var/canvas_type in typesof(/obj/item/canvas)) + printed_canvas = canvas_type + if(initial(printed_canvas.width) == art_width && initial(printed_canvas.height) == art_height) + printed_canvas = new canvas_type(get_turf(computer.physical)) + break + printed_canvas.fill_grid_from_icon(art_icon) + printed_canvas.generated_icon = art_icon + printed_canvas.icon_generated = TRUE + printed_canvas.finalized = TRUE + printed_canvas.painting_name = title + printed_canvas.author_ckey = author + printed_canvas.name = "painting - [title]" + ///this is a copy of something that is already in the database- it should not be able to be saved. + printed_canvas.no_save = TRUE + printed_canvas.update_icon() + to_chat(usr, "You have printed [title] onto a new canvas.") + playsound(computer.physical, 'sound/items/poster_being_created.ogg', 100, TRUE) diff --git a/tgstation.dme b/tgstation.dme index 4432a414ff6..efb4a9fd5e5 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -31,6 +31,7 @@ #include "code\__DEFINES\ai.dm" #include "code\__DEFINES\antagonists.dm" #include "code\__DEFINES\aquarium.dm" +#include "code\__DEFINES\art.dm" #include "code\__DEFINES\atmospherics.dm" #include "code\__DEFINES\atom_hud.dm" #include "code\__DEFINES\bitfields.dm" @@ -2816,6 +2817,7 @@ #include "code\modules\modular_computers\file_system\programs\ntdownloader.dm" #include "code\modules\modular_computers\file_system\programs\ntmonitor.dm" #include "code\modules\modular_computers\file_system\programs\ntnrc_client.dm" +#include "code\modules\modular_computers\file_system\programs\portrait_printer.dm" #include "code\modules\modular_computers\file_system\programs\powermonitor.dm" #include "code\modules\modular_computers\file_system\programs\radar.dm" #include "code\modules\modular_computers\file_system\programs\robocontrol.dm" diff --git a/tgui/packages/tgui/interfaces/NtosPortraitPrinter.js b/tgui/packages/tgui/interfaces/NtosPortraitPrinter.js new file mode 100644 index 00000000000..23312d6a09e --- /dev/null +++ b/tgui/packages/tgui/interfaces/NtosPortraitPrinter.js @@ -0,0 +1,140 @@ +import { resolveAsset } from '../assets'; +import { useBackend, useLocalState } from '../backend'; +import { Button, NoticeBox, Section, Stack, Tabs } from '../components'; +import { NtosWindow } from '../layouts'; + +export const NtosPortraitPrinter = (props, context) => { + const { act, data } = useBackend(context); + const [tabIndex, setTabIndex] = useLocalState(context, 'tabIndex', 0); + const [listIndex, setListIndex] = useLocalState(context, 'listIndex', 0); + const { + library, + library_secure, + library_private, + } = data; + const TABS = [ + { + name: 'Common Portraits', + asset_prefix: "library", + list: library, + }, + { + name: 'Secure Portraits', + asset_prefix: "library_secure", + list: library_secure, + }, + { + name: 'Private Portraits', + asset_prefix: "library_private", + list: library_private, + }, + ]; + const tab2list = TABS[tabIndex].list; + const current_portrait_title = tab2list[listIndex]["title"]; + const current_portrait_asset_name = TABS[tabIndex].asset_prefix + "_" + tab2list[listIndex]["md5"]; + return ( + + + + +
+ + {TABS.map((tabObj, i) => !!tabObj.list && ( + { + setListIndex(0); + setTabIndex(i); + }}> + {tabObj.name} + + ))} + +
+
+ +
+ + + + + + {current_portrait_title} + + +
+
+ + + +
+ + +
+
+
+ + + Printing a canvas costs 10 paper from + the printer installed in your machine. + + +
+
+
+
+ ); +};